gluPerspective was removed in OpenGL 3.1, any replacements?

前端 未结 5 692
耶瑟儿~
耶瑟儿~ 2020-12-23 11:50

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 Open

相关标签:
5条回答
  • 2020-12-23 12:22

    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 );
    
    0 讨论(0)
  • 2020-12-23 12:23

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

    Computing the matrix

    This snippet of code is based on the gluPerspective documentation.

     void BuildPerspProjMat(float *m, float fov, float aspect,
     float znear, float zfar)
     {
      float f = 1/tan(fov * PI_OVER_360);
    
      m[0]  = f/aspect;
      m[1]  = 0;
      m[2]  = 0;
      m[3]  = 0;
    
      m[4]  = 0;
      m[5]  = f;
      m[6]  = 0;
      m[7]  = 0;
    
      m[8]  = 0;
      m[9]  = 0;
      m[10] = (zfar + znear) / (znear - zfar);
      m[11] = -1;
    
      m[12] = 0;
      m[13] = 0;
      m[14] = 2*zfar*znear / (znear - zfar);
      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;
    }
    
    0 讨论(0)
  • 2020-12-23 12:24

    Use GLM.

    glm::mat4 projection = glm::perspective(
      // FOV & aspect
      60.0f, 16.0f / 10.0f, 
      // Near and far planes
      0.001f, 1000f);
    
    // If you're using the now deprecated matrix stacks
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(glm::value_ptr(projection));
    
    // if you're using the new shader based pipelines
    GLint projectionUniformLocation = ...;
    glUniformMatrix4fv(projectionUniformLocation, 1, GL_FALSE, 
      glm::value_ptr(projection));
    

    Note, if you have GLM_FORCE_RADIANS defined then you should use radians in the perspective function, not degrees...

    glm::mat4 projection = glm::perspective(
      // FOV & aspect
      PI / 3.0f, 16.0f / 10.0f, 
      // Near and far planes
      0.001f, 1000f);
    
    0 讨论(0)
  • 2020-12-23 12:25

    The formula for various perspective matrices is documented in the Direct3D documentation.

    Here is the formulation for D3DXMatrixPerspectiveFovRH, the right-handed perspective projection matrix:

    yScale = cot(fovY/2)
    xScale = yScale / aspect ratio
    
    xScale     0          0              0
    0        yScale       0              0
    0        0        zf/(zn-zf)        -1
    0        0        zn*zf/(zn-zf)      0
    
    0 讨论(0)
  • 2020-12-23 12:26

    This is a modified version of Dan's function, with simplified calculations from Unspecified Behavior.

    void buildPerspProjMat(GLfloat *m, GLfloat fov, GLfloat aspect,
    GLfloat znear, GLfloat zfar){
    
      GLfloat h = tan(fov);
      GLfloat w = h / aspect;
      GLfloat depth = znear - zfar;
      GLfloat q = (zfar + znear) / depth;
      GLfloat qn = 2 * zfar * znear / depth;
    
      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;
    }
    
    0 讨论(0)
提交回复
热议问题