raylib: [rlgl] rlPushMatrix() is incorrect

Look at this line here:

https://github.com/raysan5/raylib/blob/master/src/rlgl.c#L413

glPushMatrix() is supposed to push on a new matrix onto the stack, with cloning the previous one. Though rlPushMatrix(), it’s also loading the identity matrix (because of a call to rlLoadIdentity()). This is incorrect if you want to emulate the original OpenGL fixed function API.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 23 (23 by maintainers)

Most upvoted comments

here some comments to have some sort of work-log about the differences between raylibs handling of the matrix-stack and the opengl way:

I’ve analysed gl-gears how opengl handles the things and the structure is:

OpenGL (matrix-stack means a datastructure which combines elements of the stack!)
   Gears:
      glMatrixMode(PROJECTION)   mode=1
         glLoadIdentity
         glFrustum
      glMatrixMode(MODELVIEW)    mode=0
         glLoadIdentity
         glTranslate

      draw-loop:
         glPushMatrix
            glRotate
            glPushMatrix
               glTranslate
               glCallList(gear) (glVertex3f)
            glPopMatrix
            ----
            glPushMatrix
               glTranslate
               glCallList(gear)
            glPopMatrix
         glPopMatrix
   Implementation Details:
      - there are three matrix stacks, one for each mode (projection, modelview and texture)
      - glLoadIdentity loads the identity matrix to the matrix stack pointer with the index of the current matrix_mode
      - glPushMatrix goes on the stack one index higher and copies the old index matrix to the new one!
      - glPopMatrix simply goes one index lower
      - glRotate creates rotation matrix and mulleft to the top matrix stack element
      - glFrustum creates matrix and mulleft to the top matrix stack element
      - glBegin does a multiplication of the current element of MODELVIEW-stack and PROJECTION-stack to transform all vertices between begin and end

Raylib in contrast has this structure in the examples:

Raylib (Matrix-Stack means more like a software-stack datastructure to remember old values, but not to combine elements on the stack and has only one stack for everything)
   Example:
      initGraphicDevice - sets ortographic projection to matrix stack
      BeginDrawing - (depends on beeing in MODELVIEW-Mode) rlLoadIdentity, downscaleview-matrix
         Begin3DMode(camera) - PushMatrix, set Projection and Modelview based on camera
            glvertex3f....
         End3dMode - pop Projection matrix, set modelview to identity
      EndDrawing

Biggest drawback with current implementation in raylib: opengl and raylib both uses a matrix-stack, but they’re completely different in it’s behaviour. will continue to investigate about good solutions to this.

You’re going to be confusing a lot of people though. Is there a document somewhere that outlines what the differences are between rlgl and the old OpenGL 1.1 API?

I’ve looked at the code and found the following: with the current implementation (with setting the matrix to identity) you do (for example) in DrawCube a rlTranslatef which leads from your logic to an absolute position for the cube (because first the matrix is set to identity by the pushmatrix).

you’re using the matrix-stack like a normal stack of integers, just to safe the old value and be able to use a new one, but the matrix-stack was not meant to be used like that, is was meant to be used in an object-hierachy (think about a human 3d object consisting of a body, arms and legs). with that hierachy you can modify the matrix of the base object (the body for the human object) and by using the stack the arms and legs are automatically positioned correctly if the matrix-stack is used for drawing them (because the transformation of the body is automatically also used for the other objects).

Here is a really good explanation of the concept: https://www.processing.org/tutorials/transform2d/

My advice would be to remove the position argument for the cube and instead let the user first define the wanted transformation by placing it on top of the matrix stack and then only draw the cube (with the current implementation it’s not possible for the user to let the cube rotate locally because the push-matrix clears the transform-matrix and for a rotating cube you would need a rotate AFTER the pushmatrix.). So remove the rlPushMatrix from the DrawCube (and other primitives) and remove also the translate and let the user set the matrix for the object to be drawn. Then you have a proper implementation for your primitives with respect for object-/world- and camera-space.

EDIT: I could make a pull-request with my proposal if that would help you…