我正在从一个由顶点和颜色组成的数组创建一个3D立方体。我想将这些颜色和顶点分离成单独的数组,并用正确的颜色渲染立方体。但我不知道如何正确创建VBO,这样程序就不会崩溃。
这是我的Cube类,它包含顶点,
private float[] vertices = {
//Position //Colours
// VO
-0.5f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, //Bottom right
// V1
-0.5f, -0.5f, 0.5f, 0.0f, 0.5f, 0.0f, 1.0f, //Top Left
// V2
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 1.0f, //Top Right
// V3
0.5f, 0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 1.0f, //Bottom left
// V4
-0.5f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
// V5
0.5f, 0.5f, -0.5f, 0.0f, 0.5f, 0.0f, 1.0f,
// V6
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 1.0f,
// V7
0.5f, -0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 1.0f,
};
private int[] triangles = {
// Front face
0, 1, 3, 3, 1, 2,
// Top Face
4, 0, 3, 5, 4, 3,
// Right face
3, 2, 7, 5, 3, 7,
// Left face
6, 1, 0, 6, 0, 4,
// Bottom face
2, 1, 6, 2, 6, 7,
// Back face
7, 6, 4, 7, 4, 5,
};
这就是我希望我的数组被分离的方式(与上面的类相同(
private float[] vertices = {
//Position
// VO
-0.5f, 0.5f, 0.5f,
// V1
-0.5f, -0.5f, 0.5f,
// V2
0.5f, -0.5f, 0.5f,
// V3
0.5f, 0.5f, 0.5f,
// V4
-0.5f, 0.5f, -0.5f,
// V5
0.5f, 0.5f, -0.5f,
// V6
-0.5f, -0.5f, -0.5f,
// V7
0.5f, -0.5f, -0.5f,
};
private float[] colours = {
//Colours
// VO
0.5f, 0.0f, 0.0f, 1.0f,
// V1
0.0f, 0.5f, 0.0f, 1.0f,
// V2
0.0f, 0.0f, 0.5f, 1.0f,
// V3
0.0f, 0.5f, 0.5f, 1.0f,
// V4
0.5f, 0.0f, 0.0f, 1.0f,
// V5
0.0f, 0.5f, 0.0f, 1.0f,
// V6
0.0f, 0.0f, 0.5f, 1.0f,
// V7
0.0f, 0.5f, 0.5f, 1.0f,
};
private int[] triangles = {
// Front face
0, 1, 3, 3, 1, 2,
// Top Face
4, 0, 3, 5, 4, 3,
// Right face
3, 2, 7, 5, 3, 7,
// Left face
6, 1, 0, 6, 0, 4,
// Bottom face
2, 1, 6, 2, 6, 7,
// Back face
7, 6, 4, 7, 4, 5,
};
这是我的Mesh类,所有的渲染都在这里处理。我的问题是如何将颜色数组应用到这个类中?只有当顶点类包含顶点的位置和颜色时,我才能用正确的颜色渲染立方体,而不是当它们是分开的时。
public void Init(){
/*
float aspectRation = (float) width / height;
projectionMatrix = new Matrix4f().perspective(FOV, aspectRation, nearPlane, farPlane);
*/
//COMPILE AND LINK SHADERS
//************
// Vertex Shader
//************
vertexID = glCreateShader(GL_VERTEX_SHADER); //Load shader type
glShaderSource(vertexID, vertexShaderSrc); // Pass shader source to GPU
glCompileShader(vertexID); // Compile shader
//Error check in compilation process
int success = glGetShaderi(vertexID,GL_COMPILE_STATUS);
if(success == GL_FALSE){
int lenght = glGetShaderi(vertexID, GL_INFO_LOG_LENGTH);
System.out.println("ERROR: 'defaultShader.glsl: nt Vertex shader compilation failed !");
System.out.println(glGetShaderInfoLog(vertexID,lenght));
}
//************
// Fragment Shader
//************
fragmentID = glCreateShader(GL_FRAGMENT_SHADER); //Load shader type
glShaderSource(fragmentID, fragmentShaderSrc); // Pass shader source to GPU
glCompileShader(fragmentID); // Compile shader
//Error check in compilation process
success = glGetShaderi(fragmentID,GL_COMPILE_STATUS);
if(success == GL_FALSE){
int lenght = glGetShaderi(fragmentID, GL_INFO_LOG_LENGTH);
System.out.println("ERROR: 'defaultShader.glsl: nt Vertex shader compilation failed !");
System.out.println(glGetShaderInfoLog(fragmentID,lenght));
}
//************
// Link shaders and Check for errors
//************
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexID);
glAttachShader(shaderProgram, fragmentID);
glLinkProgram(shaderProgram);
//Check for linking errors
success = glGetProgrami(shaderProgram, GL_LINK_STATUS);
if(success == GL_FALSE){
int lenght = glGetProgrami(shaderProgram, GL_INFO_LOG_LENGTH);
System.out.println("ERROR: 'defaultShader.glsl:' nt Linking of shaders failed !");
System.out.println(glGetProgramInfoLog(fragmentID,lenght));
assert false : "";
}
int uniformLocation = glGetUniformLocation(shaderProgram,"projectionMatrix");
uniforms.put("projectionMatrix",uniformLocation);
int uniformPosLocation = glGetUniformLocation(shaderProgram,"worldMatrix");
uniformsPosition.put("worldMatrix",uniformPosLocation);
//************
// Generate VAO, VBO and EBO and send them to GPU
//************
// GENERATE VAO
VAO_ID = glGenVertexArrays();
glBindVertexArray(VAO_ID);
//Create float buffer of vertices
FloatBuffer vertexBuffer = MemoryUtil.memAllocFloat(vertices.length);
vertexBuffer.put(vertices).flip();
// GENERATE VBO and upload VertexBuffer
VBO_ID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
memFree(vertexBuffer);
//Create Indices and upload them
IntBuffer elementBuffer = MemoryUtil.memAllocInt(triangles.length);
elementBuffer.put(triangles).flip();
//Create EBO
EBO_ID = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_ID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);
//Create vertex attribute pointers
int positionSize = 3;
int colorSize = 4;
int floatSizeInBytes = 4;
int vertexSizeInBytes = (positionSize + colorSize) * floatSizeInBytes;
glVertexAttribPointer(0, positionSize, GL_FLOAT, false, vertexSizeInBytes, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, colorSize, GL_FLOAT, false, vertexSizeInBytes, positionSize * floatSizeInBytes);
glEnableVertexAttribArray(1);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
public void Render(){
//Bind shader program
glUseProgram(shaderProgram);
SetUniform("projectionMatrix", projectionMatrix);
SetUniform2("worldMatrix", worldMatrix);
//Bind VAO currently in use
glBindVertexArray(VAO_ID);
//Enable vertex atribute pointers
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//Draw triangles
glDrawElements(GL_TRIANGLES,triangles.length, GL_UNSIGNED_INT,0);
//Unbind everything
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(0);
glUseProgram(0);
}
根据我对OpenGL的了解,在GPU接收颜色数据之前,您似乎正在关闭发送到GPU的当前缓冲区。(我可能完全错了(
我在我的项目中尝试了这个方法,所以你可能需要稍微坐立不安才能让它为你的项目工作,但这个方法应该是一样的。有了这个,你应该能够使用颜色,三角形和顶点的分离数组
//************
// Generate VAO, VBO and EBO and send them to GPU
//************
// GENERATE VAO
VAO_ID = glGenVertexArrays();
glBindVertexArray(VAO_ID);
//POSITION VBO
// GENERATE VBO and upload VertexBuffer
VBO_ID = glGenBuffers();
//Create float buffer of vertices
FloatBuffer vertexBuffer = MemoryUtil.memAllocFloat(vertices.length);
vertexBuffer.put(vertices).flip();
glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
//COLOR VBO
//GENERATE VBO and upload colourBuffer
colourVBO_ID = glGenBuffers();
FloatBuffer colourBuffer = MemoryUtil.memAllocFloat(colours.length);
colourBuffer.put(colours).flip();
glBindBuffer(GL_ARRAY_BUFFER, colourVBO_ID);
glBufferData(GL_ARRAY_BUFFER, colourBuffer, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0);
//TRIANGLE VBO
//Create Indices and upload them
EBO_ID = glGenBuffers();
IntBuffer elementBuffer = MemoryUtil.memAllocInt(triangles.length);
elementBuffer.put(triangles).flip();
//Create EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_ID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
memFree(vertexBuffer);
memFree(colourBuffer);
memFree(elementBuffer);