2014-04-21 32 views
1

我想解決VBOR/OpenGL excercice中的一個錯誤,但經過幾個小時(幾天)後,我無法找到問題所在。在OpenGL中實現VBO,窗口保持黑色

問題是窗戶保持黑色,立方體沒有(正確)繪製。

-

OpenGL上下文似乎對OpenGL正確創建3.2

頂點着色器:

#version 150 core 
uniform mat4 RotationMatrix; 
uniform mat4 ProjectionMatrix; 

in vec3 in_Position; 

void main(void) 
{ 
    gl_Position = ProjectionMatrix * RotationMatrix * vec4(in_Position, 1.0); 
} 

VBO初始化:

// <-- Create OpenGL 3.2 context 
// <-- Load Shaders 
// <-- Set ClearColor, clearDepth, DepthFUnc, enable Depth 
// <-- Set Viewport, init projection and modelview matrix. 
float positionData[] = 
{ 
    -0.5f, 0.5f, -0.5f, 
    0.5f, 0.5f, -0.5f, 
    0.5f, -0.5f, -0.5f, 
    -0.5f, -0.5f, -0.5f, 
    -0.5f, 0.5f, 0.5f, 
    0.5f, 0.5f, 0.5f, 
    0.5f, -0.5f, 0.5f, 
    -0.5f, -0.5f, 0.5f, 
}; 

GLuint indexes[] = 
{ 
    0, 1, 2, 0, 2, 3, 
    4, 5, 6, 4, 6, 7, 
    0, 3, 7, 0, 7, 4, 
    1, 5, 6, 1, 6, 2, 
    0, 4, 5, 0, 5, 1, 
    2, 3, 7, 2, 7, 6 
}; 
glGenBuffers(2, vboHandles); 
glBindBuffer(GL_ARRAY_BUFFER, vboHandles[0]); 
glBufferData(GL_ARRAY_BUFFER, 24*sizeof(float), positionData, GL_STATIC_DRAW); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles[1]); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36*sizeof(GLuint), 
    indexes, GL_STATIC_DRAW); 

在OpenGL的繪製函數:

//<--Clear buffer, set Uniform variables for projection and modelview 

glBindBuffer(GL_ARRAY_BUFFER, vboHandles[0]); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles[1]); 

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL); 

//<-- Flush Opengl and swap buffers 

正確/錯誤

Correctly drawn cube, without VBO Incorrectly drawn cube, with VBO

編輯:片段着色器:

#version 150 core 
out vec4 out_Color; 
void main(void){ 
    out_Color = vec4(1.0, 0.0, 0.0, 1.0f); 
} 

EDITED 2:添加上下文創建

SDL_Window* window; 
SDL_GLContext context; 
if (SDL_Init(SDL_INIT_VIDEO) < 0) { 
    return 0; 
} 
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 

SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); 
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); 

if ((window = SDL_CreateWindow("Practica 4 and lot of stuff for the final prictice", 
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
    800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN)) == NULL) 
{ 
    SDL_Quit(); 
    return 0; 
} 
if (NULL== (context = SDL_GL_CreateContext(window))) 
{ 
    SDL_DestroyWindow(window); 
    SDL_Quit(); 
    return 0; 
} 

glewExperimental = GL_TRUE; 
GLuint glewStatus = glewInit(); 
if (glewStatus != GLEW_OK) 
{ 
    cout << "Error" << endl; 
} 
+0

您對flushing的評論OpenGL和交換緩衝區讓我感到奇怪......使用任何標準窗口API交換緩衝區。 GLX,CGL,EGL,WGL)隱式地刷新OpenGL的命令隊列。這意味着至少交換緩衝區等同於調用'glFlush(...)',並且不需要單獨完成。在某些實現中(例如Microsoft的GDI渲染器),WGL甚至調用'glFinish(...)'並在交換緩衝區之前等待所有內容完成。 –

+1

最後,用這樣的註釋替換代碼的重要部分使得很難診斷你的實際問題。我只能假設你的評論意味着你調用了'glFlush(...)'和'* SwapBuffers(...)'。 –

回答

1

日夜不停的罰款她e:

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

#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 
using namespace glm; 

#include <iostream> 
using namespace std; 


struct Program 
{ 
    static GLuint Load(const char* vert, const char* geom, const char* frag) 
    { 
     GLuint prog = glCreateProgram(); 
     if(vert) AttachShader(prog, GL_VERTEX_SHADER, vert); 
     if(geom) AttachShader(prog, GL_GEOMETRY_SHADER, geom); 
     if(frag) AttachShader(prog, GL_FRAGMENT_SHADER, frag); 
     glLinkProgram(prog); 
     CheckStatus(prog); 
     return prog; 
    } 

private: 
    static void CheckStatus(GLuint obj) 
    { 
     GLint status = GL_FALSE; 
     if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status); 
     if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status); 
     if(status == GL_TRUE) return; 
     GLchar log[ 1 << 15 ] = { 0 }; 
     if(glIsShader(obj)) glGetShaderInfoLog(obj, sizeof(log), NULL, log); 
     if(glIsProgram(obj)) glGetProgramInfoLog(obj, sizeof(log), NULL, log); 
     std::cerr << log << std::endl; 
     exit(-1); 
    } 

    static void AttachShader(GLuint program, GLenum type, const char* src) 
    { 
     GLuint shader = glCreateShader(type); 
     glShaderSource(shader, 1, &src, NULL); 
     glCompileShader(shader); 
     CheckStatus(shader); 
     glAttachShader(program, shader); 
     glDeleteShader(shader); 
    } 
}; 

#define GLSL(version, shader) "#version " #version "\n" #shader 

const char* vert = GLSL 
(
    150 core, 
    uniform mat4 RotationMatrix; 
    uniform mat4 ProjectionMatrix; 

    in vec3 in_Position; 

    void main(void) 
    { 
     gl_Position = ProjectionMatrix * RotationMatrix * vec4(in_Position, 1.0); 
    } 
); 

const char* frag = GLSL 
(
    150 core, 
    out vec4 out_Color; 
    void main(void){ 
     out_Color = vec4(1.0, 0.0, 0.0, 1.0f); 
    } 
); 

GLuint vbo = 0; 
GLuint ibo = 0; 
void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    double w = glutGet(GLUT_WINDOW_WIDTH); 
    double h = glutGet(GLUT_WINDOW_HEIGHT); 
    double ar = w/h; 
    mat4 projection = glm::ortho<float>(-1 * ar, 1 * ar, -1.0, 1.0, -1.0, 1.0); 

    mat4 modelview = mat4(1.0); 

    // prepare to render 
    static GLuint prog = Program::Load(vert, NULL, frag); 
    glUseProgram(prog); 

    GLint proj = glGetUniformLocation(prog, "ProjectionMatrix"); 
    glUniformMatrix4fv(proj, 1, GL_FALSE, glm::value_ptr(projection)); 

    GLint model = glGetUniformLocation(prog, "RotationMatrix"); 
    glUniformMatrix4fv(model, 1, GL_FALSE, glm::value_ptr(modelview)); 

    float positionData[] = 
    { 
     -0.5f, 0.5f, -0.5f, 
     0.5f, 0.5f, -0.5f, 
     0.5f, -0.5f, -0.5f, 
     -0.5f, -0.5f, -0.5f, 
     -0.5f, 0.5f, 0.5f, 
     0.5f, 0.5f, 0.5f, 
     0.5f, -0.5f, 0.5f, 
     -0.5f, -0.5f, 0.5f, 
    }; 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData, GL_STREAM_DRAW); 

    GLuint indexes[] = 
    { 
     0, 1, 2, 0, 2, 3, 
     4, 5, 6, 4, 6, 7, 
     0, 3, 7, 0, 7, 4, 
     1, 5, 6, 1, 6, 2, 
     0, 4, 5, 0, 5, 1, 
     2, 3, 7, 2, 7, 6 
    }; 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STREAM_DRAW); 

    GLint pos = glGetAttribLocation(prog, "in_Position"); 
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(pos); 

    glDrawElements(GL_TRIANGLES, sizeof(indexes)/sizeof(GLuint), GL_UNSIGNED_INT, 0); 

    glutSwapBuffers(); 
} 

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

    glewExperimental = GL_TRUE; 
    glewInit(); 

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

    glGenBuffers(1, &vbo); 
    glGenBuffers(1, &ibo); 

    glutDisplayFunc(display); 
    glutMainLoop(); 
    return 0; 
} 
+0

我目前正在尋找差異,我會接受和添加評論,當我會發現確切的問題。謝謝。 –

+1

我錯了我錯過了VAO,所以VBO沒有與着色器相關聯。 –

+1

@AdrianMaire:然後你必須使用*** *** ***配置文件。 *兼容性*配置文件中不需要VAO。您的上下文配置文件是OpenGL 3.2+中應包含的重要信息。 –