Jump to content

  • Log In with Google      Sign In   
  • Create Account


Replacing glMultMatrixd with Shaders ...


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 tmason   Members   -  Reputation: 199

Like
0Likes
Like

Posted 05 May 2014 - 04:12 AM

Hello,

First, thanks to everyone for their help with my earlier posts. Much appreciated...

So, my current question has to do with replacing deprecated code.

I currently have a dirty mix of old and new stuff that goes like this:
 

/*

Somewhere in an initialize function

*/

glBindVertexArray(mVBONames[INDEX_VAO]);
// Create VBOs
glGenBuffers(VBO_COUNT - 1, mVBONames);

// Save vertex attributes into GPU
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[VERTEX_VBO]);
glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount * VERTEX_STRIDE * sizeof(float), lVertices, GL_STATIC_DRAW);
delete[] lVertices;

if (mHasNormal)
{
    glBindBuffer(GL_ARRAY_BUFFER, mVBONames[NORMAL_VBO]);
    glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount * NORMAL_STRIDE * sizeof(float), lNormals, GL_STATIC_DRAW);
    delete[] lNormals;
}

if (mHasUV)
{
    glBindBuffer(GL_ARRAY_BUFFER, mVBONames[UV_VBO]);
    glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount * UV_STRIDE * sizeof(float), lUVs, GL_STATIC_DRAW);
    delete[] lUVs;
}

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mVBONames[INDEX_VBO]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, lPolygonCount * TRIANGLE_VERTEX_COUNT * sizeof(unsigned int), lIndices, GL_STATIC_DRAW);

glBindVertexArray(0);
delete[] lIndices;

And when I am about to draw later in code
 


[...]

glPushMatrix();
glMultMatrixd((const double*)pGlobalPosition);

[...]

glGenVertexArrays(1, &mVBONames[INDEX_VAO]);
glBindVertexArray(mVBONames[INDEX_VAO]);

[...]

const GLsizei lElementCount = mSubMeshes[pMaterialIndex]->TriangleCount * 3;
glDrawElements(GL_TRIANGLES, lElementCount, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(lOffset));

[...]

glBindVertexArray(0);

[...]
glPopMatrix();

I really want to move to shaders and thus remove myself completely from the glPush-Pop stuff and the glMultMatrixd stuff but I am not exactly sure at the moment how.

It seems like I would just:
 

  • Create another array buffer
  • send my global position into that array buffer
  • multiply the buffered vertic data with the global position buffer in a shader
  • and then go from there

But is that right?

I didn't see an exact tutorial online or writeup on how to replace the glMultMatrixd functionality in shaders as I searched.

Any help is appreciated.

Thank you for your time.


Edited by tmason, 05 May 2014 - 04:13 AM.


Sponsor:

#2 Aliii   Members   -  Reputation: 1332

Like
1Likes
Like

Posted 05 May 2014 - 05:14 AM

I didn't see an exact tutorial online or writeup on how to replace the glMultMatrixd functionality in shaders as I searched

 

glMultMatrixd is just one of the many deprecated functions. It wouldnt make sense to make tutorials separately for every single one.

On the other hand, there are very good tutorials on shaders. For-dummies and advanced ones.

(+if you switch to shaders you cant replace all the functions one-by-one and still have your stuff rendered properly, if thats what you mean. Also it would help if you would ask more direct questions:))

 

Tutorials:

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/

http://ogldev.atspace.co.uk/

 

You replace glMultMatrix with simple multiplying in the shaders. Like: PVM = P * V * M

(Im guessing "pGlobalPosition" is your camera/view matrix)

 

It seems like I would just:


Create another array buffer
send my global position into that array buffer
multiply the buffered vertic data with the global position buffer in a shader
and then go from there


But is that right?

 

At first:

create one VBO and fill it with some test vertex data. (also use a VAO).

load the shader source code for the vertex and fragment shaders.(dont use matrices at first)

