opengl - 如何在没有 gluUnProject 的情况下在现代 OpenGL 中进行选择?

标签 opengl opentk mouse-picking

在不使用 gluUnProject 的情况下,如何在现代 OpenGL 中将屏幕坐标转换为世界坐标?

最佳答案

AFAIK - gluUnproject 需要提供给它的所有信息(模型 View 、投影等),它只执行矩阵求逆计算。因此,如果您有这些矩阵,您可以调用 gluUnproject 或自己执行这些计算。

下面的代码取自 here (复制过来以便如果链接失效,这个答案仍然有效)。

int glhUnProjectf(float winx, float winy, float winz, float *modelview, float *projection, int *viewport, float *objectCoordinate)
  {
      // Transformation matrices
      float m[16], A[16];
      float in[4], out[4];
      // Calculation for inverting a matrix, compute projection x modelview
      // and store in A[16]
      MultiplyMatrices4by4OpenGL_FLOAT(A, projection, modelview);
      // Now compute the inverse of matrix A
      if(glhInvertMatrixf2(A, m)==0)
         return 0;
      // Transformation of normalized coordinates between -1 and 1
      in[0]=(winx-(float)viewport[0])/(float)viewport[2]*2.0-1.0;
      in[1]=(winy-(float)viewport[1])/(float)viewport[3]*2.0-1.0;
      in[2]=2.0*winz-1.0;
      in[3]=1.0;
      // Objects coordinates
      MultiplyMatrixByVector4by4OpenGL_FLOAT(out, m, in);
      if(out[3]==0.0)
         return 0;
      out[3]=1.0/out[3];
      objectCoordinate[0]=out[0]*out[3];
      objectCoordinate[1]=out[1]*out[3];
      objectCoordinate[2]=out[2]*out[3];
      return 1;
  }

  void MultiplyMatrices4by4OpenGL_FLOAT(float *result, float *matrix1, float *matrix2)
  {
    result[0]=matrix1[0]*matrix2[0]+
      matrix1[4]*matrix2[1]+
      matrix1[8]*matrix2[2]+
      matrix1[12]*matrix2[3];
    result[4]=matrix1[0]*matrix2[4]+
      matrix1[4]*matrix2[5]+
      matrix1[8]*matrix2[6]+
      matrix1[12]*matrix2[7];
    result[8]=matrix1[0]*matrix2[8]+
      matrix1[4]*matrix2[9]+
      matrix1[8]*matrix2[10]+
      matrix1[12]*matrix2[11];
    result[12]=matrix1[0]*matrix2[12]+
      matrix1[4]*matrix2[13]+
      matrix1[8]*matrix2[14]+
      matrix1[12]*matrix2[15];
    result[1]=matrix1[1]*matrix2[0]+
      matrix1[5]*matrix2[1]+
      matrix1[9]*matrix2[2]+
      matrix1[13]*matrix2[3];
    result[5]=matrix1[1]*matrix2[4]+
      matrix1[5]*matrix2[5]+
      matrix1[9]*matrix2[6]+
      matrix1[13]*matrix2[7];
    result[9]=matrix1[1]*matrix2[8]+
      matrix1[5]*matrix2[9]+
      matrix1[9]*matrix2[10]+
      matrix1[13]*matrix2[11];
    result[13]=matrix1[1]*matrix2[12]+
      matrix1[5]*matrix2[13]+
      matrix1[9]*matrix2[14]+
      matrix1[13]*matrix2[15];
    result[2]=matrix1[2]*matrix2[0]+
      matrix1[6]*matrix2[1]+
      matrix1[10]*matrix2[2]+
      matrix1[14]*matrix2[3];
    result[6]=matrix1[2]*matrix2[4]+
      matrix1[6]*matrix2[5]+
      matrix1[10]*matrix2[6]+
      matrix1[14]*matrix2[7];
    result[10]=matrix1[2]*matrix2[8]+
      matrix1[6]*matrix2[9]+
      matrix1[10]*matrix2[10]+
      matrix1[14]*matrix2[11];
    result[14]=matrix1[2]*matrix2[12]+
      matrix1[6]*matrix2[13]+
      matrix1[10]*matrix2[14]+
      matrix1[14]*matrix2[15];
    result[3]=matrix1[3]*matrix2[0]+
      matrix1[7]*matrix2[1]+
      matrix1[11]*matrix2[2]+
      matrix1[15]*matrix2[3];
    result[7]=matrix1[3]*matrix2[4]+
      matrix1[7]*matrix2[5]+
      matrix1[11]*matrix2[6]+
      matrix1[15]*matrix2[7];
    result[11]=matrix1[3]*matrix2[8]+
      matrix1[7]*matrix2[9]+
      matrix1[11]*matrix2[10]+
      matrix1[15]*matrix2[11];
    result[15]=matrix1[3]*matrix2[12]+
      matrix1[7]*matrix2[13]+
      matrix1[11]*matrix2[14]+
      matrix1[15]*matrix2[15];
  }

关于opengl - 如何在没有 gluUnProject 的情况下在现代 OpenGL 中进行选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17193703/

相关文章:

未绘制每个顶点的 C++ OpenGL 颜色

wpf - OpenTK、SharpGL 和 WPF

c# - OpenTK - 如何按给定角度旋转对象

c# - OpenTK 中的 Sprite Sheet 动画

c++ - 确定鼠标指向的对象是什么?

opengl - 如何使用多采样帧缓冲区在 OpenGL 中选择几何体?

OpenGL鼠标选取策略

c++ - GLSL语法问题: unexpected NEW_IDENTIFIER

c++ - 动态 2d 阴影 - 混合问题

OpenGL 360 度透视