0
votes

I'm starting to learn about OpenGL and doing some early examples to understand the API how to use it. The I'm currently stuck on, is with a rotation example. The code, (provided bellow) is supposed to create a 2D square from 4 vertices and apply a rotation of 30º around the Z axis. Apparently, the code seems fine and I've seen it running in my professor's machine and it works. If I draw the square without applying the rotation inside the shader, the program draws the square, but with no rotation, of course.

Could this be caused by some bad configuration? All the other examples seems to work fine.

Here is the code:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Angel.h"

glm::vec2 vertices[4] = {
    glm::vec2( -0.5, -0.5 ),
    glm::vec2(  0.5, -0.5 ),
    glm::vec2(  0.5,  0.5 ),
    glm::vec2( -0.5,  0.5 ),
};

const int NumPoints = 6;
glm::vec2 points[NumPoints];

void square( ){
    points[0] = vertices[0];
    points[1] = vertices[1];
    points[2] = vertices[2];
    points[3] = vertices[0];
    points[4] = vertices[2];
    points[5] = vertices[3];
}

GLuint matRot;
void init( void ){
    square();
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

    GLuint program = InitShader( "vshader1.glsl", "fshader1.glsl" );
    glUseProgram( program );

    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
                           BUFFER_OFFSET(0) );

    matRot = glGetUniformLocation( program, "rot" );

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); 
}

void display( void ){
    glClear( GL_COLOR_BUFFER_BIT );    

    glm::mat4 rotZ; 
    rotZ = glm::rotate(rotZ, glm::radians(30.0f), glm::vec3(0.0f,0.0f,1.0f));
    glUniformMatrix4fv(matRot,1,GL_FALSE, glm::value_ptr(rotZ)); 

    glDrawArrays( GL_TRIANGLES, 0, NumPoints );  
    glFlush();
}

int main( int argc, char **argv ){
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
    glutInitWindowSize( 512, 512 );
    glutInitWindowPosition(0,0);
    glutCreateWindow( "square rotation" );

    glewInit(); 

    init();

    glutDisplayFunc( display );

    glutMainLoop();
    return 0;
}

The Angel.h is an additional resource that helps with some management of all those libraries. It can be found here and the InitShader implementation is here

The vertex shader:

#version 130

in vec4 vPosition;
uniform mat4 rot;

void main()
{
    gl_Position = rot * vPosition;
}

If I don't multiply rot * vPosition, the "un-rotated" square is drawn

And the fragments shadder:

#version 130

out vec4 fColor;

void main()
{
    fColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}
1
How does this matter ? It may rotate by wrong angle and not by 30 degrees. But OP is saying he doesnt see any rotation.Paritosh Kulkarni
The static method is glm::degress(30.0f) rigth? I tried this way, but still a blank windowLucas Henrique
You will need to upgrade the graphics card drivers for this. New graphics card drivers will come with new version of OpenGL and GLSL.Paritosh Kulkarni
@ParitoshKulkarni I have version 0.9.9-a1 and tried both way (with glm::degress(30.0f) and with 30.0f and didn't work as wellLucas Henrique
I think just update the driver also change to double buffering replace glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA ); to glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );Paritosh Kulkarni

1 Answers

2
votes

Workin' fine on my machine with FreeGLUT, GLUT_DOUBLE, & GLM 0.9.8.4:

screenshot of rotated square

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <cstdarg>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

struct Program
{
    static GLuint Load( const char* shader, ... )
    {
        GLuint prog = glCreateProgram();
        va_list args;
        va_start( args, shader );
        while( shader )
        {
            const GLenum type = va_arg( args, GLenum );
            AttachShader( prog, type, shader );
            shader = va_arg( args, const char* );
        }
        va_end( args );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static 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;
        GLchar 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( EXIT_FAILURE );
    }

    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

glm::vec2 vertices[4] =
{
    glm::vec2( -0.5, -0.5 ),
    glm::vec2(  0.5, -0.5 ),
    glm::vec2(  0.5,  0.5 ),
    glm::vec2( -0.5,  0.5 ),
};

const int NumPoints = 6;
glm::vec2 points[NumPoints];

void square( )
{
    points[0] = vertices[0];
    points[1] = vertices[1];
    points[2] = vertices[2];
    points[3] = vertices[0];
    points[4] = vertices[2];
    points[5] = vertices[3];
}

GLuint matRot;
void init( void )
{
    square();
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

    const char* vert = GLSL
    (
        130,
        in vec4 vPosition;
        uniform mat4 rot;

        void main()
        {
            gl_Position = rot * vPosition;
        }
    );

    const char* frag = GLSL
    (
        130,
        out vec4 fColor;

        void main()
        {
            fColor = vec4( 1.0, 0.0, 0.0, 1.0 );
        }
    );
    GLuint program = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
    glUseProgram( program );

    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );

    matRot = glGetUniformLocation( program, "rot" );

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); 
}


void display()
{
    glClear( GL_COLOR_BUFFER_BIT );    

    glm::mat4 rotZ; 
    rotZ = glm::rotate(rotZ, glm::radians(30.0f), glm::vec3(0.0f,0.0f,1.0f));
    glUniformMatrix4fv(matRot,1,GL_FALSE, glm::value_ptr(rotZ)); 

    glDrawArrays( GL_TRIANGLES, 0, NumPoints );  

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 600, 600 );
    glutCreateWindow( "GLUT" );

    glewExperimental = GL_TRUE;
    glewInit();

    init();

    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}