compile the shaders and link the shader-program.

activate the program with glUseProgram, bind the VAO/VBO, draw.

 

If that works, you can start adding the matrices. For data that is small and is expected to change every frame you use "uniforms". You need to create one and load the view matrix(global position?) into it every frame.(for matrices that are used in many shaders - like the view matrix - you could create an uniform buffer, ...but dont do that now.)

...then you can add the projection matrix.

 

If you want to see a really basic example of shaders/VAOs, ...see this example Ive made not so long ago:

http://www.gamedev.net/topic/655851-basic-opengl-sdl-2-app-source/#entry5149208



#3 bioglaze   Members   -  Reputation: 467

Like
1Likes
Like

Posted 05 May 2014 - 07:26 AM

You should have a very well-reasoned use-case to use double data type in matrices, because they are much slower than floats.



#4 haegarr   Crossbones+   -  Reputation: 3723

Like
1Likes
Like

Posted 05 May 2014 - 07:28 AM


… how to replace the glMultMatrixd functionality in shaders ...

Basically you don't do so at all. glMultMatrix, like all the other matrix routines, was used to compute a matrix on the CPU side. The resulting matrix then was sent to the shaders. To mimic this, you need to use a matrix library like e.g. glm and send the result as an uniform to the shader.

 

Of course, you can do the multiply inside the shader (as Aliii has shown above), and for some use cases this would be the way to go. But the vertex shader will do the product one time for every vertex it is processing, while (as long as matrices on the old matrix stack are concerned) they need to be computed at most once per model.

 

Hence the usual way is to use a matrix library, compute matrices on the CPU side, send it as uniform (stand alone or in a UBO) to the shader, and use it in the shader as is. As said, special use cases will need another way to go.



#5 tmason   Members   -  Reputation: 199

Like
0Likes
Like

Posted 05 May 2014 - 12:23 PM

I didn't see an exact tutorial online or writeup on how to replace the glMultMatrixd functionality in shaders as I searched

 
glMultMatrixd is just one of the many deprecated functions. It wouldnt make sense to make tutorials separately for every single one.
On the other hand, there are very good tutorials on shaders. For-dummies and advanced ones.
(+if you switch to shaders you cant replace all the functions one-by-one and still have your stuff rendered properly, if thats what you mean. Also it would help if you would ask more direct questions:))


I guess I am still a beginner as I didn't know enough to ask a more direct question. I thought asking about replacing that function in my code was sufficient.

In either case, knowing that switching to shaders will require me to drop all of my other deprecated code is a big help.

I thought it was a case of upgrade as you go.

 
Tutorials:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
http://ogldev.atspace.co.uk/
 
You replace glMultMatrix with simple multiplying in the shaders. Like: PVM = P * V * M
(Im guessing "pGlobalPosition" is your camera/view matrix)


OK, I will also look at matrix multiplication/addition for translations as well.

For example, if all of the geometry imported for a mesh needs to be moved up and over 5 feet.

It seems like I would just:
Create another array buffer
send my global position into that array buffer
multiply the buffered vertic data with the global position buffer in a shader
and then go from there
But is that right?

 
At first:
create one VBO and fill it with some test vertex data. (also use a VAO).
load the shader source code for the vertex and fragment shaders.(dont use matrices at first)
compile the shaders and link the shader-program.
activate the program with glUseProgram, bind the VAO/VBO, draw.
 
If that works, you can start adding the matrices. For data that is small and is expected to change every frame you use "uniforms". You need to create one and load the view matrix(global position?) into it every frame.(for matrices that are used in many shaders - like the view matrix - you could create an uniform buffer, ...but dont do that now.)
...then you can add the projection matrix.
 
If you want to see a really basic example of shaders/VAOs, ...see this example Ive made not so long ago:
http://www.gamedev.net/topic/655851-basic-opengl-sdl-2-app-source/#entry5149208

I will check these out. Thank you very much for your time.

#6 tmason   Members   -  Reputation: 199

