glm::perspective inverts image

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                                           
"
        "in vec3 vertexPosition;                                     
"
        "uniform mat4 view;                                          
"
        "uniform mat4 proj;                                          
"
        "out vec4 vertColour;                                        
"
        "void main()                                                 
"
        "{                                                           
"
        "    if (gl_VertexID == 0 || gl_VertexID == 1)               
"
        "        vertColour = vec4(1.0, 0.0, 0.0, 1.0);              
"
        "    else if (gl_VertexID == 2 || gl_VertexID == 3)          
"
        "        vertColour = vec4(0.0, 1.0, 0.0, 1.0);              
"
        "    else                                                    
"
        "        vertColour = vec4(0.0, 0.0, 1.0, 1.0);              
"
        "    gl_Position = proj * view * vec4(vertexPosition, 1.0);  
"
        "}                                                             ";

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


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

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

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.

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 basically saying that all angle measurements for GLM 0.9.6 are now in radians.