Page 2 of 3
OpenGL Vertex Buffer Objects
Posted: Wed Jun 20, 2012 6:39 pm
by Nokurn
RandomDever wrote:OK so I've looked a bit at VBOs and I have this pseudo-code:
Code: Select all
GLuint colorBuffer = NULL;
GLuint positionBuffer = NULL;
GLubyte colors[] = { 255, 255, 255, 128 };
glGenBuffers( 1, &colors );
glBindBuffer( GL_ARRAY_BUFFER, colorBuffer );
glBufferData( GL_ARRAY_BUFFER, 4 * sizeof(GLubyte) );
glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 );
GLfloat positions[] = { -1.0F, -1.0F, 1.0F, -1.0F, 1.0F, 1.0F, -1.0F, 1.0F };
glGenBuffers( 1, &positions );
glBindBuffer( GL_ARRAY_BUFFER, positionBuffer );
glBufferData( GL_ARRAY_BUFFER, 8 * sizeof(GLfloat) );
glVertexPointer( 2, GL_FLOAT, 0, 0 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glDrawArrays( GL_QUADS, 0, 4 ); //Not entirely sure how this works
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
I don't exactly know what the third parameter of 'glDrawArrays' does, but besides that, is this code correct?
Also the example I drew from to make the above code draws a square with 2 triangles ( for some reason )
but it doesn't have a texture so how would I do that?
Code: Select all
struct Vertex {
GLfloat position[3]; // x, y, z
GLfloat texture[2]; // u, v
GLfloat color[4]; // r, g, b, a
GLubyte padding[28]; // pads structure to 64 bytes for efficiency
};
////////////
// Uploading
GLuint name;
glGenBuffers(1, &name);
glBindBuffer(GL_ARRAY_BUFFER, name);
Vertex vertices[4] = {
// x y z u v r g b a
{ {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f}, { 0 }},
{ {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, { 0 }},
{ {1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, { 0 }},
{ {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 1.0f, 0.0f}, { 0 }},
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), reinterpret_cast<GLvoid const*>(&vertices), GL_STATIC_DRAW);
//////////
// Drawing
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer (3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLvoid const*>(offsetof(Vertex, position)));
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLvoid const*>(offsetof(Vertex, texture)));
glColorPointer (4, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLvoid const*>(offsetof(Vertex, color)));
glDrawArrays(GL_QUADS, 0, sizeof vertices / sizeof(Vertex));
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
offsetof is defined in <cstddef>
Re: OpenGL Fullscreen Crashing
Posted: Wed Jun 20, 2012 8:25 pm
by RandomDever
Nokurn wrote:RandomDever wrote:Yes 'BlitTexture', based on your description, does use immediate mode.
It would be fairly easy to make it use a display list, but I'll have to do some research on VBOs, after I get some sleep.
Because essentially I am building this engine to be as fast as fast as possible, while trying to maintain some ease of use. ( As well as finally implementing a bunch of cool debug features to make it a lot easier to find bugs )
And also to make a 2D
platformer.
Keep in mind that premature optimization can often cause more problems than it solves. In this case, however, I don't think you will regret implementing a proper renderer.
Also, try to focus on the game aspect of the project. Too often people start out to write a game, then start writing an engine, then get sidetracked by the engine. Many engines grow naturally as you develop a game. Once the game is done, you can pull out the engine code and then work on it as an engine. Or, you could incorporate it in another game, let it grow, and continue the cycle. You'll end up with a much more mature engine than if you specifically wrote an engine.
I plan to make things as I need them while developing the game, but since the rendering system is so important I am focusing on getting that up to snuff before going all out on the game.
And I had a pretty 'mature' engine before this one but I decided to rebuild from the ground up with OpenGL, because replacing the current engine would take longer anyway.
EDIT: Thanks for the code I'll implement it whenever I get over being sick...
EDIT 2: Wait... UV is where the texture goes. but what about the texture id?
Re: OpenGL Fullscreen Crashing
Posted: Wed Jun 20, 2012 11:57 pm
by Nokurn
RandomDever wrote:Nokurn wrote:RandomDever wrote:Yes 'BlitTexture', based on your description, does use immediate mode.
It would be fairly easy to make it use a display list, but I'll have to do some research on VBOs, after I get some sleep.
Because essentially I am building this engine to be as fast as fast as possible, while trying to maintain some ease of use. ( As well as finally implementing a bunch of cool debug features to make it a lot easier to find bugs )
And also to make a 2D
platformer.
Keep in mind that premature optimization can often cause more problems than it solves. In this case, however, I don't think you will regret implementing a proper renderer.
Also, try to focus on the game aspect of the project. Too often people start out to write a game, then start writing an engine, then get sidetracked by the engine. Many engines grow naturally as you develop a game. Once the game is done, you can pull out the engine code and then work on it as an engine. Or, you could incorporate it in another game, let it grow, and continue the cycle. You'll end up with a much more mature engine than if you specifically wrote an engine.
I plan to make things as I need them while developing the game, but since the rendering system is so important I am focusing on getting that up to snuff before going all out on the game.
And I had a pretty 'mature' engine before this one but I decided to rebuild from the ground up with OpenGL, because replacing the current engine would take longer anyway.
EDIT: Thanks for the code I'll implement it whenever I get over being sick...
EDIT 2: Wait... UV is where the texture goes. but what about the texture id?
The texture is not explicitly bound to the VBO. If GL_TEXTURE_COORD_ARRAY is enabled, the VBO will be rendered using the bound texture, the same as glTexCoord + glVertex.
Edit: I don't know what I'm talking about.
Re: OpenGL Fullscreen Crashing
Posted: Sat Jun 23, 2012 7:17 pm
by RandomDever
Okay. So I feel a bit better now.
So what do you not know what you're talking about?
Does it use the bound texture or not?
Also. I'm assuming I can modify this buffer at any time correct?
The only thing I would change is the alpha.
BTW the implementation you gave me and the one I saw when I researched used per vertex coloring.
I don't need this yet so is there a more efficient way to make VBOs? Or does it have to have per vertex color data?
Also. Do VBOs take rotation and scale data? Or can I just use glRotate and glScale?
Also. I want my games to support changing resolution. But when the screen is stretched textures (especially text) look a bit pixelated.
Is there a good way to deal with this? Or do I have to make textures for the highest resolution I want to support so that they never get scaled up?
I know. Alot of questions. But hey. I was stuck in a bed for 2-3 days with nothing to do.
Re: OpenGL Fullscreen Crashing
Posted: Mon Jun 25, 2012 3:11 pm
by Nokurn
RandomDever wrote:So what do you not know what you're talking about?
I removed a section about multitexturing.
RandomDever wrote:Does it use the bound texture or not?
It uses the bound and active texture.
RandomDever wrote:Also. I'm assuming I can modify this buffer at any time correct?
Yes. Use glBufferSubData.
RandomDever wrote:The only thing I would change is the alpha.
You will probably want to use a shader for this instead. You'll be calling glBufferSubData a lot to update each alpha value.
RandomDever wrote:BTW the implementation you gave me and the one I saw when I researched used per vertex coloring.
I don't need this yet so is there a more efficient way to make VBOs? Or does it have to have per vertex color data?
I don't know exactly what you mean by this, but you can disable the color attribute by skipping the corresponding gl(Enable|Disable)ClientAttribute calls and not calling glColorPointer. Usually you will use a shader for colors anyway.
RandomDever wrote:Also. Do VBOs take rotation and scale data? Or can I just use glRotate and glScale?
The transform data isn't embedded in the VBO. If you're using the fixed pipeline, you will use glRotate, glScale, and glTranslate to apply transformations to your VBO prior to rendering. If you're using the modern pipeline, you will provide a transform matrix to your vertex shader with glUniform and multiply it in.
RandomDever wrote:Also. I want my games to support changing resolution. But when the screen is stretched textures (especially text) look a bit pixelated.
Is there a good way to deal with this? Or do I have to make textures for the highest resolution I want to support so that they never get scaled up?
Use high resolution textures. Down scaling looks better than up scaling.
Re: OpenGL Fullscreen Crashing
Posted: Mon Jun 25, 2012 11:54 pm
by RandomDever
Thank you for answering the 20 ?s I had there.
But here's some more:
What exactly are 'shaders' and how would you use them for coloring and alpha blending?
Also, how should I handle changing aspect ratios?
My game is going to be designed for 4:3 but I want it to support 16:9 as well.
But is there a good way to have it support both without stretching?
Re: OpenGL Fullscreen Crashing
Posted: Tue Jun 26, 2012 1:27 pm
by Nokurn
RandomDever wrote:What exactly are 'shaders' and how would you use them for coloring and alpha blending?
Shaders are miniature programs written specifically to run on the GPU. Their uses vary from pass-through shaders that enable a modern pipeline to function to simple sine-based water shaders to advanced rendering techniques like Phong shading, FXAA, and most forms of realtime lighting.
There are a number of types, but the two original and most basic shaders are:
- Vertex shaders are called for each vertex being rendered. You use them to transform the vertex's position in 3D space. This is where you would apply transformation matrices (projection, world, local) in a modern pipeline (the built-in OpenGL transformation functions were deprecated in 3.0 and removed in 3.1).
- Fragment shaders are called for each fragment (similar to a pixel) being rendered. You use them to alter a pixel's final appearance, including color, alpha, and depth. This is where you would sample a texture to determine the color for the pixel.
You can find a lot of good shader tutorials online.
RandomDever wrote:Also, how should I handle changing aspect ratios?
My game is going to be designed for 4:3 but I want it to support 16:9 as well.
But is there a good way to have it support both without stretching?
It depends on your game. Some ways to handle it are:
- Lock the aspect ratio; don't let the player choose a resolution without your target aspect ratio. Full screen will always be stretched without some form of black bars.
- Render a larger portion of the scene to accomodate widescreen monitors. This is typically the best way to go for 3D games where you can control the fov, but for 2D games it may give too much of an advantage to allow the player to see more of the playfield.
- Maintain different sets of assets for different aspect ratios. For unexpected aspect ratios, select the nearest match. This is a lot of work, but you'll get the best visual results for 2D games. It's been done several times before, and most games that run on both iPod/iPhone and iPad use this technique.
If there are any games that you are modeling yours after, you should examine them and see how they react to aspect ratio changes.
Edit: Added more examples of shader uses.
Re: OpenGL Fullscreen Crashing
Posted: Fri Jul 13, 2012 9:40 pm
by RandomDever
I know it's been a while since I asked a question but I have a couple.
If I have animated textures and I'm using a VBO ( assuming I'm using a sprite sheet ) how would I change frames?
Or should I just devise some way to load a sprite sheet as individual textures?
Re: OpenGL Fullscreen Crashing
Posted: Sat Jul 14, 2012 11:08 am
by qpHalcy0n
I would avoid splitting the sprites up.
Load all of the possible texture coordinate pairs into the VBO consecutively so the VBO might look like:
Vx, Vy, Vz, T1x, T1y, T2x, T2y, T3x, T3y, etc on to the next vertex.
Just advance the texture coordinate pointer via glTexCoordPointer. Now, if you have multiple sprites in the set and the frames aren't all synchronized, then you'll likely have to split up the draw calls and handle the texture coordinate pointers accordingly. This will avoid having to lock the VBO up to remap it, which is costly and not recommended.
This becomes much much easier in the programmable pipeline.
Re: OpenGL Fullscreen Crashing
Posted: Sat Jul 14, 2012 4:21 pm
by RandomDever
Well now I'm getting an error:
Code: Select all
error C3861: 'glGenBuffers': identifier not found
error C3861: 'glBindBuffer': identifier not found
error C3861: 'glBufferData': identifier not found
I really don't understand this.
Re: OpenGL Fullscreen Crashing
Posted: Sat Jul 14, 2012 6:48 pm
by qpHalcy0n
Support for VBO was added to the specification in 2003 (V1.5). The appropriate GL version may not have been brought into scope or you have a very old glext.h.
In any event, tack on "ARB" to the end. This is pre-1.5 syntax. (glGenBuffersARB, glBindBufferARB, etc...)
Welcome to OpenGL, enjoy your stay....
Re: OpenGL Fullscreen Crashing
Posted: Sat Jul 14, 2012 10:22 pm
by RandomDever
Code: Select all
error C3861: 'glGenBuffersARB': identifier not found
error C3861: 'glBindBufferARB': identifier not found
error C3861: 'glBufferDataARB': identifier not found
Re: OpenGL Fullscreen Crashing
Posted: Sun Jul 15, 2012 2:10 am
by qpHalcy0n
Did you not have this code working before? Have you included glext.h? To make it easier, you might use GLEW for all of this. Handling extensions and GL versioning across vendors and across platforms is a monolithic pain in the ass ... and thats being nice.
Re: OpenGL Fullscreen Crashing
Posted: Sun Jul 15, 2012 6:32 pm
by RandomDever
Whenever I try to include glext.h it tells me it can't.
However in SDL_opengl I believe you simply define GL_GLEXT_PROTOTYPES.
But when I do that:
Code: Select all
error LNK2001: unresolved external symbol _glBufferDataARB@16
error LNK2001: unresolved external symbol _glBindBufferARB@8
error LNK2001: unresolved external symbol _glGenBuffersARB@8
Yeah. OpenGL!!!
Re: OpenGL Fullscreen Crashing
Posted: Sun Jul 15, 2012 7:56 pm
by qpHalcy0n
Do you even HAVE glext.h? It will be in the window's SDK gl include subdirectory. I can't speak for SDL, but if you're linked against OpenGL32.lib you should have no problems. The extensions are implemented by the vendor driver.