16

我正在尝试按照“交互式计算机图形使用基于着色器的 OPENGL® 的自上而下的方法”第 6 版中的说明进行 Sierpinski 垫圈。

我有这个代码

谢尔宾斯基.cpp

#include <GL/glew.h>
#include <GL/glut.h>
#include <glm/glm.hpp>
#include "Angel.h"
#include <iostream>
#include <vector>
#include <cmath>
#define NUM_PUNTOS 4
#define DIVISIONES 5


namespace Global
{
    GLint Ndivisions = DIVISIONES;
    GLint Nvertices = (GLint) std::pow(3,Ndivisions + 1);
    std::vector<glm::vec2> points;

};

void display(void);
void init();
//void idle(void);
void triangle(glm::vec2,glm::vec2,glm::vec2,std::vector<glm::vec2> &);
void divide_triangle(glm::vec2,glm::vec2,glm::vec2,GLint,std::vector<glm::vec2> &);
inline glm::vec2 dividir(glm::vec2,double);
glm::vec2 dividir(glm::vec2,double);   

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGBA);
    glutInitWindowSize(800,600);
    glutInitContextVersion(3,2);
    glutInitContextProfile(GLUT_CORE_PROFILE);
    //IMPORTANTE: CREAR ANTES QUE LOS CALLBACKS
    glutCreateWindow("Sierpinski gasket");    //Init
    glewInit();//IMPORTANTÍSIMO
    init();    
    glutDisplayFunc(display);
    #ifdef LIBGL_DEBUG
    std::cout<<LIBGL_DEBUG<<'\n';
    #endif

    //Despues de todo es que se crea la ventana
    glutMainLoop();    

}
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_POINTS, 0, Global::Nvertices);
    glFlush();
}
void init()
{
    //Inicializamos array global
    divide_triangle(glm::vec2(0.0,0.0),glm::vec2(1.0,0.0),glm::vec2(0.5,1.0),Global::Ndivisions,Global::points);
    glm::vec2 *points = &Global::points[0];
    GLuint vao,program;
    program = Angel::InitShader("shaders/Sierpinski.vertex.glsl",
            "shaders/Sierpinski.fragment.glsl");
    glUseProgram(program);

    for(int x = 0; x<Global::points.size();x++)
        std::cout<<"X: "<<points[x].x<<" Y: "<<points[x].y<<"\n";

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    //Buffers
    GLuint buffer;
    glGenBuffers(1, &buffer);
    std::cout<<"Primer test\n";
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER,sizeof(points),
            points,GL_STATIC_DRAW);
    //glGenVertexArrays(1, &buffer);
    //glBindVertexArray(buffer);
    std::cout<<buffer<<'\n';
    // Initialize the vertex position attribute from the vertex shader
    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
            BUFFER_OFFSET(0) );

}
void triangle(glm::vec2 a,glm::vec2 b,glm::vec2 c,std::vector<glm::vec2> &points)
{
    size_t old_size = points.size();
    points.resize(old_size + 3);
    points[old_size] = a;
    points[old_size + 1] = b;
    points[old_size + 2] = c;
    //std::cout<<"Finalizado\n";
}

void divide_triangle(glm::vec2 a,glm::vec2 b,glm::vec2 c,GLint k,std::vector<glm::vec2> &points)
{
    if(k>0)
    {
        glm::vec2 ab = dividir(a + b,2.0);
        glm::vec2 ac = dividir(a + c,2.0);
        glm::vec2 bc = dividir(b + c,2.0);

        //Dividimos triángulo
        int new_k = k - 1;
        divide_triangle(a,ab,ac,new_k,points);
        divide_triangle(c,ac,bc,new_k,points);
        divide_triangle(b,bc,ab,new_k,points);
    }
    else
    {
        triangle(a,b,c,points);
    }
}

glm::vec2 dividir(glm::vec2 vectorcito,double escalar)
{
    return glm::vec2(vectorcito.x/escalar,vectorcito.y/escalar);
}
//void idle(void){}

天使.h

//////////////////////////////////////////////////////////////////////////////
//
//  --- Angel.h ---
//
//   The main header file for all examples from Angel 6th Edition
//
//////////////////////////////////////////////////////////////////////////////

#ifndef __ANGEL_H__
#define __ANGEL_H__

//----------------------------------------------------------------------------
// 
// --- Include system headers ---
//

#include <cmath>
#include <iostream>

//  Define M_PI in the case it's not defined in the math header file
#ifndef M_PI
#  define M_PI  3.14159265358979323846
#endif

//----------------------------------------------------------------------------
//
// --- Include OpenGL header files and helpers ---
//
//   The location of these files vary by operating system.  We've included
//     copies of open-soruce project headers in the "GL" directory local
//     this this "include" directory.
//

#ifdef __APPLE__  // include Mac OS X verions of headers
#  include <OpenGL/OpenGL.h>
#  include <GLUT/glut.h>
#else // non-Mac OS X operating systems
#  include <GL/glew.h>
#  include <GL/freeglut.h>
#  include <GL/freeglut_ext.h>
#endif  // __APPLE__

// Define a helpful macro for handling offsets into buffer objects
#define BUFFER_OFFSET( offset )   ((GLvoid*) (offset))

//----------------------------------------------------------------------------
//
//  --- Include our class libraries and constants ---
//

namespace Angel {

//  Helper function to load vertex and fragment shader files
GLuint InitShader( const char* vertexShaderFile,
           const char* fragmentShaderFile );

//  Defined constant for when numbers are too small to be used in the
//    denominator of a division operation.  This is only used if the
//    DEBUG macro is defined.
const GLfloat  DivideByZeroTolerance = GLfloat(1.0e-07);

//  Degrees-to-radians constant 
const GLfloat  DegreesToRadians = M_PI / 180.0;

}  // namespace Angel

/*#include "vec.h"
#include "mat.h"
#include "CheckError.h"*/

#define Print(x)  do { std::cerr << #x " = " << (x) << std::endl; } while(0)

//  Globally use our namespace in our example programs.
//using namespace Angel;

namespace Angel {

// Create a NULL-terminated string by reading the provided file
static char*
readShaderSource(const char* shaderFile)
{
    FILE* fp = fopen(shaderFile, "r");

    if ( fp == NULL ) { return NULL; }

    fseek(fp, 0L, SEEK_END);
    long size = ftell(fp);

    fseek(fp, 0L, SEEK_SET);
    char* buf = new char[size + 1];
    fread(buf, 1, size, fp);

    buf[size] = '\0';
    fclose(fp);

    return buf;
}


// Create a GLSL program object from vertex and fragment shader files
GLuint
InitShader(const char* vShaderFile, const char* fShaderFile)
{
    struct Shader {
    const char*  filename;
    GLenum       type;
    GLchar*      source;
    }  shaders[2] = {
    { vShaderFile, GL_VERTEX_SHADER, NULL },
    { fShaderFile, GL_FRAGMENT_SHADER, NULL }
    };

    GLuint program = glCreateProgram();

    for ( int i = 0; i < 2; ++i ) {
    Shader& s = shaders[i];
    s.source = readShaderSource( s.filename );
    if ( shaders[i].source == NULL ) {
        std::cerr << "Failed to read " << s.filename << std::endl;
        exit( EXIT_FAILURE );
    }

    GLuint shader = glCreateShader( s.type );
    glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
    glCompileShader( shader );

    GLint  compiled;
    glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
    if ( !compiled ) {
        std::cerr << s.filename << " failed to compile:" << std::endl;
        GLint  logSize;
        glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
        char* logMsg = new char[logSize];
        glGetShaderInfoLog( shader, logSize, NULL, logMsg );
        std::cerr << logMsg << std::endl;
        delete [] logMsg;

        exit( EXIT_FAILURE );
    }

    delete [] s.source;

    glAttachShader( program, shader );
    }

    /* link  and error check */
    glLinkProgram(program);

    GLint  linked;
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
    if ( !linked ) {
    std::cerr << "Shader program failed to link" << std::endl;
    GLint  logSize;
    glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
    char* logMsg = new char[logSize];
    glGetProgramInfoLog( program, logSize, NULL, logMsg );
    std::cerr << logMsg << std::endl;
    delete [] logMsg;

    exit( EXIT_FAILURE );
    }

    /* use program object */
    glUseProgram(program);

    return program;
}

}  // Close namespace Angel block

#endif // __ANGEL_H__

我使用以下命令编译它

g++ Sierpinski.cpp -I. -lGL -lglut -lGLU -lGLEW -g -o Sierpinski.out

当我运行它时,会出现以下内容:

[asdrubal@localhost tests]$ ./Sierpinski.out 
libGL error: failed to load driver: i965
libGL error: Try again with LIBGL_DEBUG=verbose for more details.
libGL error: failed to load driver: swrast
libGL error: Try again with LIBGL_DEBUG=verbose for more details.
X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  154 (GLX)
  Minor opcode of failed request:  34 ()
  Serial number of failed request:  39
  Current serial number in output stream:  38

有什么建议么?

PS:我现在正在使用

3.6.9-1-ARCH (Arch Linux)

编辑1:

着色器

谢尔宾斯基片段变种glsl

void main()
{
    gl_FragColor = vec4(0.0,1.0,0.0,1.0);
}

谢尔宾斯基变种glsl

#version 120
attribute vec4 vPosition; /*Si se quieren setear variables*/
void main()
{

  gl_Position = vPosition;

}

使用 LIBGL_DEBUG=verbose 输出

[asdrubal@localhost tests]$ ./Sierpinski.out 
libGL: OpenDriver: trying /usr/lib32/dri/tls/i965_dri.so
libGL: OpenDriver: trying /usr/lib32/dri/i965_dri.so
libGL error: dlopen /usr/lib32/dri/i965_dri.so failed (/usr/lib32/dri/i965_dri.so: cannot open shared object file: No such file or directory)
libGL error: unable to load driver: i965_dri.so
libGL error: driver pointer missing
libGL error: failed to load driver: i965
libGL: OpenDriver: trying /usr/lib32/dri/tls/swrast_dri.so
libGL: OpenDriver: trying /usr/lib32/dri/swrast_dri.so
libGL error: dlopen /usr/lib32/dri/swrast_dri.so failed (/usr/lib32/dri/swrast_dri.so: cannot open shared object file: No such file or directory)
libGL error: unable to load driver: swrast_dri.so
libGL error: failed to load driver: swrast
X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  154 (GLX)
  Minor opcode of failed request:  34 ()
  Serial number of failed request:  39
  Current serial number in output stream:  38

编辑2:

命令:

lspci | grep VGA

退货

00:02.0 VGA compatible controller: Intel Corporation Mobile GM965/GL960 Integrated Graphics Controller (primary) (rev 03)
4

1 回答 1

12
Intel Corporation Mobile GM965/GL960

您正在运行第四代英特尔芯片,因此:

glutInitContextVersion(3,2);

是相当...乐观

除非你想要软件渲染,在这种情况下你必须等待一段时间让 Mesa 升级到OpenGL 3.2

编辑:试试这个:

#include <GL/glew.h>
#include <GL/glut.h>
#include <glm/glm.hpp>
#include <iostream>
#include <vector>
#include <cmath>
#include <stdexcept>

using namespace std;

// vertex shader
const GLchar* vert =
"#version 120\n"
"attribute vec2 position;"
"void main()"
"{"
"   gl_Position = vec4( position, 0.0, 1.0 );"
"}"
;

// fragment shader
const GLchar* frag = 
"#version 120\n"
"void main()"
"{"
"    gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );"
"}"
;

const unsigned int NUM_PUNTOS = 4;
const unsigned int DIVISIONES = 5;

namespace Global
{
    GLint Ndivisions = DIVISIONES;
    GLint Nvertices = (GLint) std::pow(3.0,Ndivisions + 1);
    std::vector<glm::vec2> points;
};

void triangle( glm::vec2 a, glm::vec2 b, glm::vec2 c, std::vector<glm::vec2> &points )
{
    size_t old_size = points.size();
    points.resize(old_size + 3);
    points[old_size] = a;
    points[old_size + 1] = b;
    points[old_size + 2] = c;
}

glm::vec2 dividir( glm::vec2 vectorcito, double escalar )
{
    return glm::vec2(vectorcito.x/escalar,vectorcito.y/escalar);
}

void divide_triangle( glm::vec2 a, glm::vec2 b, glm::vec2 c, GLint k, std::vector<glm::vec2> &points )
{
    if(k>0)
    {
        glm::vec2 ab = dividir(a + b,2.0);
        glm::vec2 ac = dividir(a + c,2.0);
        glm::vec2 bc = dividir(b + c,2.0);

        //Dividimos triángulo
        int new_k = k - 1;
        divide_triangle(a,ab,ac,new_k,points);
        divide_triangle(c,ac,bc,new_k,points);
        divide_triangle(b,bc,ab,new_k,points);
    }
    else
    {
        triangle(a,b,c,points);
    }
}

void CheckStatus( const GLenum id )
{
    GLint status = GL_FALSE, loglen = 10;
    if( glIsShader(id) )    glGetShaderiv( id, GL_COMPILE_STATUS, &status ); 
    if( glIsProgram(id) )   glGetProgramiv( id, GL_LINK_STATUS, &status );
    if( GL_TRUE == status ) return;
    if( glIsShader(id) )    glGetShaderiv( id, GL_INFO_LOG_LENGTH , &loglen);
    if( glIsProgram(id) )   glGetProgramiv( id, GL_INFO_LOG_LENGTH , &loglen);
    vector< char > log( loglen, 'E' );
    if( glIsShader(id) )    glGetShaderInfoLog( id, loglen, NULL, &log[0] );
    if( glIsProgram(id) )   glGetProgramInfoLog( id, loglen, NULL, &log[0] );
    throw logic_error( string( log.begin(), log.end() ) ); 
}

GLuint CreateShader( const GLenum aType, const string& aSource )
{
    GLuint shader = glCreateShader( aType );
    const GLchar* shaderString = aSource.c_str();
    glShaderSource( shader, 1, &shaderString, NULL );
    glCompileShader( shader );
    CheckStatus( shader );
    return shader;
}

GLuint CreateProgram( const string& aVertexShader, const string& aFragmentShader )
{
    GLuint vert = CreateShader( GL_VERTEX_SHADER, aVertexShader );
    GLuint frag = CreateShader( GL_FRAGMENT_SHADER, aFragmentShader );
    GLuint program = glCreateProgram();
    glAttachShader( program, vert );
    glAttachShader( program, frag );
    glLinkProgram( program );
    glDeleteShader( vert );
    glDeleteShader( frag );
    CheckStatus( program );
    return program;
}

GLuint prog = 0;
GLuint vbo = 0;
void init()
{
    GLenum glewError = glewInit();
    if( GLEW_OK != glewError )
        throw runtime_error( (char*)glewGetErrorString(glewError) );

    cout << "GL_VERSION   : " << glGetString(GL_VERSION) << endl;
    cout << "GL_VENDOR    : " << glGetString(GL_VENDOR) << endl;
    cout << "GL_RENDERER  : " << glGetString(GL_RENDERER) << endl;    
    cout << "GLEW_VERSION : " << glewGetString(GLEW_VERSION) << endl;
    cout << "GLSL VERSION : " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;

    if( !GLEW_VERSION_2_1 )
        throw runtime_error( "OpenGL 2.1 or better required for GLSL support." ); 

    // load shaders
    prog = CreateProgram( vert, frag );

    //Inicializamos array global
    divide_triangle
        (
        glm::vec2(0.0,0.0),
        glm::vec2(1.0,0.0),
        glm::vec2(0.5,1.0),
        Global::Ndivisions,
        Global::points
        );

    // create/fill VBO
    glGenBuffers( 1, &vbo );
    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    unsigned int numBytes = sizeof( glm::vec2 ) * Global::points.size();
    glBufferData( GL_ARRAY_BUFFER, numBytes, &Global::points[0].x, GL_STATIC_DRAW );
}

void display(void)
{
    glClear( GL_COLOR_BUFFER_BIT );

    glUseProgram( prog );

    GLint position_loc = glGetAttribLocation( prog, "position" );
    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glVertexAttribPointer( position_loc, 2, GL_FLOAT, GL_FALSE, sizeof( glm::vec2 ), 0 );
    glEnableVertexAttribArray( position_loc );

    glDrawArrays( GL_POINTS, 0, Global::points.size() );

    glDisableVertexAttribArray( position_loc );

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv );
    glutInitWindowSize( 800,600 );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutCreateWindow( "Sierpinski gasket" );
    init();
    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}

截屏

于 2012-12-13T16:29:37.213 回答