Sign in to follow this  
reloadead

OpenGL How to process texture indices properly

Recommended Posts

reloadead    1795
Hey guys,

I've been working on loading some models and so far it's going alright, got me a nice model and everything seems to be working fine, except that I'm rather clueless on how to texture it properly.

I'm working with VBOs and I load my stuff from an .obj file. Just like the vertices, I need to draw UVs with the indices provided, but I don't know how to process them properly with opengl. I tried to do it the same way with just creating another IBO for the UVs, but I don't know if this is the right way and if it is, where to put it (as my model is simply black, it seems to fail).

I checked with GDebugger and the texture seems to be there and I also enabled it with glEnable( GL_TEXTURE_2D );

Any pointers in the right direction would be appreciated. This is what I have so far:

[code]Rld::Mesh::Mesh( String a_FileName, String a_Name )
{
testtexid = SOIL_load_OGL_texture("Data/diffuseF.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
m_Name = a_Name;
Load(a_FileName);

glGenBuffers(1, &m_VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float3) * m_Vertices.size(), &m_Vertices[0], GL_STATIC_DRAW);

glGenBuffers(1, &m_UVBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_UVBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float2) * m_UVs.size(), &m_UVs[0], GL_STATIC_DRAW);

glGenBuffers(1, &m_NormalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_NormalBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float3) * m_Normals.size(), &m_Normals[0], GL_STATIC_DRAW);

glGenBuffers(1, &m_IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * m_Indices.size(), &m_Indices[0], GL_STATIC_DRAW);

glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}

void Rld::Mesh::Render()
{
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_TEXTURE_2D );


glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

//How do I process this with an index buffer?
glEnableVertexAttribArray(1);
glBindBuffer( GL_ARRAY_BUFFER, m_UVBuffer );
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(2);
glBindBuffer( GL_ARRAY_BUFFER, m_NormalBuffer );
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer );
glDrawElements( GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0 );

glDisableVertexAttribArray(2);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);

glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glBindTexture( GL_TEXTURE_2D, 0 );
}[/code]

Share this post


Link to post
Share on other sites
karwosts    840
Unfortunately processing texture coordinates from obj models is not trivial. In opengl you only get one IBO which must be shared by all buffers (for a given vertex, position, color, texcoord, normal, must all be in the same index of the buffer).

Because obj gives each attribute its own set of indices, you will need to read in the data and rearrange/reindex everything such that all attribute buffers are aligned on a single index.

If you have trouble doing this, just search the forums and I'm sure you'll find hundreds of discussions on the topic. I think pretty much every opengl developer runs into this wall early in their development carrer.

Share this post


Link to post
Share on other sites
reloadead    1795
[quote name='karwosts' timestamp='1329337882' post='4913454']
Unfortunately processing texture coordinates from obj models is not trivial. In opengl you only get one IBO which must be shared by all buffers (for a given vertex, position, color, texcoord, normal, must all be in the same index of the buffer).

Because obj gives each attribute its own set of indices, you will need to read in the data and rearrange/reindex everything such that all attribute buffers are aligned on a single index.

If you have trouble doing this, just search the forums and I'm sure you'll find hundreds of discussions on the topic. I think pretty much every opengl developer runs into this wall early in their development carrer.
[/quote]

Hmm thanks, I feel kinda stupid seeing how many answer there have been already..

Anyway, from what I can come up with from the previous answers I simply "spread out" my UVs with duplicate entries into a buffer and left the rest as is (so my UVs don't actually need an index anymore). Will this be enough or will this work at all? The previous threads led me to believe it should work. If it should, I'm doing something wrong elsewhere. :)

Share this post


Link to post
Share on other sites
karwosts    840
I'm not sure if that's an adequate general-case solution. In some cases you may actually need to increase the size of the vertex/index buffer with new indices. In an original VBO, you can have a single position vector share two UV vectors. For example if you had a quad consisting of two triangles, with unique textures on each tri, it might look like this:

f 1/1 2/2 3/3
f 2/4 3/5 4/6

Originally you'll have a vbo/ibo of 4 vertices, but you'll end up needing 6 to represent the texcoords accurately. You'll probably need to toss the entire existing IBO and recreate one from scratch.

Share this post


Link to post
Share on other sites
reloadead    1795
Ah yes, I see what you're going at. This will eventually be something that will happen with more complex models. Suddenly I don't like .obj files anymore.

Thanks for the clarification.

Share this post


Link to post
Share on other sites
reloadead    1795
I didn't want to start a new topic as it is somewhat related to this one. I am still stuck at the texturing part. I now have one Vertex buffer with position, normal and UV data and by using another model format I don't have to use indices anymore.

The model loads just fine, all the coords are loaded properly and so does the texture (if I am allowed to believe GDebugger). However, the texture refuses to show up and right now I am not sure if this has something to do with my VBO or just not handling texturing correctly. This is how the code looks:

[code]Rld::Mesh::Mesh( String a_FileName, String a_Name )
{
testtexid = SOIL_load_OGL_texture("Data/diffuseF.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
m_Name = a_Name;
Load(a_FileName);

glGenBuffers(1, &m_VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) * m_Vertices.size(), &m_Vertices[0], GL_STATIC_DRAW);

glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

void Rld::Mesh::Render()
{
glColor3f(1.0f, 0.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, testtexid);

glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(12));

glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(24));

glDrawArrays(GL_TRIANGLES, 0, m_Vertices.size());

glDisableVertexAttribArray(2);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);

glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindTexture( GL_TEXTURE_2D, 0 );
}[/code]

