LWJGL problem making MVP and passing to shader

Hey guys,

I’m trying to move my c++ game over to java. I’m having a problem with the model view projection matrix I’m passing to my vertex shader. It just doesn’t want to work in java.

Every game loop, I compute the Matrix4f MVP matrix then pass it to my drawable objects. My objects take care of passing it to their shader and drawing themselves. When I don’t use the MVP, things are visible but only from that default view, when I do use MVP, it just all goes to the background color and nothing is visible. Either I’m not computing the MVP correctly or something weird is happening between the main game loop and the shader.

In my project positive Z is the up direction. I want to use the players xyz to recalculate the camera position and have the camera follow the character around the world like an RPG or FPS.

Sorry for the huge wall of text, but I don’t know where the problem is, so I don’t know what I should or shouldn’t include.
I’d be happy to email you the code ( it’s only two classes right now ) if you think you can better find the problem that way.

Here is the code in c++ that definitely works:

            float CAMERA_DISTANCE_BEHIND = 8.0f;
	float facing = player->getFacing();
	facing = (float) (((int) (facing + 180)) % 360);

	float eyeX = player->getCharacterX()+ CAMERA_DISTANCE_BEHIND * cos(facing * PI / 180.0);
	float eyeY = player->getCharacterY()+ CAMERA_DISTANCE_BEHIND * sin(facing * PI / 180.0);
			
	glm::mat4 Projection = glm::perspective(45.0f, (float) 640 / 480, 0.1f,	100.0f);

	float aX = player->getCharacterX();
	float aY = player->getCharacterY();
	float aZ = player->getCharacterZ();

	glm::mat4 View = glm::lookAt(
			glm::vec3(eyeX, eyeY, player->getCharacterZ() + 4.0), // Camera is at (4,3,3), in World Space
			glm::vec3(aX, aY, aZ),
			glm::vec3(0, 0, player->getCharacterZ() + 20.0) 
					);
	
	glm::mat4 Model = glm::mat4(1.0f); 
	glm::mat4 MVP = Projection * View * Model; 

            player->setMVP(MVP);

// inside the player class

glUseProgram( programID ); 

GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint rgbID = glGetUniformLocation(programID, "RGB");
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);	
glUniform4f(rgbID, (GLfloat)red,(GLfloat)red,(GLfloat)0.5f,(GLfloat)1.0f );	
		
glBindVertexArray(VAO);		
glDrawElements( GL_TRIANGLES,sizeof(vertexData), GL_UNSIGNED_INT, NULL );

glBindVertexArray(0);
glUseProgram( NULL );

// shader used for player

const GLchar* playerShaderVertex[] =
		{
"#version 130 \n  
in vec3 position; \n                                
uniform mat4 MVP;                                  
void main()                                       
{                                                  
	vec4 v = vec4( position , 1 );                 
	gl_Position = MVP * v;                         
}" };

Here is the java code that doesn’t work:

private void gameloop() {
	glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
	while (!glfwWindowShouldClose(window)) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glfwPollEvents();

		//... grab and handle input

		MVP=MVP.zero();

                    // code I got from a helpful guy at the lwjgl site
		float CAMERA_DISTANCE_BEHIND = 8.0f;
		float HEIGHT_ABOVE_PLAYER = 4.0f;
		float facingInRad = (float) Math.toRadians(t.getFacing());
		float angle = (float) Math.atan(HEIGHT_ABOVE_PLAYER / CAMERA_DISTANCE_BEHIND);
		MVP.perspective((float) Math.toRadians(45), 640.0f / 480.0f, 0.01f, 100.0f)
				.translate(0, 0, -CAMERA_DISTANCE_BEHIND) 
				.rotateX(angle - (float) Math.PI * 0.5f) 
				.rotateZ(facingInRad) 
				.translate((float) -t.getX(), (float) -t.getY(), (float) -t.getZ()); 
		
		player.setMVP(MVP);
		player2.setMVP(MVP); // this guy doesn't move, but I need him there to see if my person is actually moving around in the world
		
		player.draw();
		player2.draw();
		
		glfwSwapBuffers(window); 
	}
}

