PDA

View Full Version : glm: Triangle with perspective



Schnulla
07-12-2010, 11:23 AM
Hi,

I can see my first "OpenGL 3.2 core profile"-triangle :)
Now I tried to add perspective using the nice glm library.

But somehow the triangle disappears when using the
perspective stuff. Here is my code:


#version 150 core

uniform mat4 ModelViewProjectionMatrix;

in vec3 in_Position;

void main(void)
{
gl_Position= ModelViewProjectionMatrix * vec4(in_Position, 1.0);
}


#version 150 core

out vec4 out_Color;

void main(void)
{
out_Color = vec4(1.0, 0.0, 0.0, 1.0);
}



// setup projection matrix

ProjectionMatrix= glm::mat4(1.0f);
ProjectionMatrix*= glm::perspective(45.0f, 1024.0f / 768.0f, 0.1f, 200.0f);


// setup modelview matrix (look down the negative z-axis)

ModelViewMatrix= glm::mat4(1.0f);
ModelViewMatrix*= glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));


// create and upload modelviewprojection matrix

ModelViewProjectionMatrix= ProjectionMatrix * ModelViewMatrix;
glUniformMatrix4fv(glGetUniformLocation(m_handle, "ModelViewProjectionMatrix"), 1, false, glm::value_ptr(ModelViewProjectionMatrix));


// setup triangle using VBO and VAO

float* vert = new float[9];

vert[0] = 0.0; vert[1] = 1.0; vert[2]= -10.0;
vert[3] =-1.0; vert[4] =-1.0; vert[5]= -10.0;
vert[6] = 1.0; vert[7] =-1.0; vert[8]= -10.0;

unsigned int m_vaoID;

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

glGenBuffers(1, &m_vboID);
glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), vert, GL_STATIC_DRAW); glVertexAttribPointer((GLuint)ATTRIBUTE_LOCATION_W ORLDVERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(ATTRIBUTE_LOCATION_WORLD VERTEX);


// render

glDrawArrays(GL_TRIANGLES, 0, 3);


// cleanup

glBindVertexArray(0);

delete[] vert;

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &m_vboID);

glDeleteVertexArrays(1, &m_vaoID);


I can see this triangle...
http://s7.directupload.net/images/100712/temp/g3j9lu44.png (http://s7.directupload.net/file/d/2218/g3j9lu44_png.htm)
...when I apply the following changes to the code above:


glUniformMatrix4fv(glGetUniformLocation(m_handle, "ModelViewProjectionMatrix"), 1, false, glm::value_ptr(glm::mat4(1.0f)/*ModelViewProjectionMatrix*/));

vert[0] = 0.0; vert[1] = 1.0; vert[2]= -1.0;
vert[3] =-1.0; vert[4] =-1.0; vert[5]= -1.0;
vert[6] = 1.0; vert[7] =-1.0; vert[8]= -1.0;


So the change is that I upload an identity (no projection)
matrix for the modelviewprojection matrix and display the
triangle at z == -1.0f instead of -10.0f.

I have disabled back-face culling and depth test.

Where is my mistake? I can't get the triangle to work
with perspective. I'm really stuck :(

Help is really appreciated!

Groovounet
07-13-2010, 04:00 AM
Instead of:
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));

