Jonathan
Jonathan

Reputation: 1100

How can I use transform matrices without using shaders with the OpenGL SuperBible in C++?

I am well versed in C++, but fairly new to openGL and the OpenGL SuperBible. I would like to take a projection matrix that the prior developer used in a shader and apply the matrix without a shader. For example, I would like to take the following (only the relevant code is posted):

GLShaderManager shaderManager;
// Zoom and shade
shaderManager.UseStockShader(GLT_SHADER_FLAT, viewFrustum.GetProjectionMatrix(), vGreen);

and use it to adjust the zoom without applying the shader (where ???? is the function I am looking for):

// Adjust the zoom without applying a shader
????(viewFrustum.GetProjectionMatrix());

My question is, what function(s) could I use to do this? Note that the matrix in viewFrustum.GetProjectionMatrix() is already set up, and I am trying to avoid having to recode this whole functionality. I am looking for a function that will just apply the matrix and not interfere with color.

Clarification: The object I am drawing can have over 1 million polygons, and changes color. I am simply looking for a function that goes in place of ????.

Upvotes: 2

Views: 733

Answers (4)

Jonathan
Jonathan

Reputation: 1100

While not quite what I was looking for, I did finally come across a solution that works with my code. I was able to play around with the factors that were used to set up the projection matrix, and then do the following:

glPushMatrix(); //Save the current matrix state

// ... Do calculations to convert from orthographic to scaling factors (basically 1/x)

glScaled(x,y,1.0); // Scale, increasing by a factor of x and y

// ... Do my drawing

glPopMatrix(); // Revert to the previous matrix state (before zooming)

If someone can still find a function to take the place of ???? in my original question, I will probably come back and accept it. Thank you all for your help, and assistance in finding good opengl resources.

Upvotes: 0

Amadeus
Amadeus

Reputation: 10685

Let me try.

Supposition:

  • Your frustum is simmetrical, i.e., top = -botton and left = -right (those are the values you have used to specify the frustrum matrix)

To achieve zoom effects, let's say, by factor f, just multiply the diagonal matrix by this factor (only for the two first row), i.e.

  m = viewFrustum.GetProjectionMatrix();
  m[0][0] = m[0][0] * f;
  m[1][1] = m[0][0] * f;

  shaderManager.UseStockShader(GLT_SHADER_FLAT, m, vGreen);

which, essentially is apply a scale matrix to it.

But, I believe is easier to change viewFrustum via is function parameter, or better yet, by using perspective matrix.

And yes, you have to pass this matrix to the shaders, there no way to change it only in CPU

Another solution:

Modify your vertex shader, by creating a new uniform variable, let's say: scale

In gl_position attribution, change it to be something like this:

gl_Position = scale * YOUR_MATRIX * points;

Now, in CPU, attribute your scale matrix to this uniform, using something like this:

m = scale(f, f, 1);
`pass m to vertex uniform shader`

Upvotes: 1

wdavilaneto
wdavilaneto

Reputation: 816

You need No shader for that. As Stated on OpenGl Documentation (http://www.opengl.org/wiki/Viewing_and_Transformations)

"A simple method for zooming is to use a uniform scale on the ModelView matrix. However, this often results in clipping by the zNear and zFar clipping planes if the model is scaled too large.

A better method is to restrict the width and height of the view volume in the Projection matrix."

static float zoomFactor; /* Global, if you want. Modified by user input..*/
/* A routine for setting the projection matrix. May be called from a resize
  event handler in a typical application. Takes integer width and height 
  dimensions of the drawing area. Creates a projection matrix with correct
  aspect ratio and zoom factor. */
void setProjectionMatrix (int width, int height)
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective (50.0*zoomFactor, (float)width/(float)height, zNear, zFar);
  /* ...Where 'zNear' and 'zFar' are up to you to fill in. */
}

Edited:

There is no need for an extra "apply matrix function".

"gluPerspective specifies a viewing frustum into the world coordinate system... The matrix generated by gluPerspective() is multipled by the current matrix, just as if glMultMatrix() were called with the generated matrix. To load the perspective matrix onto the current matrix stack instead, precede the call to gluPerspective() with a call to glLoadIdentity()

From: http://code.nabla.net/doc/OpenGL/api/OpenGL/man/gluPerspective.html

Upvotes: 1

Mr. Developerdude
Mr. Developerdude

Reputation: 9688

You need to know the configuration of the matrices in OpenGL, such as how many rows and columns they have and whether they are row or column major. This can be gleaned from many places, including:

  1. The official OpenGL specs.
  2. Some tutorial on the subject
  3. From the sources of some of the many OpenGL compatible matrix math libraries out there.

In fact most 3D engines based on OpenGL will have some rudimentary form of matrix support that is compatible. It might actually be better to just use one of those libraries.

@genpfault suggested GLM which looks promising.

Upvotes: 1

Related Questions