2015-09-11 97 views
3

我使用的FreeGlut。我已經成功地在一個VBO中使用着色器程序渲染了一個三角形。OpenGL 3.3 - 無效的操作錯誤(1282)後glDrawArrays

着色器程序編譯,鏈接和驗證不會引發錯誤。我相信問題在於我存儲和呼叫VBO(其中2個)的方式,因爲之前我只與1個VBO合作。

編輯:刪除所有不必要的代碼

#include <GL/glew.h> 
#include <GL/freeglut.h> 
#include <string.h> 
#include <stdio.h> 

#define countof(x) sizeof(x)/sizeof(x[0]) 

#define NUM_BUFFERS 2 
#define INFOLOG_SIZE 1024 

GLuint VBO_ids[NUM_BUFFERS]; 
GLfloat VBO0[] = {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f}; 
GLfloat VBO1[] = {-1.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,-1.0f, 0.0f}; 
GLfloat *VBOs[NUM_BUFFERS] = { VBO0, VBO1 }; 
GLuint shader_prog_id; 

const GLchar *vert_src = 
"#version 330\n" 
"layout (location = 0) in vec3 Pos;\n" 
"void main() {\n" 
" gl_Position = vec4(Pos.x, Pos.y, Pos.z, 1.0); }\n"; 

const GLchar *frag_src = 
"#version 330\n" 
"out vec4 FragColor;\n" 
"void main() {\n" 
" FragColor = vec4(1.0, 1.0, 1.0, 1.0); }\n"; 

void vbo_init(void) { 
    glGenBuffers(NUM_BUFFERS, VBO_ids); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO_ids[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(VBO0), VBOs[0], GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO_ids[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(VBO1), VBOs[1], GL_STATIC_DRAW); } 

int shader_init(const GLchar **v_src, const GLchar **f_src, GLint *v_size, GLint *f_size) { 
    GLint success; 
    shader_prog_id = glCreateProgram(); 
    GLuint v_shader = glCreateShader(GL_VERTEX_SHADER); 
    GLuint f_shader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(v_shader, 1, v_src, v_size); 
    glShaderSource(f_shader, 1, f_src, f_size); 
    glCompileShader(v_shader); 
    glCompileShader(f_shader); 
    glAttachShader(shader_prog_id, v_shader); 
    glAttachShader(shader_prog_id, f_shader); 
    glLinkProgram(shader_prog_id); 
    glValidateProgram(shader_prog_id); 
    return 1; } 

int draw_initialize(void) { 
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    vbo_init(); 
    GLint vsrcsize = strlen(vert_src); 
    GLint fsrcsize = strlen(frag_src); 
    shader_init(&vert_src, &frag_src, &vsrcsize, &fsrcsize); 
    return 1; } 

void draw_callback(void) { 
    glClear(GL_COLOR_BUFFER_BIT); 
    glUseProgram(shader_prog_id); 
    glEnableVertexAttribArray(0); 

    glBindBuffer(GL_ARRAY_BUFFER, VBO_ids[0]); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
    glDrawArrays(GL_TRIANGLES, 0, countof(VBO0)/3); 
    puts((char*)gluErrorString(glGetError())); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO_ids[1]); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
    glDrawArrays(GL_TRIANGLES, 0, countof(VBO1)/3); 

    glDisableVertexAttribArray(0); 
    glutSwapBuffers(); } 

int main(int argc, char **argv) { 
    glutInit(&argc, argv); 
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); 
    glutInitContextProfile(GLUT_CORE_PROFILE); 
    glutInitContextVersion(3, 3); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
    glutInitWindowSize(600, 600); 
    glutCreateWindow("title"); 

    glewInit(); 
    draw_initialize(); 

    glutIdleFunc(draw_callback); 
    glutMainLoop(); 
    return 0; } 
+0

如果有人想嘗試之前重現錯誤鏈接器標誌是'-lglut -lGLEW' –

回答

1

你需要在覈心方面提供一個Vertex Array Object (VAO)

int draw_initialize(void) 
{ 
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    vbo_init(); 
    GLint vsrcsize = strlen(vert_src); 
    GLint fsrcsize = strlen(frag_src); 
    shader_init(&vert_src, &frag_src, &vsrcsize, &fsrcsize); 

    GLuint vao = 0; 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    return 1; 
} 

它們封裝頂點ATTRIB啓用(glEnableVertexAttribArray())和指針(glVertexAttribPointer())狀態。

另外:

  • glewExperimental = GL_TRUEglewInit()
  • 設置的實際glutDisplayFunc(),而不是希望GLUT會弄清楚你的意思只登記空閒回調
+0

非常感謝!核心環境是好還是壞?我讀過一些地方,1)它很好2)VAO不是那種便攜式的,我不得不叮''glewExperimental'來與他們合作。 –

+0

@ Xis88它們便攜;它們包含在3.0+ OpenGL規範中。我不確定爲什麼'glewExperimental'需要設置爲訪問相關功能。 –

+0

我注意到這裏有一些額外的錯誤:'glBufferData(GL_ARRAY_BUFFER,sizeof(VBO0),VBOs [0],GL_STATIC_DRAW);'這是壞了,我相信你需要'&VBOs [0]'上面所以你得到一個實際的指針緩衝區。 –