将OpenGL SuperBible(6E)示例中的代码应用于GLFW窗口

时间:2013-12-30 14:51:22

标签: opengl glfw

我目前正在尝试通过OpenGL SuperBible(6E)学习OpenGL。但是,我不是使用作者编写的窗口类,而是尝试将这些示例应用到我自己的GLFW窗口环境中。

到目前为止,我已经能够自己重新创建许多示例,但我遇到了一个我无法开始工作的例子。

这是问题SuperBible示例的.cpp文件,“movingtri”:

#include <sb6.h>
#include <math.h>

class singlepoint_app : public sb6::application
{

void init()
{
    static const char title[] = "OpenGL SuperBible - Single Point";

    sb6::application::init();

    memcpy(info.title, title, sizeof(title));
}

virtual void startup()
{
    static const char * vs_source[] =
    {
        "#version 410 core                                                 \n"
        "                                                                  \n"
        "layout (location = 0) in vec4 offset;                             \n"
        "                                                                  \n"
        "void main(void)                                                   \n"
        "{                                                                 \n"
        "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
        "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
        "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
        "                                                                  \n"
        "    // Add 'offset' to our hard-coded vertex position             \n"
        "    gl_Position = vertices[gl_VertexID] + offset;                 \n"
        "}                                                                 \n"
    };

    static const char * fs_source[] =
    {
        "#version 410 core                                                 \n"
        "                                                                  \n"
        "out vec4 color;                                                   \n"
        "                                                                  \n"
        "void main(void)                                                   \n"
        "{                                                                 \n"
        "    color = vec4(0.0, 0.8, 1.0, 1.0);                             \n"
        "}                                                                 \n"
    };

    program = glCreateProgram();
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, fs_source, NULL);
    glCompileShader(fs);

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, vs_source, NULL);
    glCompileShader(vs);

    glAttachShader(program, vs);
    glAttachShader(program, fs);

    glLinkProgram(program);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
}

virtual void render(double currentTime)
{
    static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
    glClearBufferfv(GL_COLOR, 0, green);

    glUseProgram(program);

    GLfloat attrib[] = { (float)sin(currentTime) * 0.5f,
                         (float)cos(currentTime) * 0.6f,
                         0.0f, 0.0f };

    glVertexAttrib4fv(0, attrib);

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

virtual void shutdown()
{
    glDeleteVertexArrays(1, &vao);
    glDeleteProgram(program);
}

private:
GLuint          program;
GLuint          vao;
};

DECLARE_MAIN(singlepoint_app)

现在,我失败了尝试自己应用此代码(使用GLFW和GLEW):

#include "glew.h"
#include "glfw3.h"
#include "math.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

int main(void)
{
GLFWwindow* window;

if (!glfwInit())
{
    exit(EXIT_FAILURE);
}

window = glfwCreateWindow(800, 600, "OpenGL - movingtri", NULL, NULL);

if (!window)
{
    glfwTerminate();
    exit(EXIT_FAILURE);
}

glfwMakeContextCurrent(window);

glewInit();

//begin OpenGL code from example movingtri.cpp

GLuint          program;
    GLuint          vao;

static const char * vs_source[] =
    {
        "#version 410 core                                                 \n"
        "                                                                  \n"
        "layout (location = 0) in vec4 offset;                             \n"
        "                                                                  \n"
        "void main(void)                                                   \n"
        "{                                                                 \n"
        "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
        "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
        "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
        "                                                                  \n"
        "    // Add 'offset' to our hard-coded vertex position             \n"
        "    gl_Position = vertices[gl_VertexID] + offset;                 \n"
        "}                                                                 \n"
    };

    static const char * fs_source[] =
    {
        "#version 410 core                                                 \n"
        "                                                                  \n"
        "out vec4 color;                                                   \n"
        "                                                                  \n"
        "void main(void)                                                   \n"
        "{                                                                 \n"
        "    color = vec4(0.0, 0.8, 1.0, 1.0);                             \n"
        "}                                                                 \n"
    };

    program = glCreateProgram();
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, fs_source, NULL);
    glCompileShader(fs);

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, vs_source, NULL);
    glCompileShader(vs);

    glAttachShader(program, vs);
    glAttachShader(program, fs);

    glLinkProgram(program);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

// end of movingtri initialization

while (!glfwWindowShouldClose(window))
{  
    double currentTime = glfwGetTime();
    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);

    // begin rendering code from movingtri

    static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
    glClearBufferfv(GL_COLOR, 0, green);

    glUseProgram(program);

    GLfloat attrib[] = { (float)sin(currentTime) * 0.5f,
                         (float)cos(currentTime) * 0.6f,
                         0.0f, 0.0f };

    glVertexAttrib4fv(0, attrib);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    //end rendering code


    glfwSwapBuffers(window);
    glfwPollEvents();
}

glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}

我上面使用的相同复制和粘贴技术在SuperBible中处理了许多其他更复杂的示例。

我已经测试并修改了这段代码几个小时,但我只做了一个可能相关的观察:

如果我从此行中删除“+ offset”:

"    gl_Position = vertices[gl_VertexID] + offset;                 \n"

然后出现三角形,但当然不会移动。

这是movingtri.cpp示例应该是什么样的gif:

http://i.stack.imgur.com/deF3B.gif

这是我在实现movingtri.cpp时失败的尝试的图像:

http://i.stack.imgur.com/Q1kI7.png

2 个答案:

答案 0 :(得分:1)

您需要从GLFW请求核心上下文。检查着色器编译和链接状态/日志也是一个好主意。

尝试这样的事情:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

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;
    char 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 );
}

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 );
}

GLuint LoadProgram( 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;
}

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


int main( int argc, char** argv )
{
    if( !glfwInit() )
    {
        exit(EXIT_FAILURE);
    }

    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL - movingtri", NULL, NULL);

    if( !window )
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);

    GLenum err = glewInit();
    if( GLEW_OK != err )
    {
        cerr << "glewInit() failed: " << glewGetErrorString(err) << endl;
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    const char* vert = GLSL
    (
        410 core,
        layout (location = 0) in vec4 offset;
        void main()
        {
            const vec4 vertices[] = vec4[]
            (
                vec4( 0.25, -0.25, 0.5, 1.0),
                vec4(-0.25, -0.25, 0.5, 1.0),
                vec4( 0.25,  0.25, 0.5, 1.0)
            );

            // Add 'offset' to our hard-coded vertex position
            gl_Position = vertices[ gl_VertexID ] + offset;
        }
    );

    const char* frag = GLSL
    (
        410 core,
        out vec4 color;
        void main()
        {
            color = vec4(0.0, 0.8, 1.0, 1.0);
        }
    );

    GLuint program = LoadProgram( vert, NULL, frag );

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

    while( !glfwWindowShouldClose(window) )
    {
        double currentTime = glfwGetTime();
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);

        // begin rendering code from movingtri

        static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
        glClearBufferfv(GL_COLOR, 0, green);

        glUseProgram(program);

        GLfloat attrib[] =
        {
            (float)sin(currentTime) * 0.5f,
            (float)cos(currentTime) * 0.6f,
            0.0f, 
            0.0f
        };

        glVertexAttrib4fv(0, attrib);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        //end rendering code

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

答案 1 :(得分:0)

这里也有同样的问题,但我确实有效。

顶点着色器:

layout (location = 1) in vec4 offset;

程序:

glVertexAttrib4fv(1, attrib);

所以我所做的就是将位置更改为1而不是0.其他大于0的数字也没问题。 我不知道为什么location = 0似乎被禁止用于除顶点位置之外的任何数据。

有人有想法吗?