Like
0Likes
Like

Posted 05 May 2014 - 12:31 PM

You should have a very well-reasoned use-case to use double data type in matrices, because they are much slower than floats.


That was what the function I used exported the global position variable in.

I will look into converting the function and/or using a different one so I can use a float there or a better data type.

Thank you for pointing that out.

#7 tmason   Members   -  Reputation: 199

Like
0Likes
Like

Posted 05 May 2014 - 12:35 PM

… how to replace the glMultMatrixd functionality in shaders ...

Basically you don't do so at all. glMultMatrix, like all the other matrix routines, was used to compute a matrix on the CPU side. The resulting matrix then was sent to the shaders. To mimic this, you need to use a matrix library like e.g. glm and send the result as an uniform to the shader.
 
Of course, you can do the multiply inside the shader (as Aliii has shown above), and for some use cases this would be the way to go. But the vertex shader will do the product one time for every vertex it is processing, while (as long as matrices on the old matrix stack are concerned) they need to be computed at most once per model.
 
Hence the usual way is to use a matrix library, compute matrices on the CPU side, send it as uniform (stand alone or in a UBO) to the shader, and use it in the shader as is. As said, special use cases will need another way to go.

Thank you. In your experience has it taken a long time for a 4-8MB mesh to load when you performed the calculation first and then sent it over to the GPU?

#8 mhagain   Crossbones+   -  Reputation: 7413

Like
1Likes
Like

Posted 05 May 2014 - 01:04 PM

 

 

… how to replace the glMultMatrixd functionality in shaders ...

Basically you don't do so at all. glMultMatrix, like all the other matrix routines, was used to compute a matrix on the CPU side. The resulting matrix then was sent to the shaders. To mimic this, you need to use a matrix library like e.g. glm and send the result as an uniform to the shader.
 
Of course, you can do the multiply inside the shader (as Aliii has shown above), and for some use cases this would be the way to go. But the vertex shader will do the product one time for every vertex it is processing, while (as long as matrices on the old matrix stack are concerned) they need to be computed at most once per model.
 
Hence the usual way is to use a matrix library, compute matrices on the CPU side, send it as uniform (stand alone or in a UBO) to the shader, and use it in the shader as is. As said, special use cases will need another way to go.

Thank you. In your experience has it taken a long time for a 4-8MB mesh to load when you performed the calculation first and then sent it over to the GPU?

 

 

You don't perform the calculation on the mesh.  The mesh vertices remain unchanged and you do the position * MVP calculation in your vertex shader.


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#9 tmason   Members   -  Reputation: 199

Like
0Likes
Like

Posted 05 May 2014 - 01:08 PM

You don't perform the calculation on the mesh.  The mesh vertices remain unchanged and you do the position * MVP calculation in your vertex shader.


See above, another commenter suggested that you perform the calculation once on the CPU before the vertex buffer import into the GPU and thus the shaders don't have to recalculate the project. View matrix every time on the GPU side.

#10 Aliii   Members   -  Reputation: 1332

Like
1Likes
Like

Posted 05 May 2014 - 01:20 PM

He said that you multiply the matrices on CPU side once per every mesh/model. ...then upload it to the shader in an uniform, ...so you dont have to do the PVM = M * V * P per every single vertex(in the shader).

If you have 1000 vertices that would mean 1000 of this: PVM = P * V * M.

 

(but dont worry about this, unless you are about to finish your game. That is not much work for the GPU. Doing the same thing on the CPU - doing software rendering - would result in very low framerate with a 4-8MB mesh.)


Edited by Aliii, 05 May 2014 - 01:24 PM.


#11 tmason   Members   -  Reputation: 199

Like
0Likes
Like

Posted 08 May 2014 - 06:55 AM

Thanks to everyone's help I managed to figure this out. I have a separate question about the Model View Projection matrix when it comes to translating objects as well as having this matrix but I will start a separate post for that.

 

Thanks again.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS