I have probably a very simple question in OpenGL. I want to draw different shapes with textures on them. So I defined a vertex struct, which contains the positions of knots and additional information (normal vector, texture coordinates, reference to texture):
public struct Vertex
{
public Vector3 position;
public Vector3 normal;
public Vector2 texCoord;
public int texid;
public static int SizeInBytes
{
get { return Vector3.SizeInBytes * 2 + Vector2.SizeInBytes + sizeof(int); }
}
public Vertex(Vector3 position, Vector3 normal, Vector2 texCoord, int texid)
{
this.position = position;
this.normal = normal;
this.texCoord = texCoord;
this.texid = texid;
}
}
Then I create 2 vertex arrays (VA_TopBottom_WP and VA_Side_WP) with its vertex buffers (VB_TopBottom_WP and VB_Side_WP). Moreover, I create all textures.
internal void init()
{
// Create Buffer for top and bottom part
GL.GenVertexArrays(1, out VA_TopBottom_WP);
GL.BindVertexArray(VA_TopBottom_WP);
VB_TopBottom_WP = GL.GenBuffer();
// Create Buffer for side part
GL.GenVertexArrays(1, out VA_Side_WP);
GL.BindVertexArray(VA_Side_WP);
VB_Side_WP = GL.GenBuffer();
// Create textures
texes = new List<STL_Tools.Texture2D>();
texes.Add(new STL_Tools.Texture2D());//Default texture
for (int n = 0; n < session.pgm.Count(); n++)
{
texes.Add(new STL_Tools.Texture2D());
}
updateFrame();
}
Then I update the buffer content:
public void updateFrame()
{
// Top and bottom buffer
GL.BindVertexArray(VA_TopBottom_WP);
GL.BindBuffer(BufferTarget.ArrayBuffer, VB_TopBottom_WP);
//Fill vertex structure
vertBuffer_TopBottom = poly.GetTopBottomMeshesVertex();
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertex.SizeInBytes * vertBuffer_TopBottom.Length), vertBuffer_TopBottom, BufferUsageHint.StaticDraw);
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(0,3, VertexAttribPointerType.Float,false, Vertex.SizeInBytes, (IntPtr)0);//Position
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes*2));//Texture
GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes));//Normal
// Side buffer
GL.BindVertexArray(VA_Side_WP);
GL.BindBuffer(BufferTarget.ArrayBuffer, VB_Side_WP);
vertBuffer_Side = poly.GetSideVertex();//Fill vertices
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertex.SizeInBytes * vertBuffer_Side.Length), vertBuffer_Side, BufferUsageHint.StaticDraw);
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)0);//Position
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes * 2));//Texture
GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes));//Normal
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
}
The Vertex variables contain afterwards reasonable texture coordinates (Vector2 objects in the following). E. g.:
vertBuffer_Side = new Vertex[4]
{new Vertex(new Vector3(0,0,0),new Vector3(1,0,0),new Vector2(0,0),0),
new Vertex(new Vector3(0,-80,0),new Vector3(1,0,0),new Vector2(1,0),0),
new Vertex(new Vector3(0,-80,-10),new Vector3(1,0,0),new Vector2(1,1),0),
new Vertex(new Vector3(0,0,-10),new Vector3(1,0,0),new Vector2(0,0),0)};
Then I draw everything with the following function:
public void renderFrame()
{
GL.PushMatrix();
GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.NormalArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);
// Draw Side
GL.BindVertexArray(VA_Side_WP);
GL.Color3(Color.White);
GL.Enable(EnableCap.Texture2D);
for (int n = 0; n < (vertBuffer_Side.Length / 4); n++)
{
//GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindTexture(TextureTarget.Texture2D, texes[vertBuffer_Side[n*4].texid].ID);
GL.DrawArrays(PrimitiveType.Quads, n*4,4);
}
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.Disable(EnableCap.Texture2D);
//Draw top and bottom
GL.BindVertexArray(VA_TopBottom_WP);
...
GL.PopMatrix();
}
The geometry is drawn correctly. But the texture is not drawn correctly. It is drawn only with one color. It is the color of the far right pixel of the textures. Probably, the following function does not work correctly:
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes * 2));//Texture
Where is my mistake?