Reputation: 187
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 );
}
Upvotes: 0
Views: 1443
Reputation: 52157
Workin' fine on my machine with FreeGLUT, GLUT_DOUBLE
, & GLM 0.9.8.4:
#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;
}
Upvotes: 2