views:

951

answers:

2

I'm trying to read some OpenGL tutorials on the net. the problem is that I found some old ones that use gluPerspective(). gluPerspective was deprecated in OpenGL 3.0 and removed in 3.1.

What function can I use instead?

I'm using C++ with latest FreeGlut installed.

+4  A: 

Copied from one of my older projects:

// The following code is a fancy bit of math that is eqivilant to calling:
// gluPerspective( fieldOfView/2.0f, width/height , 0.1f, 255.0f )
// We do it this way simply to avoid requiring glu.h
GLfloat zNear = 0.1f;
GLfloat zFar = 255.0f;
GLfloat aspect = float(width)/float(height);
GLfloat fH = tan( float(fieldOfView / 360.0f * 3.14159f) ) * zNear;
GLfloat fW = fH * aspect;
glFrustum( -fW, fW, -fH, fH, zNear, zFar );
Toji
Except glFrustum() was deprecated in 3.1 also.
genpfault
Really? Shame, that.
Toji
+6  A: 

You have to compute the matrix manually and then pass it to OpenGL.

Computing the matrix

This snippet of code was lifted from geeks3d via opengl.org.

 void BuildPerspProjMat(float *m, float fov, float aspect,
 float znear, float zfar)
 {
  float ymax = znear * tan(fov * PI_OVER_360);
  float ymin = -ymax;
  float xmax = ymax * aspect;
  float xmin = ymin * aspect;

  float width = xymax - xmin;
  float height = xymax - ymin;

  float depth = zfar - znear;
  float q = -(zfar + znear) / depth;
  float qn = -2 * (zfar * znear) / depth;

  float w = 2 * znear / width;
  w = w / aspect;
  float h = 2 * znear / height;

  m[0]  = w;
  m[1]  = 0;
  m[2]  = 0;
  m[3]  = 0;

  m[4]  = 0;
  m[5]  = h;
  m[6]  = 0;
  m[7]  = 0;

  m[8]  = 0;
  m[9]  = 0;
  m[10] = q;
  m[11] = -1;

  m[12] = 0;
  m[13] = 0;
  m[14] = qn;
  m[15] = 0;
 }

There is a C++ library called OpenGL Mathematics that may be useful.

Loading the Matrix in OpenGL 3.1

I am still new to the OpenGL 3.1 API, but you need to update a matrix on the GPU and then make use of it in your vertex shader to get the proper perspective. The following code just loads the matrix using glUniform4fv onto the video card.

{
  glUseProgram(shaderId);
  glUniformMatrix4fv(glGetUniformLocation(shaderId, "u_proj_matrix"),
                     1, GL_FALSE, theProjectionMatrix);
  RenderObject();
  glUseProgram(0);
}

A simple vertex shader from a random blog (found through stack overflow).

attribute vec4      a_position;
attribute vec4      a_color;

varying vec4        v_color;

uniform mat4 u_proj_matrix;
uniform mat4 u_model_matrix;

void main() {
  mat4 mvp_matrix = u_proj_matrix * u_model_matrix;
  v_color = a_color;
  gl_Position = mvp_matrix * a_position;
}
Dan
thank you :) that opengl mathematics library seems not bad at all.
ufk
Perfect! Thanks for sharing.
Xavier Ho
This function doesn't work. What is xmax and ymax? They're used on the second line and not defined
gman
I followed the article sources back to the original, which is in French: http://www.xgouchet.fr/blog/index.php/post/2009/07/27/Definir-le-zoom-du-Camera-sous-OpenGL-ES. It sets ymax = znear * tan(fov * PI_OVER_360); and gets via xmax = ymax * aspect. ymin = -ymax; xmin = ymin * aspect;
Dan