PDA

View Full Version : glm::perspective inverts image



kosborn
02-05-2015, 09:11 PM
Hi,

I am using GLM 0.9.6.1 on Windows 8.1 (Qt Creator and VC++ 2008). When using glm perspective as my projection matrix I find my rendered image is inverted. Replacing the projection matrix with glm frustum gives me the correct orientation. I'm not sure if it's a bug or there is something basic that I'm missing. I wrote a sample program to illustrate:



#include "stdafx.h"

#include <GL/glew.h>
#include <freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <string>

#define WIDTH 512
#define HEIGHT 512
#define ASPECT (float)WIDTH / (float)HEIGHT

static GLfloat axes[] = {
0.0, 0.0, 0.0,
0.0, 0.0, 1.0,
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0
};

const std::string vertShader =
"#version 400 core \n"
"in vec3 vertexPosition; \n"
"uniform mat4 view; \n"
"uniform mat4 proj; \n"
"out vec4 vertColour; \n"
"void main() \n"
"{ \n"
" if (gl_VertexID == 0 || gl_VertexID == 1) \n"
" vertColour = vec4(1.0, 0.0, 0.0, 1.0); \n"
" else if (gl_VertexID == 2 || gl_VertexID == 3) \n"
" vertColour = vec4(0.0, 1.0, 0.0, 1.0); \n"
" else \n"
" vertColour = vec4(0.0, 0.0, 1.0, 1.0); \n"
" gl_Position = proj * view * vec4(vertexPosition, 1.0); \n"
"} ";

const std::string fragShader =
"#version 400 core \n"
"in vec4 vertColour; \n"
"out vec4 fragColour; \n"
"void main() \n"
"{ \n"
" fragColour = vertColour; \n"
"} ";


GLuint vao;
GLuint prog;
GLuint pmLoc;
glm::mat4 projMatrix[2];

static void displayCallback();

int _tmain(int argc, _TCHAR* argv[])
{
glutInit(&argc, (char **)argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(2*WIDTH, HEIGHT);
int window = glutCreateWindow("GLM Projection Matrix");
glewExperimental = GL_TRUE;
glewInit();
glClearColor(0.2f, 0.2f, 0.3f, 1.0f);

glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.3f, 0.3f, 1.5f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
projMatrix[0] = glm::frustum(-ASPECT * 0.1f, ASPECT * 0.1f, -0.1f, 0.1f, 0.1f, 100.0f);
projMatrix[1] = glm::perspective(55.0f, ASPECT, 0.1f, 100.0f);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(axes) * sizeof(GLfloat), axes, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);

GLuint vs = glCreateShader(GL_VERTEX_SHADER);
const char *vsource = vertShader.c_str();
glShaderSource(vs, 1, &vsource, NULL);
glCompileShader(vs);

GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
const char *fsource = fragShader.c_str();
glShaderSource(fs, 1, &fsource, NULL);
glCompileShader(fs);

prog = glCreateProgram();
glAttachShader(prog, vs);
glAttachShader(prog, fs);
glLinkProgram(prog);
glDeleteShader(vs);
glDeleteShader(fs);

glUseProgram(prog);
GLuint vmLoc = glGetUniformLocation(prog, "view");
pmLoc = glGetUniformLocation(prog, "proj");
glUniformMatrix4fv(vmLoc, 1, GL_FALSE, glm::value_ptr(viewMatrix));

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

static void displayCallback()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);

for (int i = 0; i < 2; i++) {
glViewport(WIDTH*i, 0, WIDTH, HEIGHT);
glUniformMatrix4fv(pmLoc, 1, GL_FALSE, glm::value_ptr(projMatrix[i]));
glDrawArrays(GL_LINES, 0, 6);
}

glutSwapBuffers();
}

I would be grateful for any suggestions.

Thanks, K

kosborn
02-06-2015, 01:37 PM
It seems it's a bug in the documentation rather than a bug in the code. The documentation says

"fov Expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise."

but when the angle is passed as radians the perspective matrix works as expected.

K

Alfonse Reinheart
02-06-2015, 02:22 PM
It seems it's a bug in the documentation rather than a bug in the code.

Since GLM is supposed to default to the old GLU library's behavior, that sounds more like a bug in GLM than a bug in its documentation. So file a bug report.

kosborn
02-06-2015, 02:56 PM
Since GLM is supposed to default to the old GLU library's behavior, that sounds more like a bug in GLM than a bug in its documentation. So file a bug report.

It looks like GLM is no longer defaulting to old GLU library behaviour. After a bit of looking around (which I probably should have done sooner) I found the following release notes for GLM 0.9.6 (http://glm.g-truc.net/0.9.5/updates.html) basically saying that all angle measurements for GLM 0.9.6 are now in radians.