I have the feeling that this would be better:
glm::lookAt(glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

No sure actually, it could be many thinks....

Schnulla
07-13-2010, 01:30 PM
Mhmmm my triangle "sits" on the negative z-axis at -10.
So I guess the camera should look down the negative z-axis to
be able to see the triangle. That's why I set the camera position
to (0,0,0) and the camera target to a point on the negative
z-axis (0,0,-1).

Anyway I tried your version but still no triangle =/. I really
wonder what could be wrong because it is not much code.
The shaders are minimalist... the object is minimalist... and
also visible without projection... all I do is multiplying
with the modelviewprojection matrix.

Schnulla
07-19-2010, 01:00 PM
Groovounet do you have a working GLM example
similiar to my code above? I have no clue
whats wrong. It works without the projection
so I guess the projection matrix that glm
returns does not work.

marshats
07-19-2010, 09:26 PM
I took a look at Projection tutorial (http://www.gamedev.net/reference/articles/article839.asp) to first confrim what you had made sense -- yes it did. I then pulled together a quick complete code to try it out. This works fine for me ... I used the notation &variable[0][0] instead of glm::value_ptr(variable) notation.



#define GL3_PROTOTYPES
#include <GL3/gl3.h>
#include <SDL.h>
#include <iostream>
#include <fstream>

//OpenGL Mathematics (GLM). A C++ mathematics library for 3D graphics.
#include <glm/glm.hpp>
#include <glm/GLM_GTX_matrix_projection.h>
#include <glm/GLM_GTX_transform2.h> // for lookAt

void glError(const char *file, int line) {
GLenum err(glGetError());

while(err!=GL_NO_ERROR) {
std::string error;

switch(err) {
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
}

std::cerr<<"GL_"<<error<<" - "<<file<<':'<<line<<std::endl;
err=glGetError();
}
}

int main() {
//SDL Initialization
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3 );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,2 );
SDL_Init(SDL_INIT_VIDEO);

const int r_width(640),r_height(480);
SDL_WindowID window(SDL_CreateWindow("Foo",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,r_w idth,r_height,SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN)) ;
SDL_GLContext glcontext(SDL_GL_CreateContext(window));

std::cout<<"OpenGL "<<glGetString(GL_VERSION)<<" (GLSL "<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<')'<<std::endl;

//Create shaders and shader program
GLuint vshader(glCreateShader(GL_VERTEX_SHADER));
GLuint fshader(glCreateShader(GL_FRAGMENT_SHADER));
GLuint program(glCreateProgram());

{
std::ifstream source_file("image.vert");

std::string data;
std::getline(source_file,data,'\0');

const GLchar *vshader_source(data.c_str());

glShaderSource(vshader,1,&amp;vshader_source,NULL);
}

{
std::ifstream source_file("image.frag");

std::string data;
std::getline(source_file,data,'\0');

const GLchar *fshader_source(data.c_str());

glShaderSource(fshader,1,&amp;fshader_source,NULL);
}

glCompileShader(vshader);
glCompileShader(fshader);

glAttachShader(program,vshader);
glAttachShader(program,fshader);
glLinkProgram(program);

//Get handles to shader uniforms
GLint l_ModelViewProjectionMatrix(glGetUniformLocation(p rogram,"ModelViewProjectionMatrix")); //uniform mat4 ModelViewProjectionMatrix;

//Create geometry vertex array
GLuint buf_in_Position,vao;
const GLfloat in_Position[3*3]= {
0.0f, 1.0f,-10.0f,
-1.0f,-1.0f,-10.0f,
1.0f,-1.0f,-10.0f
};

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

//in vec3 in_Position;
glGenBuffers(1,&amp;buf_in_Position);
glBindBuffer(GL_ARRAY_BUFFER,buf_in_Position);
glBufferData(GL_ARRAY_BUFFER,sizeof(in_Position),i n_Position,GL_STATIC_DRAW);
const GLint l_in_Position(glGetAttribLocation(program,"in_Position"));
glVertexAttribPointer(l_in_Position,3,GL_FLOAT,GL_ TRUE,0,NULL);
glEnableVertexAttribArray(l_in_Position);

//Render
glm::mat4 projmat;
glm::mat4 modelmat;
glm::mat4 ModelViewProjectionMatrix;

projmat=glm::mat4(1.0); //loadIdentity
projmat*=glm::perspective(45.0f, 1024.0f / 768.0f, 0.1f, 200.0f);

modelmat=glm::mat4(1.0); //loadIdentity
modelmat*=glm::lookAt( glm::vec3(0.0f,0.0f, 0.0f),
glm::vec3(0.0f,0.0f,-1.0f),
glm::vec3(0.0f,1.0f, 0.0f));

ModelViewProjectionMatrix=projmat*modelmat;

glUseProgram(program);

glUniformMatrix4fv(l_ModelViewProjectionMatrix,1,G L_FALSE,&amp;ModelViewProjectionMatrix[0][0]);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES,0,3);

glError(__FILE__,__LINE__);
SDL_GL_SwapWindow(window);
SDL_Delay(6000);

//Quit
glDeleteShader(vshader);
glDeleteShader(fshader);
glDeleteProgram(program);
SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(window);
SDL_Quit();
}

Schnulla
07-20-2010, 10:00 AM
I just found the problem. While converting stuff from OpenGL
1.X to 3.2 I had to comment out some old code in a utility
class to avoid that glGetError throws errors.

Unfortunately in this code also some arrays were allocated.
Later there was a write operation on these arrays (which I
forgot to comment out too). This operation wrote into
undefined memory locations partially overwriting my glm
matrices. I don't know why this did not instantly crash
the program. Anyway thanks god I finally found the problem.

Also thanks for your effort marshats because after I read
your post that the code works fine for you I figured this
memory corruption out by moving the matrix calculations
from my Init method directly in front of the
glDrawElements command.

Lo and behold! I suddenly saw the triangle! So I compared
the matrix generated in front of the glDrawElements command
with the matrix generated in my Init method and noticed
a difference in one mvp column caused by this invalid write. :mad:

Shame on my that I did not notice this earlier!

Groovounet
07-21-2010, 10:09 AM
Great to read!

I was afraid that something trivial doesn't work in GLM but fortunately it's not the case here! :) Sorry I didn't put must effort on this thread, I am in holidays.

Damn it, what am I doing here? Nice day guys!