Iphone OpenGL:编辑 MODELVIEW_MATRIX

发布于 2024-10-13 05:12:46 字数 519 浏览 1 评论 0原文

我正在研究一个旋转的 3D 立方体(glFrustumf 设置),它将当前矩阵乘以前一个矩阵,以便立方体继续旋转。见下文

/* save current rotation state */
GLfloat matrix[16]; 
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);

/* re-center cube, apply new rotation */
glLoadIdentity(); 

glRotatef(self.angle, self.dy,self.dx,0);

glMultMatrixf(matrix);

问题是我需要退出(就好像我有相机一样)。 我尝试编辑矩阵,这种方法有效,但出现了噪音。立方体跳来跳去。

   matrix[14] = -5.0;
   matrix[13] = 0;
   matrix[12] =0; 

有没有办法编辑当前的模型视图矩阵,以便我可以通过将立方体乘以另一个矩阵来设置立方体的位置?

I working on a spinning 3D cube (glFrustumf setup) and it multiplies the current matrix by the previous one so that the cube continues to spin. See below

/* save current rotation state */
GLfloat matrix[16]; 
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);

/* re-center cube, apply new rotation */
glLoadIdentity(); 

glRotatef(self.angle, self.dy,self.dx,0);

glMultMatrixf(matrix);

The problem is I need to step back from this (as if I had a camera).
I tried to edit the matrix and that kind of works but picks up noise. The cube jumps around.

   matrix[14] = -5.0;
   matrix[13] = 0;
   matrix[12] =0; 

Is there a way to edit the current Modelview Matrix so that I can set the position of the cube with multiplying it by another matrix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

童话 2024-10-20 05:12:46

您不应该将 OpenGL 误认为是场景图,也不应该误认为是数学库。这意味着:不要读回矩阵,而是将其任意相乘。相反,每次执行渲染过程时都会重新构建整个矩阵堆栈。我想我应该指出,在 OpenGL-4 中,所有矩阵函数都已被删除。相反,您应该提供矩阵作为制服。

根据@Burf2000的评论进行编辑:
您的典型渲染处理程序将如下所示(伪代码):

draw_object():
    # bind VBO or plain VertexArrays (you might even use immediate mode, but that's deprecated)
    # draw the stuff using glDrawArrays or better yet glDrawElements

render_subobject(object, parent_transform):
    modelview = parent_tranform * object.transform
    if OPENGL3_CORE:
        glUniformMatrix4fv(object.shader.uniform_location[modelview], 1, 0, modelview)
    else:
        glLoadMatrixf(modelview)
    draw_object(object)
    for subobject in object.subobjects:
        render_subobject(subobject, modelview)

render(deltaT, window, scene):
    if use_physics:
        PhysicsSimulateTimeStep(deltaT, scene.objects)
    else:
        for o in scene.objects:
            o.animate(deltaT)

    glClearColor(...)
    glClearDepth(...)
    glViewport(0, 0, window.width, window.height)
    glDisable(GL_SCISSOR_TEST);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)

    # ...

    # now _some_ objects' render pass - others may precede or follow, like for creating reflection cubemaps or water refractions.

    glViewport(0, 0, window.width, window.height)
    glEnable(GL_DEPTH_TEST)
    glDepthMask(1)
    glColorMask(1,1,1,1)

    if not OPENGL3_CORE:
        glMatrixMode(GL_PROJECTION)
        glLoadMatrixf(scene.projection.matrix)

    for object in scene.objects:
        bind_shader(object.shader)
        if OPENGL3_CORE:
            glUniformMatrix4fv(scene.projection_uniform, 1, 0, scene.projection.matrix)

    # other render passes

    glViewport(window.HUD.x, window.HUD.y, window.HUD.width, window.HUD.height)
    glStencil(window.HUD.x, window.HUD.y, window.HUD.width, window.HUD.height)
    glEnable(GL_STENCIL_TEST)
    glDisable(GL_DEPTH_TEST)

    if not OPENGL3_CORE:
        glMatrixMode(GL_PROJECTION)
        glLoadMatrixf(scene.HUD.projection.matrix)
    render_HUD(...)

等等。我希望你能了解总体思路。 OpenGL 既不是场景图,也不是矩阵操作库。

You should not mistreat OpenGL as a scene graph, nor a math library. That means: Don't read back the matrix, and multiply it arbitrarily back. Instead rebuild the whole matrix stack a new every time you do a render pass. I think I should point out, that in OpenGL-4 all the matrix functions have been removed. Instead you're expected to supply the matrices as uniforms.

EDIT due to comment by @Burf2000:
Your typical render handler will look something like this (pseudocode):

draw_object():
    # bind VBO or plain VertexArrays (you might even use immediate mode, but that's deprecated)
    # draw the stuff using glDrawArrays or better yet glDrawElements

render_subobject(object, parent_transform):
    modelview = parent_tranform * object.transform
    if OPENGL3_CORE:
        glUniformMatrix4fv(object.shader.uniform_location[modelview], 1, 0, modelview)
    else:
        glLoadMatrixf(modelview)
    draw_object(object)
    for subobject in object.subobjects:
        render_subobject(subobject, modelview)

render(deltaT, window, scene):
    if use_physics:
        PhysicsSimulateTimeStep(deltaT, scene.objects)
    else:
        for o in scene.objects:
            o.animate(deltaT)

    glClearColor(...)
    glClearDepth(...)
    glViewport(0, 0, window.width, window.height)
    glDisable(GL_SCISSOR_TEST);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)

    # ...

    # now _some_ objects' render pass - others may precede or follow, like for creating reflection cubemaps or water refractions.

    glViewport(0, 0, window.width, window.height)
    glEnable(GL_DEPTH_TEST)
    glDepthMask(1)
    glColorMask(1,1,1,1)

    if not OPENGL3_CORE:
        glMatrixMode(GL_PROJECTION)
        glLoadMatrixf(scene.projection.matrix)

    for object in scene.objects:
        bind_shader(object.shader)
        if OPENGL3_CORE:
            glUniformMatrix4fv(scene.projection_uniform, 1, 0, scene.projection.matrix)

    # other render passes

    glViewport(window.HUD.x, window.HUD.y, window.HUD.width, window.HUD.height)
    glStencil(window.HUD.x, window.HUD.y, window.HUD.width, window.HUD.height)
    glEnable(GL_STENCIL_TEST)
    glDisable(GL_DEPTH_TEST)

    if not OPENGL3_CORE:
        glMatrixMode(GL_PROJECTION)
        glLoadMatrixf(scene.HUD.projection.matrix)
    render_HUD(...)

and so on. I hope you get the general idea. OpenGL is neither a scene graph, nor a matrix manipulation library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文