public class player { // I took out a lot of code that set the xyz and make the vertex arrays. I know there’s nothing wrong there.
private int programId;
private int vertexShaderId;
private int fragmentShaderId;
private int vboId;
private int vaoId;

private int glMVPUniformLocation;
private int glRGBUniformLocation;
FloatBuffer fb = BufferUtils.createFloatBuffer(16);

private Matrix4f MVP;

private float red = 0.0f;
private float green = 0.9f;
private float blue = 0.9f;
private float alpha = 0.0f;

public player() {		
	try {
		try {
			programId = glCreateProgram();
			glUseProgram(programId);
			glMVPUniformLocation = glGetUniformLocation(programId, "MVP");
			glRGBUniformLocation = glGetUniformLocation(programId, "RGB");
			glUseProgram(0);

		} catch (Exception e) {
			System.out.println("exception caught:" + e.getMessage() + " " + e.getStackTrace());
		}

		if (programId == 0) {
			throw new Exception("Could not create Shader");
		}

		
		glCreateVertexShader("#version 330\nuniform mat4 MVP; in vec3 position; void main() { gl_Position =MVP* vec4(position, 1.0); }");				
		glCreateFragmentShader("#version 330\nuniform vec3 RGB; out vec4 fragColor;  void main() { fragColor = vec4(RGB,0.5); }");
		
		glLink();

	} catch (Exception e) {
		System.out.println("exception caught in init " + e.getMessage() + " " + e.getStackTrace());
	}
}

public void draw() {
	bindVertexData();
	glUseProgram(programId);

	glUniformMatrix4fv(glMVPUniformLocation, false, MVP.get(fb));	
	glUniform3f(glRGBUniformLocation, red, green, blue);

	glBindVertexArray(vaoId);
	glEnableVertexAttribArray(0);
	glDrawArrays(GL_TRIANGLES, 0, 3);
	glDisableVertexAttribArray(0);
	glBindVertexArray(0);

	glUseProgram(0);
}

public void glCreateFragmentShader(String shaderCode) throws Exception {
	fragmentShaderId = glCreateThisShader(shaderCode, GL_FRAGMENT_SHADER);
}

protected int glCreateThisShader(String shaderCode, int shaderType) throws Exception {
	int shaderId = glCreateShader(shaderType);
	if (shaderId == 0) {
		throw new Exception("Error creating shader. Code: " + shaderId);
	}
	glShaderSource(shaderId, shaderCode);
	glCompileShader(shaderId);
	if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
		throw new Exception("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
	}
	glAttachShader(programId, shaderId);
	return shaderId;
}

public void glCreateVertexShader(String shaderCode) throws Exception {
	vertexShaderId = glCreateThisShader(shaderCode, GL_VERTEX_SHADER);
}

public void glLink() throws Exception {
	glLinkProgram(programId);
	if (glGetProgrami(programId, GL_LINK_STATUS) == 0) {
		throw new Exception("Error linking Shader code: " + glGetProgramInfoLog(programId, 1024));
	}
	glValidateProgram(programId);
	if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
		System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024));
	}
}
public void setMVP(Matrix4f mvp) {
	MVP = mvp;
}

}

Hmm… that yellow text didn’t turn out the way I planned.

You should be able edit the post by clicking modify on the top right of the posts frame :wink:

Thanks man.

You don’t want to have a zero matrix to start with. Replace MVP.zero() with MVP.identity().

Thanks, I did the zero because the MVP values kept growing and growing with each iteration of the loop. I still can’t see the triangles though.

The next obvious issue is that you are querying the uniform locations before you even have a linked program:


            programId = glCreateProgram();
            glUseProgram(programId);
            glMVPUniformLocation = glGetUniformLocation(programId, "MVP");
            glRGBUniformLocation = glGetUniformLocation(programId, "RGB");

… Yep, I feel stupid now. That helped. Now, instead of a red screen, I see my triangles and can move one around like when I don’t use MVP in the shader. But the camera doesn’t follow the main one. It’s just that default overhead view.

With a little bit of poking around, IT WORKS!!!
I’ve been beating my head against that all summer.
Whew!

Thanks Kai.