我正在尝试渲染大量的立方体,例如" Minecraft"一个使用C#+ OpenTK + OpenGL 4.1的块。 为此,我创建了一个类型为" ElementArrayBuffer"的缓冲区。索引和类型" ArrayBuffer"的缓冲区存储顶点。 但我认为要描述它,比检查代码更困难。 如果有人有疑问请告诉我。
所以现在问题。
渲染结果不是我想要的,我不明白为什么和什么是错的。
如果我渲染这个我得到这个结果:
class Chunk
{
// The size of the chunk
// One unit means one cube
public const int WIDTH = 5;
public const int HEIGHT = 5;
public const int DEPTH = 2;
private int[][][] mData;
// The attribute location the the shader program
private int mVePositionLocation;
private int mVertexArray;
private int mIndexBuffer;
private int mVertexBuffer;
private int mIndexCount;
public Chunk(int pVePositionLocation)
{
mVePositionLocation = pVePositionLocation;
GenerateData();
GenerateMesh();
}
private void GenerateData()
{
mData = new int[DEPTH][][];
for(int z = 0; z < DEPTH; z++)
{
mData[z] = new int[HEIGHT][];
for(int y = 0; y < HEIGHT; y++)
{
mData[z][y] = new int[WIDTH];
for(int x = 0; x < WIDTH; x++)
{
mData[z][y][x] = 1;
}
}
}
}
private void GenerateMesh()
{
Queue<float> vertices = new Queue<float>();
Queue<uint> indices = new Queue<uint>();
uint offset = 0;
for (int z = 0; z < DEPTH; z++)
{
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
{
// If the value is bigger than 0 there is a cube so it should be generated
if(mData[z][y][x] > 0)
{
GenerateCube(x, y, z, offset, vertices, indices);
// Normally 36 indices offset, but for now I only generate the front face of each cube so only 6 indices
offset += 6;
}
}
}
}
// Create and fill the buffer with the indices
mIndexBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ElementArrayBuffer, mIndexBuffer);
GL.BufferData<uint>(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Count * sizeof(uint)), indices.ToArray(), BufferUsageHint.StaticDraw);
mVertexArray = GL.GenVertexArray();
GL.BindVertexArray(mVertexArray);
// The buffer with the vertices
mVertexBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, mVertexBuffer);
GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Count * sizeof(float)), vertices.ToArray(), BufferUsageHint.StaticDraw);
// The shader only needs the position
GL.EnableVertexAttribArray(mVePositionLocation);
GL.VertexAttribPointer(mVePositionLocation, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
// Store the index count, so I can render later
mIndexCount = indices.Count;
}
private void GenerateCube(int pX, int pY, int pZ, uint pOffset, Queue<float> pVertices, Queue<uint> pIndices)
{
// Front face vertices
pVertices.Enqueue(pX);
pVertices.Enqueue(pY);
pVertices.Enqueue(pZ + Cube.DEPTH);
pVertices.Enqueue(pX + Cube.WIDTH);
pVertices.Enqueue(pY);
pVertices.Enqueue(pZ + Cube.DEPTH);
pVertices.Enqueue(pX);
pVertices.Enqueue(pY + Cube.HEIGHT);
pVertices.Enqueue(pZ + Cube.DEPTH);
pVertices.Enqueue(pX + Cube.WIDTH);
pVertices.Enqueue(pY + Cube.HEIGHT);
pVertices.Enqueue(pZ + Cube.DEPTH);
// Front face indices
pIndices.Enqueue(pOffset + 0);
pIndices.Enqueue(pOffset + 2);
pIndices.Enqueue(pOffset + 3);
pIndices.Enqueue(pOffset + 0);
pIndices.Enqueue(pOffset + 3);
pIndices.Enqueue(pOffset + 1);
}
public void Render()
{
GL.BindBuffer(BufferTarget.ElementArrayBuffer, mIndexBuffer);
GL.BindVertexArray(mVertexArray);
GL.DrawElements(BeginMode.Triangles, mIndexCount, DrawElementsType.UnsignedInt, 0);
}
}
着色器程序:
string vertexShaderSource = "#version 410\n" +
"\n" +
"uniform mat4 un_Projection; \n" +
"uniform mat4 un_Transform; \n" +
"\n" +
"layout(location = 0) in vec3 ve_Position;\n" +
"\n" +
"out vec4 fr_Color;" +
"\n" +
"void main()\n" +
"{\n" +
" fr_Color = vec4(1, 0, 0, 1);\n" +
" gl_Position = un_Projection * un_Transform * vec4(ve_Position.xyz, 1);\n" +
"}\n";
string fragmentShaderSource = "#version 410\n" +
"\n" +
"in vec4 fr_Color;\n" +
"\n" +
"out vec4 fi_Color;\n" +
"\n" +
"void main()\n" +
"{\n" +
" fi_Color = fr_Color;\n" +
"}\n";
如果有人想要完整的项目文件夹: http://www.file-upload.net/download-10301899/Project.zip.html
答案 0 :(得分:0)
好的,我发现了错误。 我不应该
// Normally 36 indices offset, but for now I only generate the front face of each cube so only 6 indices
offset += 6;
应该是
// 4 vertices a face so add 4 offset a cube
offset += 4;