0

Say that I have a vertex shader. It's input section looks like this (simplified):

layout(location = 0) in vec3 V_pos;
layout(location = 1) in vec3 V_norm;
layout(location = 2) in vec2 V_texcoord1;
layout(location = 3) in vec2 V_texcoord2;
layout(location = 4) in int V_texNum;

What I want is to have the first 4 inputs come from an element buffer, while the last will come from a regular buffer. Eg, in this example, each element has two uv pairs, and I want to be able to give certain faces different textures to sample from.

Can this be done? One other option would be to give the shader a huge uniform of integers containing the values for texNum, and access that with gl_VertexID. But, that seems like a really ugly way to do it.

I'm using OpenGL 3.3 (happy to use extensions though) and c++.

Jagoly
  • 939
  • 1
  • 8
  • 32
  • "Element buffers" are only used during primitive assembly, in order to figure out the order of the vertices. In this example everything would have to be a "vertex buffer" because they are all vertex attributes. There's nothing preventing you from creating a set of integer vertex attributes, you just need to set the vertex pointer using the appropriate command (e.g. `glVertexAttribPointerI (...)`). – Andon M. Coleman Oct 05 '14 at 16:17
  • I'm not sure I know what you mean. When I'm drawing this, I do glBindVertexArray(vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glDrawElements(GL_TRIANGLES, iCount, GL_UNSIGNED_INT, 0); Where do I put the glVertexAttribPointer call? – Jagoly Oct 05 '14 at 16:26
  • Wherever you setup your vertex array object (`vao`) originally. – Andon M. Coleman Oct 05 '14 at 16:28
  • But then they will end up indexed in the same way as all other inputs. What I want is for the value to per-usage. So the array will be the same size as the index buffer. – Jagoly Oct 05 '14 at 16:31
  • Then you need to use `gl_PrimitiveID` in the geometry/fragment shader. But you'll have to limit yourself to no more than 48 triangles per-pass in GL3.3 if you want each face to have a different texture (that is the maximum number of texture image units). – Andon M. Coleman Oct 05 '14 at 16:36
  • Ok. I didn't want every face to have its own texture, just to be able to set each face to a specific texture (out of say 4). I didn't know about gl_PrimativeID, but I suppose it's the same as gl_VertexID / 3. Anyway, that is what I meant with using a big uniform. I guess that's the way to go? – Jagoly Oct 05 '14 at 16:39
  • Yeah, a lookup table is probably going to be necessary. There's an [AMD-specific extension](https://www.opengl.org/registry/specs/AMD/interleaved_elements.txt) that allows you to index certain vertex attributes separately - effectively you can pack up to 4 8-bit vertex indices or 2 16-bit indices into each element. It's not particularly portable so I don't think that's what you want. – Andon M. Coleman Oct 05 '14 at 16:42
  • Ok, going with the big uniform and lookup with primitaveid, how will the shader know how big the uniform is? – Jagoly Oct 05 '14 at 16:50
  • the answer here looks good, thanks :D http://stackoverflow.com/questions/20647207/glsl-replace-large-uniform-int-array-with-buffer-or-texture – Jagoly Oct 05 '14 at 16:56

0 Answers0