VBO的纹理浮雕纹理
问题描述:
看起来好像我在我的游戏中纹理VBOs时遇到了一些麻烦。 VBO本身似乎渲染得很好,我甚至可以相应地切换面部。但是,当我尝试添加纹理时,一切看起来都是歪斜的,有些纹理甚至出现在错误的面上。当我使用VAO的时候,一切正常,所以我目前不知道为什么纹理突然不起作用。VBO的纹理浮雕纹理
这里是一个形象:
这里是相关的数据:
private static uint frontFaceHandle;
private static uint backFaceHandle;
private static uint leftFaceHandle;
private static uint rightFaceHandle;
private static uint topFaceHandle;
private static uint bottomFaceHandle;
private static uint indexBufferId;
private static uint colorBufferId;
private static uint texCoordBufferId;
private static float[] textureCoordData = {
0, 1,
1, 1,
1, 0,
0, 0,
};
private static ushort[] indices = {
0, 1, 3,
0, 3, 2
};
private static float[] colorData = {
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
};
private static float[] frontFaceVert = {
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f
};
private static float[] backFaceVert = {
1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
};
private static float[] leftFaceVert = {
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
};
private static float[] rightFaceVert = {
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
};
private static float[] topFaceVert = {
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
};
private static float[] bottomFaceVert = {
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
};
我上传数据的方式:
static Voxel() {
/**
* Front Face
*/
GL.GenBuffers(1 , out frontFaceHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer , frontFaceHandle);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)(frontFaceVert.Length * sizeof(float)) ,
frontFaceVert ,
BufferUsageHint.StaticDraw);
/**
* Back Face
*/
GL.GenBuffers(1 , out backFaceHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer , backFaceHandle);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)(backFaceVert.Length * sizeof(float)) ,
backFaceVert ,
BufferUsageHint.StaticDraw);
/**
* Left Face
*/
GL.GenBuffers(1 , out leftFaceHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer , leftFaceHandle);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)(leftFaceVert.Length * sizeof(float)) ,
leftFaceVert ,
BufferUsageHint.StaticDraw);
/**
* Right Face
*/
GL.GenBuffers(1 , out rightFaceHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer , rightFaceHandle);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)(rightFaceVert.Length * sizeof(float)) ,
rightFaceVert ,
BufferUsageHint.StaticDraw);
/**
* Top Face
*/
GL.GenBuffers(1 , out topFaceHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer , topFaceHandle);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)(topFaceVert.Length * sizeof(float)) ,
topFaceVert ,
BufferUsageHint.StaticDraw);
/**
* Bottom Face
*/
GL.GenBuffers(1 , out bottomFaceHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer , bottomFaceHandle);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)(bottomFaceVert.Length * sizeof(float)) ,
bottomFaceVert ,
BufferUsageHint.StaticDraw);
/**
* Texture Buffer
*/
GL.GenBuffers(1 , out texCoordBufferId);
GL.BindBuffer(BufferTarget.ArrayBuffer , texCoordBufferId);
GL.BufferData(BufferTarget.ArrayBuffer , (IntPtr)(textureCoordData.Length * sizeof(float)) , textureCoordData , BufferUsageHint.StaticDraw);
/**
* Index Buffer
*/
GL.GenBuffers(1 , out indexBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.BufferData(
BufferTarget.ElementArrayBuffer ,
(IntPtr)(indices.Length * sizeof(ushort)) ,
indices ,
BufferUsageHint.StaticDraw);
/**
* Color buffer (This Remains unused for now
*/
GL.GenBuffers(1 , out colorBufferId);
GL.BindBuffer(BufferTarget.ArrayBuffer , colorBufferId);
GL.BufferData(
BufferTarget.ArrayBuffer ,
(IntPtr)colorData.Length ,
colorData ,
BufferUsageHint.StaticDraw);
}
而且我的方式绘制立方体(每张脸都是独立的vbo):
public void Render(FirstPersonCameraWidget gameCamera) {
GL.Translate(Location.X , Location.Y , Location.Z);
GL.Enable(EnableCap.Texture2D);
GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);
if(ShowFrontFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , frontFaceHandle);
GL.BindBuffer(BufferTarget.TextureBuffer , texCoordBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.FrontFace.GetID());
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
}
if(ShowBackFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , backFaceHandle);
GL.BindBuffer(BufferTarget.TextureBuffer , texCoordBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.BackFace.GetID());
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
}
if(ShowLeftFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , leftFaceHandle);
GL.BindBuffer(BufferTarget.TextureBuffer , texCoordBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.LeftFace.GetID());
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
}
if(ShowRightFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , rightFaceHandle);
GL.BindBuffer(BufferTarget.TextureBuffer , texCoordBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.RightFace.GetID());
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
}
if(ShowTopFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , topFaceHandle);
GL.BindBuffer(BufferTarget.TextureBuffer , texCoordBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.TopFace.GetID());
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
}
if(ShowBottomFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , bottomFaceHandle);
GL.BindBuffer(BufferTarget.TextureBuffer , texCoordBufferId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.BottomFace.GetID());
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
}
GL.Translate(-Location.X , -Location.Y , -Location.Z);
}
希望有人能够发现我做错了什么。
更新:我已修复@Andom M. Coleman的建议,它的工作原理,但立方体仍然略微歪斜。
答
您正在使用不同的维也纳组织你的纹理坐标阵列和阵位,是否正确?有没有对这些事情的离散结合的位置,你的代码实际上应该是这样的:
if(ShowFrontFace) {
GL.BindBuffer(BufferTarget.ArrayBuffer , frontFaceHandle);
GL.VertexPointer(3 , VertexPointerType.Float , 0 , IntPtr.Zero);
// ArrayBuffer!
GL.BindBuffer(BufferTarget.ArrayBuffer , texCoordBufferId);
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D , TextureAtlas.FrontFace.GetID());
GL.BindBuffer(BufferTarget.ElementArrayBuffer , indexBufferId);
GL.DrawElements(PrimitiveType.Triangles , 6 , DrawElementsType.UnsignedShort , IntPtr.Zero);
注:BufferTarget.TextureBuffer
实际上是一个完全不同的使用缓冲对象(纹理缓冲对象)。
顶点缓冲区,你将永远将它们绑定到BufferTarget.ArrayBuffer
再下gl___CoordPointer (...)
通话将相对于无论是当前绑定的存在。
在您的原始代码中,因为BufferTarget.ArrayBuffer
只被设置一次,所以您的纹理坐标指针实际上来自与您的顶点位置相同的一组数据。这显然不是你想要的行为。实际上,如果你想获得幻想,你可以将纹理指针的规格从分支中拉出来,因为它是不变的。只要做到以下每次一旦你画你的立方体:
GL.BindBuffer (BufferTarget.ArrayBuffer , texCoordBufferId );
GL.TexCoordPointer(2 , TexCoordPointerType.Float , 0 , IntPtr.Zero);
@Andom M.科尔曼请参阅编辑的问题。 – Krythic 2014-09-20 19:58:12
但我肯定会这样做,你知道为什么我的纹理仍然略有偏斜吗?它是我的纹理坐标吗? – Krythic 2014-09-20 20:02:00
是的,从你的顶点位置设置的方式来看,我认为你的坐标实际上应该是:0,0 0,1 1,0 1,1。 – 2014-09-20 20:03:24