2013-12-21 51 views
0

我遵循第8版,下面是我从书中修改的代码。它不会给我我想要的,而是一个空白的窗口。我想知道我在修改过程中犯了什么错误?OpenGL编程指南第一个示例

下面是我修改的代码,希望有人能指出这个错误。

#include <iostream> 
#include <OpenGL/glu.h> 
#include <OpenGL/gl3.h> 
#include <GLUT/GLUT.h> 

GLuint vaoNames[1]; 
GLuint bufferNames[1]; 
int vPosition = 0; 

GLuint createProgram(); 
GLuint createShader(GLenum type, const char* src); 
GLuint program; 

void init() 
{ 
    glGenVertexArrays(1, vaoNames); 
    glBindVertexArray(vaoNames[0]); 

    GLfloat vertices[6][2] = { 
     { -0.90, -0.90 }, // Triangle 1 
     { 0.85, -0.90 }, 
     { -0.90, 0.85 }, 
     { 0.90, -0.85 }, // Triangle 2 
     { 0.90, 0.90 }, 
     { -0.85, 0.90 } 
    }; 

    glGenBuffers(1, bufferNames); 
    glBindBuffer(GL_ARRAY_BUFFER, bufferNames[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    glUseProgram(createProgram()); 
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(vPosition); 
} 

void render() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glBindVertexArray(vaoNames[0]); 
    glDrawArrays(GL_TRIANGLES, 0, 6); 
    glFlush(); 
} 

GLuint createProgram() 
{ 
    GLuint program = glCreateProgram(); 

    const char* vertexShaderSrc = 
    "#version 400 core        \n" 
    "layout(location = 0) in vec4 vPosition;  \n" 
    "void main()         \n" 
    "{            \n" 
     "gl_Position = vPosition;     \n" 
    "}"; 
    GLuint vertexShader = createShader(GL_VERTEX_SHADER, vertexShaderSrc); 

    const char* fragmentShaderSrc = 
    "#version 400 core        \n" 
    "out vec4 fColor;        \n" 
    "void main()         \n" 
    "{            \n" 
    "fColor = vec4(0.0, 0.0, 1.0, 1.0);   \n" 
    "}"; 
    GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, fragmentShaderSrc); 

    glAttachShader(program, vertexShader); 
    glAttachShader(program, fragmentShader); 

    glLinkProgram(program); 
    return program; 
} 

GLuint createShader(GLenum type, const char* src){ 
    GLuint shaderID = glCreateShader(type); 
    glShaderSource(shaderID, 1, &src, 0); 
    glCompileShader(shaderID); 
    return shaderID; 
} 

int main(int argc, char ** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA); 
    glutInitWindowSize(512, 512); 
    glutCreateWindow("8877"); 

    init(); 
    glutDisplayFunc(render); 
    glutMainLoop(); 
} 
+0

你是否试图做一些愚蠢的事情在OSX上使用它? – genpfault

+0

除了空白屏幕之外,您是否还有其他错误?你能发布一个你得到的和你期望的(如果你可以的话)的屏幕截图吗? – rhughes

+0

为什么不检查着色器编译和链接日志? – genpfault

回答

3

当你说“有着色器编译和链接程序过程中没有错误”,你的意思是,该程序不会停止,或者你的意思,你居然跑不同的程序和检查结果glGetError()在各个点上,还是取得编译或连接日志?你的程序并没有实际的错误检查,OpenGL也不会引发异常或产生错误输出。你必须要求这些东西。

只是因为glCompileShader()不会产生错误并不意味着您的着色器实际编译。你需要检查与此类似着色器编译状态和程序与代码的链接状态:

GLint compiled; 
    glGetShaderiv(newShader, GL_COMPILE_STATUS, &compiled); 
    if (!compiled) { 
     std::string log = getLog(newShader); 
     SAY(log.c_str()); 
     throw std::runtime_error("Failed to compile shader " + log); 
    } 

其中getLog

static std::string getLog(GLuint shader) { 
    std::string log; 
    GLint infoLen = 0; 
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 

    if (infoLen > 1) { 
     char* infoLog = new char[infoLen]; 
     glGetShaderInfoLog(shader, infoLen, NULL, infoLog); 
     log = std::string(infoLog); 
     delete[] infoLog; 
    } 
    return log; 
} 

这对于检查着色器,并有相当的功能用于检查结果并获取程序链接的日志。除非你打电话给他们,否则你不能保证着色器正在编译。假设你没有在着色器语法中犯过一些简单的错误,那么你面临的最可能的问题是缺乏对OpenGL 4.x的支持,这会导致着色器立即失败。

+0

谢谢@Jherico,看来问题是Mac os x支持较低版本的Opengl导致着色器无法编译。 – Korben

+0

我应该猜到了。语句#include 是Mac OS的独特之处,我一直在为自己的OSX缺乏4.x支持而苦苦挣扎。 – Jherico

+0

我也是,根据这个链接https://developer.apple.com/graphicsimaging/opengl/capabilities/index.html,我的代码应该支持GLSL 4.1。不知何故,它似​​乎不是。我仍在为此努力 – Korben