Opengl 3d立方体不渲染
Posted
技术标签:
【中文标题】Opengl 3d立方体不渲染【英文标题】:Opengl 3d cube not rendering 【发布时间】:2019-04-07 12:00:24 【问题描述】:似乎无法渲染我的对象,只出现黑屏。
// Shader program Macro
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif
// variable declaritions for shader, windows size initialization, buffer and array objects
GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO, EBO, texture;
函数
// Function prototypes
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
顶点和片段着色器
// vertex shader source code
const GLchar * vertexShaderSource = GLSL(330,
layout (location = 0) in vec3 position; //vertex data from vertex attrib pointer 0
layout (location = 1) in vec3 color; // color data from vertex attrib pointer 1
out vec3 mobileColor;
// global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
gl_Position = projection * view * model * vec4(position, 1.0f); // transform vertices to clip coordinates
mobileColor = color; // references incoming color data
);
const GLchar * fragmentShaderSource = GLSL(330,
in vec3 mobileColor;
out vec4 gpuColor;
void main()
gpuColor = vec4(mobileColor, 1.0);
);
int main (int argc, char* argv[])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
UCreateShader();
UCreateBuffers();
// use the shader program
glUseProgram(shaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glutDisplayFunc(URenderGraphics);
glutMainLoop();
//destroys buffer onjects once used
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
return 0;
// renders graphics
void URenderGraphics(void)
glEnable(GL_DEPTH_TEST); // enables z-depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clears the screen
glBindVertexArray(VAO); // activate the vertex array object before rendering and transforming them
// transforms the object
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // place the object at the center of the viewport
model = glm::rotate(model, 45.0f, glm::vec3(0.0, 1.0f, 0.0f)); // rotate the object 45 degrees on the x
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); // increase the object size by a scale of 2
//transform the camera
glm::mat4 view;
view = glm::translate(view, glm::vec3(0.5f, 0.0f, -5.0f)); // moves teh world 0.5 units on x and -5 units in z;
//creates a perspective projection
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
//retrieves and passes transform matrices to the shader program
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
// draws the triangles
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glBindVertexArray(0); // deactive the vertex array object
glutSwapBuffers(); // flips the back with the front buffer every frame
着色器程序
// creates the shader program
void UCreateShader()
//vertex shader
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // creates the vertex shader
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // attaches the vertex shader to the source code
glCompileShader(vertexShader); // compiles the vertex shader
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
//shader program
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// delete the vertex and fragment shaders once linked
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
缓冲区
// creates the buffer and array objects
void UCreateBuffers()
// position and color data
GLfloat vertices[] =
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, -1.0f, 0.5f, 0.5f, 1.0f,
0.5f, 0.5f, -1.0f, 1.0f, 1.0f, 0.5f,
-0.5f, 0.5f, -1.0f, 0.2f, 0.2f, 0.5f,
-0.5f, -0.5f, -1.0f, 1.0f, 0.0f, 1.0f
;
GLuint indices[] =
0,1,3,
1,2,3,
0,1,4,
0,4,5,
0,5,6,
0,3,6,
4,5,6,
4,6,7,
2,3,6,
2,6,7,
1,4,7,
1,2,7
;
//index data to share position data
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// activate the vertex array object before binding and settings anvbos and vertex attribute pointers
glBindVertexArray(VAO);
//activate the VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//activate the element buffer object / indices
glBindBuffer(GL_ARRAY_BUFFER, EBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// set attrivute pointer 0 to hold position data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); //enables vertex attribute
// set attribute pointer 1 to hold color data
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
【问题讨论】:
【参考方案1】:在绑定Vertex Array Object (glBindVertexArray(VAO)
) 之后,顶点索引必须绑定到目标GL_ELEMENT_ARRAY_BUFFER
而不是GL_ARRAY_BUFFER
:
glBindVertexArray(VAO)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
注意,索引缓冲区的名称值(EBO
)在绑定时(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
)在Vertex Array Object
中说明。请参阅Index buffers。glDrawElements
绘制缓冲区的“索引”,该缓冲区由当前绑定的 VAO 引用。由于 VAO 中没有说明索引缓冲区,因此没有绘制任何内容。
进一步说明,OpenGL Mathematics (GLM) 库需要以弧度而不是度数为单位的角度。
使用glm::radians
将度数转换为辐射度。
身份矩阵必须由单个 1.0 参数 (glm::mat4 model(1.0f)
) 初始化:
例如
// transforms the object
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
model = glm::rotate(model, glm::radians(45.0f), glm::vec3(0.0, 1.0f, 0.0f));
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f));
//transform the camera
glm::mat4 view(1.0f);
view = glm::translate(view, glm::vec3(0.5f, 0.0f, -5.0f));
//creates a perspective projection
glm::mat4 projection(1.0f);
projection = glm::perspective(glm::radians(45.0f),
(GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
【讨论】:
以上是关于Opengl 3d立方体不渲染的主要内容,如果未能解决你的问题,请参考以下文章