在不同的 VBO 中分离颜色和顶点?
Separate color and vertices in separate VBOs?
我正在从一个由顶点和颜色组成的数组创建一个 3D 立方体。我想将这些颜色和顶点分离到它们单独的数组中,并用正确的颜色渲染立方体。但我不知道如何正确创建 VBO 以防止程序崩溃。
所以这是我的立方体 class,它包含顶点,
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,
};
这就是我希望分隔数组的方式(与上面相同 class)
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,
};
这是我的网格 class 所有渲染内容都在其中进行处理。我的问题是如何将颜色数组应用到 class 中?只有当顶点 class 包含顶点位置和颜色时,我才能用正确的颜色渲染立方体,如果它们是分开的。
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: \n\t 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: \n\t 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:' \n\t 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 的当前缓冲区,然后它才能接收颜色数据。 (我可能完全错了)
我在我的项目中尝试过这种方法,因此您可能需要稍微调整一下才能使其适用于您的项目,但方法应该是相同的。
有了这个,你应该能够使用分离的数组来表示颜色、三角形和顶点
//************
// 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);
我正在从一个由顶点和颜色组成的数组创建一个 3D 立方体。我想将这些颜色和顶点分离到它们单独的数组中,并用正确的颜色渲染立方体。但我不知道如何正确创建 VBO 以防止程序崩溃。
所以这是我的立方体 class,它包含顶点,
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,
};
这就是我希望分隔数组的方式(与上面相同 class)
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,
};
这是我的网格 class 所有渲染内容都在其中进行处理。我的问题是如何将颜色数组应用到 class 中?只有当顶点 class 包含顶点位置和颜色时,我才能用正确的颜色渲染立方体,如果它们是分开的。
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: \n\t 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: \n\t 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:' \n\t 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 的当前缓冲区,然后它才能接收颜色数据。 (我可能完全错了)
我在我的项目中尝试过这种方法,因此您可能需要稍微调整一下才能使其适用于您的项目,但方法应该是相同的。 有了这个,你应该能够使用分离的数组来表示颜色、三角形和顶点
//************
// 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);