VBO Multiple texture coords

Hey, I have a terrain made of 4 tiling textures(grass,dirt,metal,concrete) + one ‘mixmap’ as described in the top solution here: http://stackoverflow.com/questions/1110844/multiple-texture-images-blended-together-onto-3d-ground where the value of each channel(RGBA) corresponds to the alpha of the texture assigned to it (so red is the opacity of the grass texture at that pixel)

EVERYTHING works fine if I use the same texture coords for both. However, Since I want my ground textures to tile, and the mixmap to not tile (so top left corner of the map is texture coords 0,0 and bottom right is 1,1) I need to use separate texture coordinates for the map textures and the mixmap.

I am using an interleaved VBO. When I use gl_TexCoord[1].st, it doesn’t seem to work. For now I’m setting the second set of texture coords to have the same value as the first, but it’s not working.

Vertex Shader:


void main()
{
	gl_FrontColor = gl_Color;
	gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
	gl_TexCoord[0]=gl_MultiTexCoord0;
	gl_TexCoord[1]=gl_MultiTexCoord1;
}

Fragment shader:


const int NUM_MAP_TEXTURES = 4;
uniform sampler2D maskTexture;
uniform sampler2D mapTextures[NUM_MAP_TEXTURES];
vec3 textureColours[NUM_MAP_TEXTURES];

void main()
{
	/*vec4 maskColour = vec4(texture2D(maskTexture, gl_TexCoord[1].st)); //gl_TexCoord[0]
	maskColour.a = 1 - maskColour.a;
	
	for(int i=0;i<NUM_MAP_TEXTURES;i++)
		textureColours[i] = vec3(texture2D(mapTextures[i], gl_TexCoord[0].st));
	
	vec3 finalColour = textureColours[0] * maskColour.r;
	for(int i=1;i<NUM_MAP_TEXTURES;i++)
		finalColour = mix(finalColour,  textureColours[i], maskColour[i]);
	
	gl_FragColor = vec4(finalColour, 1.0) * gl_Color;*/
	
	vec4 maskColour = vec4(texture2D(maskTexture, gl_TexCoord[1].st)); //gl_TexCoord[0].st 'works' but I need to use 1
	gl_FragColor = maskColour;
}

VBO creation:


int numTriangles = 2;
			int numVertices = numTriangles * 3;
			int vertexSize = (2 + 2 + 2)*4; //xy (2D) + texture COORDS(2 sets) only. NO COLOUR OR NORMALS //*4 for sizeof(float)
			FloatBuffer vertexData = BufferUtils.createFloatBuffer(vertexSize*numVertices);
			vertexData.put(new float[]{
					//Triangle 1
					-150,-150, 0,0,0,0, //0.2f,0.2f,
					150,-150, 1,0,1,0, //0.6f,0.2f,
					-150,150, 0,1,0,1,//0.2f,0.6f,
					
					//Triangle 2
					150,-150, 1,0,1,0, //0.6f,0.2f,
					-150,150, 0,1,0,1, //0.2f,0.6f,
					150,150, 1,1,1,1});  //0.6f,0.6f});
			vertexData.flip();
			vertexBufferData(vertexBufferID, vertexData);

Rendering:


//Bind shader [omitted]

GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferID);
			
int vertexSize = (2 + 2+ 2)*4; //xy + uv + uv2
int numVertices = 6;
			
GL11.glVertexPointer(2, GL11.GL_FLOAT, vertexSize/*stride*/, 0/*offset*/);


GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, vertexSize/*stride*/, 2*4/*offset*/);

int sampler=ARBShaderObjects.glGetUniformLocationARB(shader.GetShaderID(), "mapTextures[0]");
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textures[0].GetTextureID());
ARBShaderObjects.glUniform1iARB(sampler, 0);



GL13.glActiveTexture(GL13.GL_TEXTURE1);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, vertexSize/*stride*/, (2+2)*4/*offset*/);
sampler=ARBShaderObjects.glGetUniformLocationARB(shader.GetShaderID(), "maskTexture");
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mixMapTexture.GetTextureID());
ARBShaderObjects.glUniform1iARB(sampler, 1);

GL13.glActiveTexture(GL13.GL_TEXTURE0);

GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, numVertices);

GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);


//Unbind shader [omitted]

Ouput using vec4 maskColour = vec4(texture2D(maskTexture, gl_TexCoord[0].st));
NB my mixmap texture has 4 bars of colour: 1,0,0,1 0,1,0,1 0,0,1,1 0,0,0,0

Ouput using vec4 maskColour = vec4(texture2D(maskTexture, gl_TexCoord[1].st));

However if I change the mixmap image colour to full green, it will show a full green rectangle. I’m thinking that the 2nd set of texture coords just doesn’t work at all and they are all set to (0,0) or something.

Can anyone help me figure this out?
Thanks,
roland

Noticed that your two sets of the texturecoords are the same.


// Set1    Set2
   0,0,    0,0,
   1,0,    1,0,
   0,1,    0,1,

   1,0,    1,0,
   0,1,    0,1,
   1,1,    1,1

So, you can pass only one set of them and use them directly in the shader. (If that is what intended)

Thanks for the reply, I was just using it for testing.
The following still makes only the red square come up:


vertexData.put(new float[]{
	//Triangle 1
	-150,-150, 0,0,0.1f,0.1f,
	150,-150, 1,0,0.6f,0.1f,
	-150,150, 0,1,0.1f,0.6f,

	//Triangle 2
	150,-150, 1,0,0.6f,0.1f,
	-150,150, 0,1,0.1f,0.6f,
	150,150, 1,1,0.6f,0.6f});
vertexData.flip();

All you should have to do is scale the non-mixmap textures to a smaller size. Then you don’t need two sets of tex coords

edit: something along the lines of this

vec4 texture0_color_map = texture2D(texture0, TexCoord * tex_scale);

Thanks, that looks like a possible solution and in most cases would be fine. However I need to be able to set custom texture coordinates for my vertices so I have to use 2 sets :frowning: Any other ideas?

I found 2 solutions.

One: (From http://www.gamedev.net/topic/509671-vbo-multiple-texture-coordinates-per-vertex-tex-coord-per-triangle/ “If you are using vbo’s (indexed or not), for each vertex a set of properties is stored (depending on what buffers you use), for example: position, normal and texture coordinates. As far as I know, if a certain vertex is used multiple times, but each time you need other texture coordinates, this is not possible. In this case you have to store the vertex and the texture coordinates multiple times in your buffers.”

Two (My solution): gl_TexCoord[0] is actually a 4d vector, so by using gl_TexCoord[0].st for the first two coordinates and new vec2(gl_TexCoord[0][2],gl_TexCoord[0][3]) I was able to hack in a 2nd set of texture coordinates by using GL11.glTexCoordPointer(4, …). I’m not sure what consequences this may cause, but seems to work for my 2d game and means I don’t need to duplicate the vertex coords or use gl_TexCoord[1]

There won’t be consequences.

glTexCoordPointer is just an arbitrary vertex attribute. You can use it for anything: colors, normals, an angle… or indeed a pair of 2d texcoords.

In fact, it’s preferable to use glVertexAttribPointer, as that is the ‘modern’, generic way to specify your vertex attributes.

Cool thanks for clarifying that :slight_smile:
I’ll look into it.