glEnable( GL_TEXTURE_2D ); is called during the initialization of openGL.

Something tells me I'm either missing something in regard to calling the texture properly or I offset in the wrong way. Any help would be much appreciated!

Share this post


Link to post
Share on other sites
karwosts    840
I don't personally see anything, maybe you could post more code. Do you have a shader? How do you know that AttribArray 1 is really the texcoord, do you have glGetAttribLocation somewhere, or glBindAttribLocation?

Share this post


Link to post
Share on other sites
reloadead    1795
[quote name='karwosts' timestamp='1329414666' post='4913714']
I don't personally see anything, maybe you could post more code. Do you have a shader? [b]How do you know that AttribArray 1 is really the texcoord, do you have glGetAttribLocation somewhere, or glBindAttribLocatio[/b]n?
[/quote]

The code I gave is actually all there is when it comes to filling/using the VBO. I'm not working with shaders yet, starting from the bottom up and later on convert it with CG. The last part you mentioned, I put up in bold in the code, this is something I am not doing. I'm following the second edition of Beginning openGL Game Programming and this is pretty much the way it is done in there so I thought that would be all. It's very logical that I can't know. So how would I get to know what buffer is what?

On a side note, I know for a fact the UVs, positions and normals are right as I am able to draw them with glEnableClientState() and everything show up just fine. I can continue on that, but I would like to extend on this and not use deprecated code :)

Share this post


Link to post
Share on other sites
V-man    813
If you are going to use glVertexAttribPointer, then you need shaders.
Otherwise, use glVertexPointer, glNormalPointer and the like.

Share this post


Link to post
Share on other sites
reloadead    1795
[quote name='V-man' timestamp='1329425354' post='4913742']
If you are going to use glVertexAttribPointer, then you need shaders.
Otherwise, use glVertexPointer, glNormalPointer and the like.
[/quote]

Right, that clears it up. Thanks for the replies. Much appreciated!

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  

  • Similar Content

    • By povilaslt2
      Hello. I'm Programmer who is in search of 2D game project who preferably uses OpenGL and C++. You can see my projects in GitHub. Project genre doesn't matter (except MMO's :D).
    • By ZeldaFan555
      Hello, My name is Matt. I am a programmer. I mostly use Java, but can use C++ and various other languages. I'm looking for someone to partner up with for random projects, preferably using OpenGL, though I'd be open to just about anything. If you're interested you can contact me on Skype or on here, thank you!
      Skype: Mangodoor408
    • By tyhender
      Hello, my name is Mark. I'm hobby programmer. 
      So recently,I thought that it's good idea to find people to create a full 3D engine. I'm looking for people experienced in scripting 3D shaders and implementing physics into engine(game)(we are going to use the React physics engine). 
      And,ye,no money =D I'm just looking for hobbyists that will be proud of their work. If engine(or game) will have financial succes,well,then maybe =D
      Sorry for late replies.
      I mostly give more information when people PM me,but this post is REALLY short,even for me =D
      So here's few more points:
      Engine will use openGL and SDL for graphics. It will use React3D physics library for physics simulation. Engine(most probably,atleast for the first part) won't have graphical fron-end,it will be a framework . I think final engine should be enough to set up an FPS in a couple of minutes. A bit about my self:
      I've been programming for 7 years total. I learned very slowly it as "secondary interesting thing" for like 3 years, but then began to script more seriously.  My primary language is C++,which we are going to use for the engine. Yes,I did 3D graphics with physics simulation before. No, my portfolio isn't very impressive. I'm working on that No,I wasn't employed officially. If anybody need to know more PM me. 
       
    • By Zaphyk
      I am developing my engine using the OpenGL 3.3 compatibility profile. It runs as expected on my NVIDIA card and on my Intel Card however when I tried it on an AMD setup it ran 3 times worse than on the other setups. Could this be a AMD driver thing or is this probably a problem with my OGL code? Could a different code standard create such bad performance?
    • By Kjell Andersson
      I'm trying to get some legacy OpenGL code to run with a shader pipeline,
      The legacy code uses glVertexPointer(), glColorPointer(), glNormalPointer() and glTexCoordPointer() to supply the vertex information.
      I know that it should be using setVertexAttribPointer() etc to clearly define the layout but that is not an option right now since the legacy code can't be modified to that extent.
      I've got a version 330 vertex shader to somewhat work:
      #version 330 uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ModelViewMatrix; layout(location = 0) in vec4 Vertex; layout(location = 2) in vec4 Normal; // Velocity layout(location = 3) in vec3 TexCoord; // TODO: is this the right layout location? out VertexData { vec4 color; vec3 velocity; float size; } VertexOut; void main(void) { vec4 p0 = Vertex; vec4 p1 = Vertex + vec4(Normal.x, Normal.y, Normal.z, 0.0f); vec3 velocity = (osg_ModelViewProjectionMatrix * p1 - osg_ModelViewProjectionMatrix * p0).xyz; VertexOut.velocity = velocity; VertexOut.size = TexCoord.y; gl_Position = osg_ModelViewMatrix * Vertex; } What works is the Vertex and Normal information that the legacy C++ OpenGL code seem to provide in layout location 0 and 2. This is fine.
      What I'm not getting to work is the TexCoord information that is supplied by a glTexCoordPointer() call in C++.
      Question:
      What layout location is the old standard pipeline using for glTexCoordPointer()? Or is this undefined?
       
      Side note: I'm trying to get an OpenSceneGraph 3.4.0 particle system to use custom vertex, geometry and fragment shaders for rendering the particles.
  • Popular Now