OpenGL红宝书第8版 - 第一个例子在Ubuntu上出现黑色方块

3

在多个网站提供的很多修改建议之后,我成功编译了第一份示例程序(来自第8版OpenGL编程指南),现在我已经拥有一个黑盒子了——与之前相比是一个巨大的进步,但尴尬的是我几乎都是依靠调试器观察程序运行,除非程序有基本错误,否则我不知道该从哪里入手。其他OpenGL示例程序可以正常运行,但我正在尝试运行新书中的第一个示例。

我的电脑配置:

john@zerofluid:~/Downloads$ glxinfo | grep OpenGL
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GT 610/PCIe/SSE2
OpenGL version string: 4.3.0 NVIDIA 313.30
OpenGL shading language version string: 4.30 NVIDIA via Cg compiler
OpenGL extensions:

Linux zerofluid 3.8.0-26-generic #38-Ubuntu SMP Mon Jun 17 21:43:33 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux (最新的13.04 Ubuntu)

我有一个问题——要发布的代码太多了,但这是书中的第一个例子——尽管它很小,但我不知道问题出在哪里。如果有人真的想帮忙,那就太好了——我会把反馈给书的作者。是的,LoadShader在其他地方找到并可能是问题所在,但它应该是一个解决方案。当我无法编译第一个示例时,很难对这本书有信心。

它可以在这里找到:https://github.com/kestess/opengl8thfirstexample.git


你改过源代码吗? - n. m.
1个回答

7

这里需要贴的代码太多了。

其实并不是。

试试这个:

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

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, len = 10;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
        std::vector< char > log( len, 'X' );
        if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
        if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
        std::cerr << &log[0] << 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
( 
    400 core,
    layout( location = 0 ) in vec4 vPosition;
    void main()
    {
        gl_Position = vPosition;
    }
);

const char* frag = GLSL
( 
    400 core,
    out vec4 fColor;
    void main()
    {
        fColor = vec4( 0.0, 0.0, 1.0, 1.0 );
    }
);

enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };

GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];

const GLuint  NumVertices = 6;

void init(void)
{
    glGenVertexArrays(NumVAOs, VAOs);
    glBindVertexArray(VAOs[Triangles]);

    GLfloat  vertices[NumVertices][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(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLuint program = Program::Load( vert, NULL, frag );
    glUseProgram(program);

    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) );
    glEnableVertexAttribArray(vPosition);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);

    glutSwapBuffers();
}

int main(int argc, char** argv)
{
     glutInit(&argc, argv);
     glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
     glutInitWindowSize(512, 512);
     glutInitContextVersion(4, 0);
     glutInitContextProfile(GLUT_CORE_PROFILE);
     glutCreateWindow(argv[0]);

     glewExperimental = GL_TRUE;
     if( GLEW_OK != glewInit() )
         exit(EXIT_FAILURE);

     init();

     glutDisplayFunc(display);
     glutMainLoop();
}

如果你使用的是#version 400 core,那么就没有理由请求一个4.3上下文。


3
我第一次登录 Stack Overflow,所以没有足够的积分来为您投票。两个漂亮的蓝色三角形-即使有上下文 4.3 和 "430 核心",也很容易理解!非常感谢。 - John Estess

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接