OpenGL 对象不能正确渲染?
Posted
技术标签:
【中文标题】OpenGL 对象不能正确渲染?【英文标题】:OpenGL object not rendering correctly? 【发布时间】:2019-04-06 22:12:55 【问题描述】:代码正常运行,没有任何错误,但对象显示为白色。我使用的 IDE 是 Eclipse。
我尝试了一些调试,在UCreateBuffers()
中发现错误#1282。
// header inclusions
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
//GLM math header inclusions
#include <GL/glm.hpp>
#include <GL/gtc/matrix_transform.hpp>
#include <GL/gtc/type_ptr.hpp>
using namespace std;
#define WINDOW_TITLE "Modern OpenGL" // window title macro
// shader program macro
#ifndef GLSL
#define GLSL(Version, Source) "#Version " #Version "\n" #Source
#endif
//variable declarations for shader, window size initialization, buffer and array objects
GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO;
GLfloat cameraSpeed = 0.0005f;
GLchar currentKey; // will store key pressed
//global vector declarations
glm::vec3 cameraPosition = glm::vec3(0.0f, 0.0f, 5.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f, 0.0f, -1.0f);
// function prototypes
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UKeyboard(unsigned char key, int x, int y);
void UKeyReleased(unsigned char key, int x, int y);
//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; // variable to transfer color data to the fragment shader
// 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); //transforms vertices to clip coordinates
mobileColor = color; // references incoming color data
);
// fragment shader source code
const GLchar * fragmentShaderSource = GLSL(330,
in vec3 mobileColor; // variable to hold incoming color data from vertex shader
out vec4 gpuColor; // variable to pass color data to the gpu
void main()
gpuColor = vec4(mobileColor, 1.0); // sends color data to the gpu for rendering
);
//main program
int main(int argc, char* argv[])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
UCreateShader();
UCreateBuffers();
//use the shader program
glUseProgram(shaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //set background color
glutDisplayFunc(URenderGraphics);
glutKeyboardFunc(UKeyboard); // detects key press
glutKeyboardUpFunc(UKeyReleased); // detects key release
glutMainLoop();
//destroys buffer objects once used
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
return 0;
//resizes the window
void UResizeWindow(int w, int h)
WindowWidth = w;
WindowHeight = h;
glViewport(0, 0, WindowWidth, WindowHeight);
// renders graphics
void URenderGraphics(void)
glEnable(GL_DEPTH_TEST); // enable z-depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO); // Activate the vertex array object before rendering and transforming them
// Camera Movement Logic
if(currentKey =='w')
cameraPosition += cameraSpeed * CameraForwardZ;
if(currentKey =='s')
cameraPosition -= cameraSpeed * CameraForwardZ;
if(currentKey =='a')
cameraPosition -= glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;
if(currentKey =='d')
cameraPosition += glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;
// 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::lookAt(cameraPosition, cameraPosition + CameraForwardZ, CameraUpY);
//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
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glutSwapBuffers(); // flips the back buffer 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
//fragment 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);
void UCreateBuffers()
GLfloat vertices[] =
//positions //Color
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
;
//generate buffer Ids
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
//activate the vertex array object before binding and setting any VBOs and Vertex Attribute Pointers
glBindVertexArray(VAO);
//Activate the VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//set attribute 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); // enables vertex attribute
glBindVertexArray(0);// enable the Vao which is good pratice
// implements the UKeyboar function
void UKeyboard(unsigned char key, GLint x, GLint y)
switch(key)
case 'w':
cout << "You pressed w!" <<endl;
break;
case 's':
cout << "You pressed s!" <<endl;
break;
case 'a':
cout << "You pressed a!" <<endl;
break;
case 'd':
cout << "You pressed d!" <<endl;
break;
default:
cout << "Press a key!" << endl;
//implements the UkeyRelease function
void UKeyReleased(unsigned char key, GLint x, GLint y)
cout << "Key released!" <<endl;
【问题讨论】:
您的“缓冲函数:...”只是显示与着色器相同的文本。然而,看看你如何设置你的 VAO 是相当重要的,因为我怀疑问题可能在那里(考虑到你的颜色似乎来自哪里)。另外,我没有看到你在任何地方打电话给glUseProgram()
。
@Michael 我在上面做了一些编辑。添加了 Main 和更改缓冲区功能。我是 glUseProgram(shaderProgram)
好的。您提到在某处出现错误 1282。这究竟发生在哪里?除此之外,一般来说查看enabling debug output 可能不会有什么坏处。
尝试在几个位置渲染对象时发生这种情况
【参考方案1】:
着色器无法编译。 GLSL 区分大小写。版本限定符必须是 #version
而不是 #Version
:
#define GLSL(Version, Source) "#Version " #Version "\n" #Source
#define GLSL(Version, Source) "#version " #Version "\n" #Source
我建议检查编译和链接错误并添加错误日志记录。
编译错误可以通过glGetShaderiv
/glGetShaderInfoLog
得到:
例如
#include <vector>
void UCompileShader( GLuint shader )
glCompileShader( shader );
GLint status;
glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
GLint logLen;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( shader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
链接错误可以通过glGetProgramiv
/glGetProgramInfoLog
得到:
例如
void ULinkShader( GLuint program )
glLinkProgram( program );
GLint status;
glGetProgramiv( program, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
GLint logLen;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( program, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
//creates the shader program
void UCreateShader()
//vertex shader
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
UCompileShader(vertexShader); // compiles the vertex shader
//fragment shader
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
UCompileShader(fragmentShader);
//shader program
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
ULinkShader(shaderProgram);
// delete the vertex and fragment shaders once linked
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
【讨论】:
兔子谢谢你。一切正常。 IDE 不抛出错误或警告的原因是什么。对于大写单词? @solidsandwich 驱动程序生成错误。但是您必须通过glGetProgramiv
得到错误。一个选项是启用Debug Output。以上是关于OpenGL 对象不能正确渲染?的主要内容,如果未能解决你的问题,请参考以下文章