我跟着this OpenGL example一起進行了一些操作,並且我的代碼編譯完成了,但它無法正常工作。使用頂點緩衝區對象在OpenGL中進行基本線條渲染
我期望看到一個白色的矩形,但是沒有任何東西被渲染,而是清晰的顏色。在我致電glDrawArrays
後,glGetError
告訴我發生了錯誤1282。我相信這個問題非常明顯,但我不明白我要出錯的地方。這裏是我的問題的簡單的例子:
#include <errno.h>
#include <stdio.h>
#include <GLFW/glfw3.h>
#include <GL/gl.h>
#define WINDOW_W 300
#define WINDOW_H 300
static const GLchar *vertex_shader_src = {
"#version 440\n"
"in vec4 position;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
"\tgl_Position = projection * position;\n"
"}\n"
};
static const GLchar *fragment_shader_src = {
"#version 440\n"
"uniform vec4 color;\n"
"out vec4 outputColor;\n"
"void main()\n"
"{\n"
"outputColor = color;\n"
"}\n"
};
static GLuint program = 0;
static GLuint vao = 0;
static const GLfloat rect_vertices[] = {
5.0f, 5.0f,
WINDOW_W - 5.0f, 5.0f,
WINDOW_W - 5.0f, 5.0f,
WINDOW_W - 5.0f, WINDOW_H - 5.0f,
WINDOW_W - 5.0f, WINDOW_H - 5.0f,
5.0f, WINDOW_H - 5.0f,
5.0f, WINDOW_H - 5.0f,
5.0f, 5.0f
};
static GLuint rect_vbo = 0;
int init_program()
{
GLint status;
GLuint vertexShader;
GLuint fragmentShader;
// Initialize our vertex shader.
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertex_shader_src, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE)
return -EINVAL;
// Initialize our fragment shader.
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragment_shader_src, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE)
return -EINVAL;
// Initialize the program.
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(status == GL_FALSE)
return -EINVAL;
// Detach the shaders, now that the program is linked.
glDetachShader(program, vertexShader);
glDetachShader(program, fragmentShader);
// Done!
return 0;
}
void ortho_matrix(GLfloat *m, GLfloat l, GLfloat r,
GLfloat b, GLfloat t, GLfloat n, GLfloat f)
{
m[0] = 2.0f/(r - l);
m[1] = 0.0f;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = 0.0f;
m[5] = 2.0f/(t - b);
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = -2.0f/(f - n);
m[11] = 0.0f;
m[12] = 0.0f;
m[13] = 0.0f;
m[14] = 0.0f;
m[15] = 1.0f;
}
int gl_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
GLint colorVec;
GLfloat color[4] = {r, g, b, a};
colorVec = glGetUniformLocation(program, "color");
if(colorVec == -1)
return -EINVAL;
glUniform4fv(colorVec, 1, color);
return 0;
}
int set_uniforms(int width, int height)
{
int r;
GLint orthoMatrix;
GLfloat matrix[16];
// Set our orthographic projection uniform.
orthoMatrix = glGetUniformLocation(program, "projection");
if(orthoMatrix == -1)
return -EINVAL;
ortho_matrix(matrix, -0.5f, ((GLfloat) (width - 1)) + 0.5f,
((GLfloat) (height - 1)) + 0.5f, -0.5f, 0.0f, 1.0f);
glUniformMatrix4fv(orthoMatrix, 1, GL_FALSE, matrix);
// Set our rendering color uniform.
r = gl_color(1.0f, 1.0f, 1.0f, 1.0f);
if(r < 0)
return r;
// Done!
return 0;
}
int init_vbo()
{
glGenBuffers(1, &rect_vbo);
glBindBuffer(GL_ARRAY_BUFFER, rect_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(rect_vertices),
rect_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return 0;
}
int render()
{
GLenum err;
glBindBuffer(GL_ARRAY_BUFFER, rect_vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_LINES, 0, sizeof(rect_vertices)/sizeof(GLfloat));
err = glGetError();
while(err != GL_NO_ERROR)
{
printf("glDrawArrays err: %d\n", err);
err = glGetError();
}
glDisableVertexAttribArray(0);
return 0;
}
int main(void)
{
int r;
GLFWwindow *window;
int width;
int height;
if(!glfwInit())
return -EINVAL;
window = glfwCreateWindow(WINDOW_W, WINDOW_H,
"My Window", NULL, NULL);
if(!window)
{
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
r = init_program();
if(r < 0)
{
glfwTerminate();
return 1;
}
r = init_vbo();
if(r < 0)
{
glfwTerminate();
return 1;
}
while(!glfwWindowShouldClose(window))
{
// Initialize the GL viewport.
glfwGetFramebufferSize(window, &width, &height);
r = set_uniforms(width, height);
if(r < 0)
{
glfwTerminate();
return r;
}
glViewport(0, 0, width, height);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
// Call the user-provided rendering function.
r = render();
if(r < 0)
{
glfwTerminate();
return r;
}
// End GL rendering, swap the buffer, and poll for events.
glUseProgram(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
我試圖尋找這個錯誤號碼,我發現如this,但我真的不知道有什麼方法可以找出特別是出錯了。
我在做什麼錯,或者,我怎麼能找到?
我很高興你想通了!當我遇到一個沒有意義的錯誤時,我經常做的事情就是以二進制搜索模式將調用添加到'glGetError()中,直到碰到實際導致錯誤的代碼行。正因爲如此,我從來不喜歡「粘性錯誤」範例。 – user1118321 2014-08-29 04:36:40
@ user1118321這是非常好的,有一個宏準備好,吐出錯誤被檢測到的行,並搶先灑在他們周圍的一些(例如在每個函數的末尾) – 2014-08-29 10:07:34
「下面」我相信你的意思是「後」。是的,根據我所經歷的(不知道這是你應該期望的),每個程序都會跟蹤它自己的制服狀態。因此,如果您使用相同着色器渲染更多幾何體,但不更新所有制服,則未更新的制服應具有與上次使用該着色器時留下的值相同的值。相當明智。 – 2014-08-29 16:45:57