• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
tmason

Replacing glMultMatrixd with Shaders ...

10 posts in this topic

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
0

Share this post


Link to post
Share on other sites

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

1

Share this post


Link to post
Share on other sites

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

1

Share this post


Link to post
Share on other sites


… 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.

1

Share this post


Link to post
Share on other sites

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.
0

Share this post


Link to post
Share on other sites

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.
0

Share this post


Link to post
Share on other sites

… 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?
0

Share this post


Link to post
Share on other sites

 

 

… 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.

1

Share this post


Link to post
Share on other sites

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.
0

Share this post


Link to post
Share on other sites

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
1

Share this post


Link to post
Share on other sites

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.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0