Confused about OpenGL 3.0+ shaders

Started by
6 comments, last by Sponji 10 years, 7 months ago

Hi all,

I recently discovered that the latest OpenGL standards have deprecated glTranslatef and a bunch of other immediate-mode functions.

My graphics hardware is not great (it doesn't support VAOs, for instance) but I feel I should learn the correct way of doing things.

I read these tutorials: http://www.swiftless.com/opengltuts/opengl4tuts.html and the ones at opengl-tutorial.net.

I tried to implement shaders into my code, but I just see some yellow lines...

Here's what I'm doing: (my shader loading function is from here):

In the initiation procedure:


      glViewport(0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y);
      projectionMatrix = glm::perspective( 75.0f, screenSize.x / screenSize.y, clip_near, clip_far);

      int programShaderID = loadShaders("vertexShader.txt","fragmentShader.txt");
      glBindAttribLocation(programShaderID, 0, "in_Position"); // Bind a constant attribute location for positions of vertices
      glUseProgram(programShaderID);

Drawing is done by VBOs only (my hardware doesn't support VAOs AFAIK), in the usual way as far as I can see.

Every frame, after drawing:


        int projectionMatrixLocation = glGetUniformLocation(programShaderID, "projectionMatrix"); // Get the location of our projection matrix in the shader  
        int viewMatrixLocation = glGetUniformLocation(programShaderID, "viewMatrix"); // Get the location of our view matrix in the shader  
        int modelMatrixLocation = glGetUniformLocation(programShaderID, "modelMatrix"); // Get the location of our model matrix in the shader

        glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]); // Send our projection matrix to the shader  
        glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]); // Send our view matrix to the shader  
        glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]); // Send our model matrix to the shader  

Shaders:

vertex:


#version 330 core
in vec3 in_Position;

void main(){

    uniform mat4 projectionMatrix;  
    uniform mat4 viewMatrix;  
    uniform mat4 modelMatrix;  

	gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(vertexPosition_modelspace, 1.0);
 }

fragment:


#version 330 core
out vec3 color;
 
void main(){
    color = vec3(1,0,0);
}

I can see something, but my glm::matrices are not seeming to work (i.e. the translation is NOT happening).

I'm so confused, and most of the tutorials seem to use VAOs which I can't do.

Am I doing this right?

Can I use shaders without VAOs?

Am I supposed to pass vertex to a shader, like I did with the matrices?

EDIT:

I checked, and it is only the translation which is not happening as far as I can see. Why is this?

Thanks very much in advance

mikey

Advertisement

 #version 330 core
in vec3 in_Position;

void main(){

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(vertexPosition_modelspace, 1.0);
}

Should be
#version 330 core
in vec3 in_Position;
 
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

void main(){


    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(vertexPosition_modelspace, 1.0);
}

Still, if your hardware doesn't supports VAO (exactly, what GPU do you have?) I don't think you can use GLSL 3.30 either.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

Thanks for the reply, TheChubu.

I did what you said- but nothing happened. The entire scene is rendered however no translation is being done.

I'm not sure if it makes a difference, but I noticed that you wrote:


vertexPosition_modelspace

instead of


in_Position

But whatever I change that variable to- nothing happens.

Are you sure I don't have to somehow feed each variable through the shader? Or is that automatic?

My graphics card is an "ATI Mobility Radeon HD 2400 XT". My machine is a 2011 iMac but running Boot Camped WinXP.

From the looks of it, TheChubu based his answer off your sample code where you used vertexPosition_modelspace.

Try using in_Position instead because that is the correct name of the uniform.

http://tinyurl.com/shewonyay - Thanks so much for those who voted on my GF's Competition Cosplay Entry for Cosplayzine. She won! I owe you all beers :)

Mutiny - Open-source C++ Unity re-implementation.
Defile of Eden 2 - FreeBSD and OpenBSD binaries of our latest game.

Yes that was probably my fault- but like I said- whatever I put there doesn't make a difference, no translations are being done. Plus- no linker errors from the shader loader are generated?

Drawing is done by VBOs only (my hardware doesn't support VAOs AFAIK), in the usual way as far as I can see.

Every frame, after drawing:


        int projectionMatrixLocation = glGetUniformLocation(programShaderID, "projectionMatrix"); // Get the location of our projection matrix in the shader  
        int viewMatrixLocation = glGetUniformLocation(programShaderID, "viewMatrix"); // Get the location of our view matrix in the shader  
        int modelMatrixLocation = glGetUniformLocation(programShaderID, "modelMatrix"); // Get the location of our model matrix in the shader

        glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]); // Send our projection matrix to the shader  
        glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]); // Send our view matrix to the shader  
        glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]); // Send our model matrix to the shader  

Here is one problem,

I guess you first do something like "glUseProgram(programShaderId)", and at the end of your drawing "glUseProgram(0)"? Or do you just use one shader? Then setting it once in the initialisation is ok.
When you set the uniforms after drawing, the shaders dont have the matrices when they draw/process everything.or if the shader is active all the time then you draw everything with the matrices from the last draw step.
And you dont need to use "glGetUniformLocation()" every frame because the locations are constant for one shader, just get the locations once after "loadShaders ("vertexShader.txt","fragmentShader.txt"); "
The right sequence would be:

Initialisation:

  1. Load shaders
  2. glGetUniformLocation

Each frame:

  1. set uniforms
  2. draw your vbo

The other stuff you are doing should be right, so this sequence only considers the uniform stuff.

A good resource for me is http://www.opengl-tutorial.org/
Feel free to ask if it is still not working or when there are other questions

Best regards
Marc

Hi Marc,

Thanks so much for your reply, it was very informative. I did what you said but it still isn't working, however I found out that my glGetUniformLocation calls are returning -1.

Why could this be?

Here's what I'm now doing:

(at startup)


loadShaders(...);
glUseProgram(programShaderID);
glBindAttribLocation(...);

int projectionMatrixLocation = glGetUniformLocation(programShaderID, "projectionMatrix");
int viewMatrixLocation = glGetUniformLocation(programShaderID, "viewMatrix");
int modelMatrixLocation = glGetUniformLocation(programShaderID, "modelMatrix");

// THESE ^^ RETURN NEGATIVE ONE!

projectionMatrix = getProjectionMatrix();

(each frame)


viewMatrix = glm::...
modelmatrix = glm::...

glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]);
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]);
	
drawModels();

Thanks :)

Usually -1 means that you don't use them in the shader and the compiler likes to optimize them out, but that isn't probably your situation. Are you sure that the shaders compile and link nicely? Use glGetProgramInfoLog to make sure about that.

Also noticed that you're calling glBindAttribLocation after loading shaders, you should bind the attributes before linking the program.

Derp

This topic is closed to new replies.

Advertisement