代码之家  ›  专栏  ›  技术社区  ›  CakeMaster

在OpenGL中投影纹理

  •  7
  • CakeMaster  · 技术社区  · 16 年前

    通过将“近剪裁平面”设置为1而不是0来修复(不知道为什么要这样开始)。请参阅骨架代码的问题,以及Adrian的答案,了解这是如何工作的以及为什么工作的。

    我有几个不同的相机位置,我的场景由一个四方形组成。

    四元体可以精确地投影到第一帧中的视区/窗口上。我想把这个相机位置的纹理投射到四边形上。纹理也完全覆盖了视区。

    我做的第一件事是

    //gl_quads…
    gltexcoord2f(/*s的一角,t空格*/);
    glvertex3f(/*适当顶点*/);;
    < /代码> 
    
    

    最后得到的结果是(图片不是我的)

    然后我意识到是的,当然,它需要是一个投影的。根据These notes:

    1. 用于确定场景中投影方向的ModelView转换。
    2. 投影变换(透视或正交)。
    3. 将近剪裁平面映射到纹理坐标的比例和偏移。

    现在它工作了,下面是代码的一个粗略实现:

    在init code中 Glenable(GL_纹理_2d); gltexenff(gl_纹理_env,gl_纹理_env_模式,gl_贴花); 双比=宽度/高度; //从ModelView矩阵设置 glmatrixmode(gl_模型视图); glloadIdentity(); GluPerspective(pcam._fov/比率,比率,1,far_z); GluLookat(/*来自相机参数*/); gltexgeni(gl_q,gl_texture_gen_mode,gl_eye_linear);/s,t,r和q glfloat splane[]=1.f,0.f,0.f,0.f//s,t,r和q,对角线 gltexgenfv(gl_s,gl_eye_plane,s plane);//s,t,r和q //—加载和绑定纹理-- glenable(gl_texture_gen_s);//s、t、r和q //比例和偏差 glmatrixmode(gl_纹理); GLPASTIMEXRY(); glloadIdentity(); gltranslatef(0.5,0.5,0.0); glscalef(0.5,0.5,1); GluPerspective(凸轮视场/比率,比率,1,远视场); GluLookat(/*到相机参数*/); glbegin(gl_四边形); glvertex3f(/*表示每个顶点*/); 格兰德(); gldisable(gl_texture_gen_s);//s、t、r和q < /代码> <不知道为什么会这样。查看骨架代码的问题,以及Adrian的答案,了解这是如何工作的以及为什么工作的。

    我有几个不同的摄像机位置,我的场景由一个四方形组成。

    四元体可以精确地投影到第一帧中的视区/窗口上。我想把这个相机位置的纹理投射到四边形上。纹理也完全覆盖了视区。

    我做的第一件事是

        // GL_QUADS...
        glTexCoord2f( /*one corner of s,t space*/);
        glVertex3f(/* appropriate vertex */);;
    

    最后得到的是类似的东西(图片不是我的)alt text

    然后我意识到是的,当然,它需要投射的转型。根据these notes:

    1. 用于确定场景中投影方向的模型视图转换。
    2. 投影变换(透视或正交)。
    3. 将近剪裁平面映射到纹理坐标的比例和偏移。

    现在它工作了,下面是代码的一个粗略实现:

    // in init code
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    
    double ratio = width/height;
    
    // set up FROM modelview matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    
    gluPerspective(pcam._fov/ratio, ratio, 1, far_z);
    gluLookAt(/* FROM camera's parameters */);
    
    glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); //S, T, R and Q
    GLfloat Splane[] = {1.f, 0.f, 0.f, 0.f}; //S, T, R and Q, diagonal
    glTexGenfv(GL_S,GL_EYE_PLANE,Splane); //S, T, R and Q
    
    // -- load and bind texture --
    
    glEnable(GL_TEXTURE_GEN_S); //S, T, R and Q
    
    // scale and bias
    glMatrixMode(GL_TEXTURE);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0.5,0.5,0.0);
    glScalef(0.5,0.5,1);
    
    gluPerspective(cam._fov/ratio, ratio, 1, far_z);
    gluLookAt(/* TO camera's parameters */);
    
    glBegin(GL_QUADS);
        glVertex3f(/* for each vertex */);
    glEnd();
    glDisable(GL_TEXTURE_GEN_S); //S, T, R and Q
    
    1 回复  |  直到 12 年前
        1
  •  4
  •   Sergio Basurco    12 年前

    查看文档 glTexGen (在您的情况下,您要使用 GL_EYE_LINEAR 以及一组适当的系数(如下所述) glEnable ( GL_TEXTURE_GEN_* )为特定纹理坐标组件(S、T、R和/或Q)启用TexGen功能时,为这些组件指定的值(通过 glTexCoord )将被忽略,而纹理坐标将根据指定的 glTexGen 模式。

    当计算纹理坐标时,通过 眉毛线 ,顶点坐标首先由当前的 GL_MODELVIEW 矩阵。在眼睛空间中,对于每个启用的组件(S、T、R、Q),顶点坐标通过 GLYMyVIEW 调用时定义的矩阵 格拉金根 ,以及结果坐标和发送到的系数之间的点积 格拉金根 然后得到。对于每个启用的组件,生成的标量值将成为纹理坐标的相应组件(S、T、R和/或Q),最终由 GL_TEXTURE 生成最终纹理坐标的矩阵。

    对于每个纹理组件,将系数(a、b、c、d)发送到 格拉金根 定义一个平面ax+by+cz+d=0。假设(a,b,c)是单位长度的向量,上面描述的点积运算的结果表示这个平面和正在处理的顶点之间的距离。如果 眉毛线 为所有四个纹理组件启用,并且S、T、R和Q的平面方程分别定义为(1.0、0.0、0.0、0.0)、(0.0、1.0、0.0、0.0)、(0.0、0.0、1.0、0.0)和(0.0、0.0、0.0、1.0),然后为每个纹理组件生成的纹理坐标与原始对象空间顶点坐标完全相同。因此, 格氏织构 矩阵应包含将这些坐标从对象空间转换为纹理空间所需的任何操作: 建模 , 观看 和 投影 从对象坐标转换为标准化设备坐标的转换,加上 规模 和 偏压 从标准化设备坐标转换为纹理空间。