0

我在正确绘制正方形时遇到了麻烦。我在 Windows 7 x64 上使用 glut 和 glew。

我只能在右上角看到一个黑色方块(我的应用程序中的 WALL)。

我正在尝试用正方形画一个迷宫。

我没有着色器的源代码:

#define GL_GLEXT_PROTOTYPES 1
#define FREEGLUT_LIB_PRAGMAS 1
#define FREEGLUT_STATIC 1
#include <gl/glew.h>
#include <gl/freeglut.h>
#include <stdlib.h>
#include <gl/glext.h>
#include "Shaders.h"
#include <iostream>
using namespace std;
GLuint buf_v;
GLuint buf_c;
#define FOR(i,s,t) for(int i = (s); i < (t);i++)
int width = 480;
int height = 800;
const int N = 24;
const int WALL = 9999;
int map[N][N];
GLfloat arrQuad[12];
GLfloat color[] ={ 1.0,1.0,1.0,1.0};
Shaders shaders;
Matrix w, v, p, wvp;
void drawQuad(float x, float y, int isWALL = 9999){//from top left corner
    glUseProgram(shaders.program);
    glBindBuffer(GL_ARRAY_BUFFER, buf_v);
    GLvoid *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY );
    arrQuad[0] = x;
    arrQuad[1] = y;
    arrQuad[2] = x;
    arrQuad[3] = y + 1.0;
    arrQuad[4] = x + 1.0;
    arrQuad[5] = y;

    arrQuad[6] = x;
    arrQuad[7] = y + 1.0;
    arrQuad[8] = x + 1.0;
    arrQuad[9] = y;
    arrQuad[10] = x + 1.0;
    arrQuad[11] = y + 1.0;
    FOR(i,0,12){
        arrQuad[i]*=(GLfloat)width;
        arrQuad[i]/=(GLfloat)N;
    }
    printf("%f, %f    %f %f \n",arrQuad[3],arrQuad[4], arrQuad[10],arrQuad[11]);
    printf("%f, %f    %f %f \n\n",arrQuad[0],arrQuad[1], arrQuad[8],arrQuad[9]);

    memcpy(buf, arrQuad, sizeof(arrQuad));
    glUnmapBuffer(GL_ARRAY_BUFFER);
    if(isWALL == WALL){
        color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f;
    }
    else
    {
        color[0] = 0.0; color[1] = 0.0; color[2] = 0.0;
    }
    if(shaders.positionAttribute != -1)
    {
        glEnableVertexAttribArray(shaders.positionAttribute);
        glVertexAttribPointer(shaders.positionAttribute, 2, GL_FLOAT, GL_FALSE, 0, 0);;
    }else{ perror("err pos attr"); }

    if(shaders.colorUniform != -1)
    {
        glUniform4fv(shaders.colorUniform, 1, color);
    }else{ perror ("err col atr"); }
    GLfloat mat_wvp_16[16] = {
        wvp[0],  wvp[1],  wvp[2],  wvp[3],
        wvp[4],  wvp[5],  wvp[6],  wvp[7],
        wvp[8],  wvp[9],  wvp[10],  wvp[11],
        wvp[12],  wvp[13],  wvp[14],  wvp[15],
    };                    

    if(shaders.mat_wvp != -1)
    {
        glUniformMatrix4fv(shaders.mat_wvp, 1, GL_FALSE, mat_wvp_16);
    }else{
        //perror ("err mat atr");
    }
    glBindBuffer(GL_ARRAY_BUFFER, buf_v);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void reshape(int w, int h)
{
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
}
void init(){
    shaders.HasGLSLSupport();
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glGenBuffers(1, &buf_v);
    glBindBuffer(GL_ARRAY_BUFFER, buf_v);
    glBufferData(GL_ARRAY_BUFFER, sizeof(arrQuad), arrQuad, GL_DYNAMIC_DRAW);

    glGenBuffers(1, &buf_c);
    glBindBuffer(GL_ARRAY_BUFFER, buf_c);
    glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_DYNAMIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    if(shaders.Init("vert.vs","frag.frg") != 0)
        perror("shader initialization error");
    wvp.loadOrthoMatrix(0.0, width, 0, height, 0.0, 100.0);

    wvp = wvp * w;
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    FOR(i, 0, N)
        FOR(j, 0, N)
    {
        drawQuad(i, j, map[i][j]);
    }

    glutSwapBuffers();
}
void timer(int i = 0)
{
    glutPostRedisplay();
    FOR(i, 0, N)
        FOR(j, 0, N)
    {
        if(rand() % 4 == 0)
            map[i][j] = WALL;
        else
            map[i][j] = -1;
    }
    display();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(width, height);
    glutCreateWindow("Hi, wave!");
    glClearColor(1.0,1.0,1.0,1.0);
    glViewport(0,0,(GLfloat)width, (GLfloat)height);
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        cout << "glewInit failed, aborting." << endl;
        exit (1);
    }
    init();

    glutTimerFunc(17,timer,0);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();

    return 0;
}

vert.vs

uniform mat4 u_wvp;
attribute vec4 a_pos;
void main ()
{
  gl_Position = (u_wvp * a_pos);
}

片段

precision mediump float;
uniform vec4 u_color;

void main(){
   gl_FragColor = u_color;
}
4

1 回答 1

1

试试这个:

#include <GL/glew.h>
#include <GL/glut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <vector>
using namespace std;

// RAII vertex attribute wrapper
struct Attrib
{
    Attrib
        ( 
        const char* name, const GLint size, const GLsizei stride, const GLvoid* pointer, 
        const GLenum type = GL_FLOAT, const GLboolean normalized = GL_FALSE, const GLuint prog = GetProgram() 
        )
    {
        mLoc = glGetAttribLocation( prog, name );
        if( mLoc < 0 ) return;
        glVertexAttribPointer( mLoc, size, type, normalized, stride, pointer );
        glEnableVertexAttribArray( mLoc );
    }

    ~Attrib()
    {
        if( mLoc < 0 ) return;
        glDisableVertexAttribArray( mLoc );
    }

    GLint mLoc;

private:
    static GLuint GetProgram()
    {
        GLint program = 0;
        glGetIntegerv( GL_CURRENT_PROGRAM, &program );
        return program;
    }
};

// GLSL shader program loader
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
(
    110,
    uniform mat4 u_wvp;
    attribute vec2 a_pos;
    void main ()
    {
      gl_Position = ( u_wvp * vec4( a_pos, 0.0, 1.0 ) );
    }
);

const char* frag = GLSL
(
    110,
    uniform vec4 u_color;
    void main(){
       gl_FragColor = u_color;
    }
);

GLuint buf_v;
GLuint buf_c;
#define FOR(i,s,t) for(int i = (s); i < (t);i++)
int width = 480;
int height = 800;
const int N = 24;
const int WALL = 9999;
int map[N][N];
GLfloat arrQuad[12];
GLfloat color[] ={ 1.0,1.0,1.0,1.0};

glm::mat4 proj;
glm::mat4 modelview;
glm::mat4 wvp;

GLuint program;
void drawQuad(float x, float y, int isWALL = 9999)
{
    //from top left corner
    glUseProgram(program);
    glBindBuffer(GL_ARRAY_BUFFER, buf_v);
    GLvoid *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY );
    arrQuad[0] = x;
    arrQuad[1] = y;
    arrQuad[2] = x;
    arrQuad[3] = y + 1.0;
    arrQuad[4] = x + 1.0;
    arrQuad[5] = y;

    arrQuad[6] = x;
    arrQuad[7] = y + 1.0;
    arrQuad[8] = x + 1.0;
    arrQuad[9] = y;
    arrQuad[10] = x + 1.0;
    arrQuad[11] = y + 1.0;
    FOR(i,0,12)
    {
        arrQuad[i]*=(GLfloat)width;
        arrQuad[i]/=(GLfloat)N;
    }
    memcpy(buf, arrQuad, sizeof(arrQuad));
    glUnmapBuffer(GL_ARRAY_BUFFER);

    if(isWALL == WALL)
    {
        color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f;
    }
    else
    {
        color[0] = 0.0; color[1] = 0.0; color[2] = 0.0;
    }

    glUniformMatrix4fv( glGetUniformLocation( program, "u_wvp" ), 1, GL_FALSE, glm::value_ptr( wvp ) );
    glUniform4fv( glGetUniformLocation( program, "u_color" ), 1, color );
    {
        glBindBuffer(GL_ARRAY_BUFFER, buf_v);
        Attrib a1( "a_pos", 2, 0, 0 );
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glBindBuffer(GL_ARRAY_BUFFER, 0);        
    }
}

void init()
{
    glGenBuffers(1, &buf_v);
    glBindBuffer(GL_ARRAY_BUFFER, buf_v);
    glBufferData(GL_ARRAY_BUFFER, sizeof(arrQuad), arrQuad, GL_DYNAMIC_DRAW);

    glGenBuffers(1, &buf_c);
    glBindBuffer(GL_ARRAY_BUFFER, buf_c);
    glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_DYNAMIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

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

    glm::mat4 proj = glm::ortho( 0.0f, (float)width, 0.0f, (float)height, 0.0f, 100.0f );
    glm::mat4 modelview = glm::mat4( 1.0f );
    wvp = proj * modelview;
}

void display()
{
    FOR(i, 0, N)
        FOR(j, 0, N)
    {
        if(rand() % 4 == 0)
            map[i][j] = WALL;
        else
            map[i][j] = -1;
    }

    glClearColor(1.0,1.0,1.0,1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    FOR(i, 0, N)
        FOR(j, 0, N)
    {
        drawQuad(i, j, map[i][j]);
    }

    glutSwapBuffers();
}

void timer(int i = 0)
{
    glutPostRedisplay();
    glutTimerFunc( 17, timer, 0 );
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(width, height);
    glutCreateWindow("Hi, wave!");
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        cout << "glewInit failed, aborting." << endl;
        exit (1);
    }
    init();

    glutTimerFunc(0,timer,0);
    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}
于 2013-05-17T22:06:45.107 回答