【问题标题】:How to use GLKMatrixStack in Objective-C? (GLKit)如何在 Objective-C 中使用 GLKMatrixStack? (GLKit)
【发布时间】:2013-12-02 08:39:48
【问题描述】:

我正在尝试将一些 OpenGL 代码从 Android 项目移植到 iOS。我之前做过一点 iOS 编程,所以我熟悉 Objective-C 的语法,但我似乎无法弄清楚这些 GLKMatrixStacks 是如何工作的。下面是我尝试移植的一些 Java 代码,其中包含我需要如何使用堆栈的示例。

public void drawLeftHip()
{
    float[] temp = new float[16];
    System.arraycopy(mModelMatrix, 0, temp, 0, mModelMatrix.length);
    stack.push(temp);

    //Global transformations here
    Matrix.translateM(mModelMatrix, 0, -1.0f, -.75f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, lThighAngle, 1.0f, 0.0f, 0.0f);  

    //draw children
    drawLeftThigh();

    //left hip
    Matrix.scaleM(mModelMatrix, 0, .25f, .25f, .25f);
    drawPackedTriangleBuffer(mSphereData, mSphereVertexCount, mModelMatrix, mColorBlack); //draw the triangle with the given model matrix

    mModelMatrix = stack.pop();
}

我基本上是复制 mModelMatrix(一个 4x4 矩阵)并将其压入堆栈,进行全局转换,绘制子项,进行局部转换,最后弹出堆栈。

我已经尝试将 NSMutableArray 用于堆栈,但我不能使用它,因为我需要使用不是 if 类型 (id) 的 GLKMatrix4。

【问题讨论】:

    标签: objective-c opengl-es stack glkit


    【解决方案1】:

    GLKMatrix4 表示一个 4x4 矩阵。它只是一个封装 16 元素 float 数组的联合,因此它类似于您示例中的 float[16] 数组。如果您使用GLKBaseEffect,您已经将它们用于您的 ModelView 和 Projection 矩阵。 (如果您正在滚动自己的着色器,无论如何使用GLKit matrix/vector types and corresponding math utilities 是个好主意,因为它们经过优化可以在 iOS 设备上提供良好的性能。)

    按照你的例子的模式:

    1. 使用GLKMatrixStackCreate 创建一个堆栈,然后使用GLKMatrixStackLoad 将您当前的ModelView 矩阵复制到堆栈上。此函数会自动复制矩阵,因此您无需像示例中那样自己创建副本。

    2. 使用GLKMatrix4TranslateGLKMatrix4Rotate 等在使用模型视图矩阵进行绘图之前对其进行转换。 (不要忘记将更改后的矩阵上传到着色器的统一变量中,或者如果使用GLKBaseEffect,则在绘制之前更新其transform 属性并将其告知prepareToDraw。)

    3. 最后,使用GLKMatrixStackGet 函数之一从堆栈中检索保存的矩阵。

    不过,这种模式实际上并没有使用堆栈——它只是保存和加载单个矩阵。您可以使用GLMatrixStackPush 来扩展模式以保存额外的矩阵,并使用GLKMatrixStackPop 来恢复到先前的状态。 (pop 函数在处理它之前不会返回顶部矩阵,因此如果您想先检索它,请使用 GLKMatrixStackGet 函数。)尽管如此,这种模式仍然没有充分利用堆栈——更好方法是将所有矩阵运算保留在堆栈中。这是一个快速(未经测试)的示例:

    // subclass of GLKViewController as in the "OpenGL Game" Xcode template
    @implementation MyViewController
    {
        GLKMatrixStack mvStack;
    }
    
    - (void)setupGL
    {
        // ... other setup code ...
    
        // set up base transform
        mvStack = GLKMatrixStackCreate(NULL);
        GLKMatrixStackTranslate(mvStack, /* ... coords ... */);
        GLKMatrixStackScale(mvStack, /* ... coords ... */);
        GLKMatrixStackRotate(mvStack, /* ... coords ... */);
    }
    
    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
    {
        // save the base transform
        GLKMatrixStackPush(mvStack);
    
        // additional transforms for figure
        GLKMatrixStackTranslate(mvStack, /* ... coords ... */);
        GLKMatrixStackScale(mvStack, /* ... coords ... */);
        GLKMatrixStackRotate(mvStack, /* ... coords ... */);
    
        [self drawBody];
    
        // restore the base transform
        GLKMatrixStackPop(mvStack);
    }
    
    - (void)drawBody
    {
        self.effect.transform.modelviewMatrix = GLKMatrixStackGetMatrix4(mvStack);
        // ... draw body ...
    
        // save body transform 
        GLKMatrixStackPush(mvStack);
    
        // transform to left leg coordinate space
        GLKMatrixStackTranslate(mvStack, /* ... coords ... */);
        GLKMatrixStackScale(mvStack, /* ... coords ... */);
        GLKMatrixStackRotate(mvStack, /* ... coords ... */);
    
        [self drawLeg];
    
        // restore to body coordinates
        GLKMatrixStackPop(mvStack);
    
        // transform to right leg coordinate space
        GLKMatrixStackTranslate(mvStack, /* ... coords ... */);
        GLKMatrixStackScale(mvStack, /* ... coords ... */);
        GLKMatrixStackRotate(mvStack, /* ... coords ... */);
    
        [self drawLeg];
    
        // restore to body coordinates
        GLKMatrixStackPop(mvStack);
    }
    
    - (void)drawLeg
    {
        self.effect.transform.modelviewMatrix = GLKMatrixStackGetMatrix4(mvStack);
        // ... draw upper leg ...
    
        // save upper leg transform 
        GLKMatrixStackPush(mvStack);
    
        // transform to lower leg coordinate space
        GLKMatrixStackTranslate(mvStack, /* ... coords ... */);
        GLKMatrixStackScale(mvStack, /* ... coords ... */);
        GLKMatrixStackRotate(mvStack, /* ... coords ... */);
    
        self.effect.transform.modelviewMatrix = GLKMatrixStackGetMatrix4(mvStack);
        // ... draw lower leg ...
    
        // restore to upper leg coordinates
        GLKMatrixStackPop(mvStack);
    }
    

    阅读GLKMatrixStack 上的文档了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      相关资源
      最近更新 更多