Search code examples
openglglutorthogonal

Orthogonal projection, drawing square in OpenGL 2.0


I'm having troubles with proper drawing squares. I'm using glut and glew on Windows 7 x64.

I can see only a black square(WALL in my app) in the right top corner.

I'm trying to draw a labyrinth with squares.

my source code without shaders:

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

frag.frg

precision mediump float;
uniform vec4 u_color;

void main(){
   gl_FragColor = u_color;
}

Solution

  • Try this:

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