简体   繁体   中英

Need help updating GLSL 120 gl_ModelViewProjectionMatrix code to GLSL 330, uniformMatrix isn't updating in shader

I have been running through tutorials and trying to figure out OpenGL 3.3 and GLSL 3.3. I managed to get the program working with a moving camera by following an old tutorial that used GLSL 1.2. My vertex shader is:

uniform float xpos;
uniform float ypos;

in vec3 position;

void main() {
    gl_Position = gl_ModelViewProjectionMatrix * (vec4(position,1.0) + vec4(
        xpos, ypos, 0.0, 0.0
    ));
}

My code has a main loop that takes the user input and changes a matrix in my camera class. The matrix is then uploaded to the shader using the line glLoadMatrixd(camera_matrix). This code works perfectly, and displays my objects and lets me move my camera around them.

However I'm trying to update my code to GLSL 3.3, but can't figure out how to. I know gl_ModelViewProjectionMatrix is depreciated and is the main problem I'm having in updating. My new shader is:

#version 330
uniform float xpos;
uniform float ypos;
uniform mat4 u_ModelViewProjectionMatrix;

in vec3 position;

void main() {
    gl_Position = u_ModelViewProjectionMatrix * (vec4(position,1.0) + vec4(
        xpos, ypos, 0.0, 0.0
    ));
}

And my code that I'm using has:

MatrixLocation = glGetUniformLocation(shaderProgram, 'u_ModelViewProjectionMatrix');

added in right under my xpos and ypos get Uniform Location calls. and:

glUniformMatrix4fv(MatrixLocation, 1, GL_FALSE, camera_matrix)

in the same spot my glLoadMatrixd(camera_matrix) call is.

To my understanding before I was using glLoadMatrixd to load my camera matrix to current matrix, and gl_ModelViewProjectionMatrix was loading that matrix into my shader. So I replaced glLoadMatrix with a call to set the uniform variable u_ModelViewProjectionMatrix with my camera matrix. Then I used that uniform value in my shader.

However where the program worked with the 1.2 shader, when made into a 3.3 shader the program stops rendering my objects with no errors thrown up. It's just the blank background without showing my vertexes. When printing my camera_matrix it shows that it is updating the same way with each version so it must be an error converting camera matrix into the shader. Does anyone know what I'm doing wrong?

Edit: When opening my window I run:

glViewport(0, 0, width, height)
glClear(GL_COLOR_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/height, .1, 1000.)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

then I run my code that sets up the window, creates the shader, creates the object vao/vertex buffers, and the main loop. My loop checks for input, updates my camera class's camera matrix, and then renders with glUseProgram(shaderProgram) / update uniforms / glVindVertexArray(obj.vao) / glDrawArrays.

You have two issues currently.

  1. camera_matrix is your ModelView matrix but you are trying to use it as Projection * ModelView

  2. camera_matrix is an array of 16 GLdouble variables (as evidenced by using glLoadMatrixd (...) originally).

    • glUniformMatrix4fv (...) expects an array of 16 GLfloat variables.

To fix issue #1 , you need to either concatenate this matrix with your projection matrix ( gluPerspective(60.0, float(width)/height, .1, 1000.) ) or pass two matrix uniforms - one for your ModelView matrix and another for your Projection matrix. The latter is the more sensible approach.

To fix issue #2 , convert from double-precision to single-precision before sending your matrix to GLSL. Do not even bother trying to pass GLSL a double-precision 4x4 matrix ( dmat4 ), it is not worth the trouble even when it is actually supported (GL 4.0+ or through the GL_ARB_gpu_shader_fp64 extension).

My problem originated from I was trying to update my shaders while still using depreciated matrix stack. My order in updating my program to the newer versions was off.

What I did was drop the matrixload/ matrixmode functions, I got rid of the camera matrix, and got rid of gluPerspective.

I bound 3 new matrices to my program with:

modelLoc = glGetUniformLocation(shader, 'model');
viewLoc = glGetUniformLocation(shader, 'view');
projLoc = glGetUniformLocation(shader, 'proj');

Then I made a new class to handle matrices and made 3 fresh identity matrices and updated them into my shader:

model = Matrix();
view = Matrix();
proj = Matrix();

glUniformMatrix4fv(viewLoc, 1, GL_FALSE, view.toArray())
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, model.toArray())
glUniformMatrix4fv(projLoc, 1, GL_FALSE, proj.toArray())

I got the shader working with all identity matrices. Then I wrote custom functions on my matrix to make translations/etc and edited the matrices to play around with them to see what worked:

view.traslate(x,y,z)
proj.perspectiveProjection(fovRadians, aspectRatio, nearClip, farClip)

I'm still playing around with my camera trying to understand the conversion from world units to screen units to make better functions such as look at, rotate around, etc. I "reinvented the wheel" a bit to understand exactly what was going on behind the sceens, but I feel like I have a grasp on it now. Thanks everyone for the help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM