how to make VBO with textures

Started by
6 comments, last by Jacob Jingle 12 years, 7 months ago
Hey there, I'm trying to code in C++ a mesh with VBO, I already have the vertex, normals and the indices, with a bit of code using functions like these:



glGenBuffers(NUM_BUFFERS, sfm->buffers);

//vertex
glBindBuffer(GL_ARRAY_BUFFER, sfm->buffers[VERTICES]);
glBufferData(GL_ARRAY_BUFFER, sfm->numOfVertexes*sizeof(float)*FLOATS_PER_VERTEX, sfm->verte, GL_STATIC_DRAW);
glVertexPointer(3,GL_FLOAT,0,BUFFER_OFFSET(0));
glEnableClientState(GL_VERTEX_ARRAY);

//normals
glBindBuffer(GL_ARRAY_BUFFER, sfm->buffers[NORMALS]);
glBufferData(GL_ARRAY_BUFFER, sfm->numOfNormals*sizeof(float)*FLOATS_PER_NORMAL, sfm->normals, GL_STATIC_DRAW);
glNormalPointer(GL_FLOAT,0,BUFFER_OFFSET(0));
glEnableClientState(GL_NORMAL_ARRAY);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sfm->buffers[INDICES]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sfm->numOfIndices*sizeof(int) ,sfm->indices, GL_STATIC_DRAW);



but I found a "half-problem", I was searching and found the function "glTexCoordPointer" which I can use to add to my VBO the texture coordinates with some more functions like in the code above, the problem here is that I can't find any functions that change my texture, sometimes I might want to use a different texture in some of parts of my mesh.

I call this a "half-problem" because I think I can create a very big texture for the whole mesh, but I would like to know if there is a way to change my texture when I'm drawing the mesh, is it possible or do I have to use the giant texture idea?
Advertisement
http://lspiroengine.com/?p=96

You are referring to what I call “render parts”. See diagram.
Right now your buffer represents an entire mesh.
But it is not possible to change materials and textures within the rendering of that mesh.

There are advanced ways to get around this, such as texture atlasing, but it is probably best to stay simple for now.
So you need to break those into more buffers.
You will need one buffer per material and the triangles that reference that material go into that buffer.
Then you can overcome this problem by setting one material (texture, shader, etc.) rendering that buffer, setting the next material, and rendering that buffer, etc.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

The old way is to glBindTexture the texture and then draw.
The new way is to use a texture array (TEXTURE_2D_ARRAY) and in your shader you select the texture layer using the 3rd coordinate.

Another method is called texture atlas. google it.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Take the above advice. I didn’t know OpenGL had that (texture arrays).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Thanks for the help,

[color=#1C2837][size=2]texture atlas was what I was thinking when I talked about the big texture, texture arrays from what I saw is a good solution, but I can't find good documentation about it and I still haven't found anything in my openGL book that describes it well, and from what i read, texture arrays can only be used in nvidia 8x00+ graphics cards, and I assume in ati/amd equivalent cards.
[color=#1C2837][size=2]

[color=#1C2837][size=2]I'm making a tower defense game, so I'm using a mesh with square zones (each square is made of 2 triangles), so I think I can render 2 triangles and after that change my texture and render other too, and continue this cycle until I complete my rendering function.

Thanks for the help,

[color="#1C2837"]texture atlas was what I was thinking when I talked about the big texture, texture arrays from what I saw is a good solution, but I can't find good documentation about it and I still haven't found anything in my openGL book that describes it well.

This is some code I put together quickly from when I was learning to do this.



glGenTextures(1, &yourtextureid);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, yourtextureid);

//create a TEXTURE_2D_ARRAY, making sure the texture width and height are the dimensions of your largest texture.
//The last argument is NULL as we want to iterate through our images and put them in the correct position in our texture array using glTexSubImage
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalTextureFormat, textureWidth, textureHeight, numberOfTextures, 0, textureFormat, GL_UNSIGNED_BYTE, NULL);

//iterate through the images to put into your texture array
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, image.width, image.height, 1, textureFormat, GL_UNSIGNED_BYTE, image.pixelData);


#version 420 core
uniform sampler2DArray myTextureSampler;
in vec2 UV;
in int index;
out vec3 out_Color;

void main(void)
{
//Use the texture coordinates as usual but the different textures are indexed by the third component of a vec3
out_Color = texture2DArray(myTextureSampler, vec3(UV, index)).rgb;
}
[font=arial, verdana, tahoma, sans-serif][size=2]I already made a VertexCoordPointer, it's working great, but if I want to draw tiles with different texture I have to draw one tile at a time or use an atlas texture, is there a limit for texture size?[/font][font=arial, verdana, tahoma, sans-serif][size=2]
[/font][color=#1C2837][size=2]
Jacob Jingle
[size=2][color=#880000]#version 420 core[color=#000000]
uniform sampler2DArray myTextureSampler[color=#666600];[color=#000000]
[color=#000088]in[color=#000000] vec2 UV[color=#666600];[color=#000000]
[color=#000088]in[color=#000000] [color=#000088]int[color=#000000] index[color=#666600];[color=#000000]
[color=#000088]out[color=#000000] vec3 out_Color[color=#666600];[color=#000000]

[color=#000088]void[color=#000000] main[color=#666600]([color=#000088]void[color=#666600])[color=#000000]
[color=#666600]{[color=#000000]
[color=#880000]//Use the texture coordinates as usual but the different textures are indexed by the third component of a vec3[color=#000000]
out_Color [color=#666600]=[color=#000000] texture2DArray[color=#666600]([color=#000000]myTextureSampler[color=#666600],[color=#000000] vec3[color=#666600]([color=#000000]UV[color=#666600],[color=#000000] index[color=#666600])).[color=#000000]rgb[color=#666600];[color=#000000]
[color=#666600]}
[color="#666600"]

[color="#666600"]

[color="#666600"]is that GLSL? if it is i would need to learn about it, since I never used it. But I think I understand your idea, that's very close to what I wanted to use. Thanks.

[font="arial, verdana, tahoma, sans-serif"]I already made a VertexCoordPointer, it's working great, but if I want to draw tiles with different texture I have to draw one tile at a time or use an atlas texture, is there a limit for texture size?[/font]

The code I gave you is one draw call. As for size limit: Texture.

[color="#666600"]is that GLSL? if it is i would need to learn about it, since I never used it. But I think I understand your idea, that's very close to what I wanted to use. Thanks.

Yes this is GLSL(4.20)...And it's definitely worth learning.

This topic is closed to new replies.

Advertisement