Understanding the render method

Started by PRW56, June 19, 2013, 15:59:03

Previous topic - Next topic

PRW56

I wanted to understand the draw method here (from the example code for the space invaders game in lwjgl), from what I understand, since the mode GL_MODELVIEW was used a stack of matricies of a minimum size of 32 is made, then glPushMatrix makes a new spot on this list, which the methods then modify by drawing the appropriate sprite image in a rectangular area, then the glPopMatrix method is called, and the matrix that was being modified is pushed back in the list, so that if a draw method is called somewhere else it will not modify the one just drawn. The way I see it a matrix (in this sense) is referring to the pixel data that will be drawn to the screen. Can someone pls correct me and/ or fill in the gaps in my knowledge? ty for any and all help

public void draw(int x, int y) {
		// store the current model matrix
		glPushMatrix();

		// bind to the appropriate texture for this sprite
		texture.bind();

		// translate to the right location and prepare to draw
		glTranslatef(x, y, 0);

		// draw a quad textured to match the sprite
		glBegin(GL_QUADS);
		{
			glTexCoord2f(0, 0);
			glVertex2f(0, 0);

			glTexCoord2f(0, texture.getHeight());
			glVertex2f(0, height);

			glTexCoord2f(texture.getWidth(), texture.getHeight());
			glVertex2f(width, height);

			glTexCoord2f(texture.getWidth(), 0);
			glVertex2f(width, 0);
		}
		glEnd();

		// restore the model view matrix to prevent contamination
		glPopMatrix();
	}

Cornix

The modelview matrix is used within the vertex shader. When you use the begin-block and send a vertex to the graphics card (example: "glVertex2f(0, 0);") the shader will do a matrix multiplication with the modelview matrix to move the vertex to another position.
If you call glTranslate(x, y, 0); then the current modelview matrix will be modified in a way, that every vertex passed to the vertex-shader will be "moved" on the screen according to x and y.


The push- and popMatrix methods are only neccessary because of the call to glTranslate.
The actual rendering code is within the begin-block.
glBegin(GL_QUADS);
		{
			glTexCoord2f(0, 0);
			glVertex2f(0, 0);

			glTexCoord2f(0, texture.getHeight());
			glVertex2f(0, height);

			glTexCoord2f(texture.getWidth(), texture.getHeight());
			glVertex2f(width, height);

			glTexCoord2f(texture.getWidth(), 0);
			glVertex2f(width, 0);
		}
		glEnd();

Just this would draw a rectangular image in one of the corners of the screen.

But you want the image to be drawn at the given (x,y)-Point.

You have 2 solutions to do so:
1). Change the vertex coordinates in the begin-block, it would look like this:
glBegin(GL_QUADS);
		{
			glTexCoord2f(0, 0);
			glVertex2f(x, y);

			glTexCoord2f(0, texture.getHeight());
			glVertex2f(x, y + height);

			glTexCoord2f(texture.getWidth(), texture.getHeight());
			glVertex2f(x + width, y + height);

			glTexCoord2f(texture.getWidth(), 0);
			glVertex2f(x + width, y);
		}
		glEnd();


2). Use glTranslate to move everything you draw by a fixed distance. (this solution is applied in your example code)

The push and the pop are not needed for this example if it is the only image that is being drawn.
But if you want to draw multiple images in the same frame you have to "save" the previous modelview matrix by using pushMatrix. Then you call glTranslate to manipulate the copy of the modelview matrix which you saved with push. Then you render your image. Then you call popMatrix to discard the copy and return to the previously pushed matrix.


If you go with the first way you dont need the push, translate and pop. But the second solution is cleaner and more easy to read.