在OpenGL中投影纹理

时间:2010-09-03 01:03:01

标签: c++ opengl 3d graphics

通过将近剪裁平面设置为1来固定,而不是0(不确定为什么它开始时)。请参阅骨架代码的问题,以及Adrian对其工作原理和原因的回答。

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

四边形是精确投影到第一帧中的视口/窗口。我想将纹理从这个相机位置投射到四边形上。纹理也完全覆盖了视口。

我做的第一件事是

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

并最终得到类似(图片不是我的)alt text

的内容

然后我意识到是的,当然,它需要是一个投射转换。根据{{​​3}}:

  1. 用于定向场景中投影的模型视图变换。
  2. 投影变换(透视或正交)。
  3. 将近剪裁平面映射到纹理坐标的比例和偏差。
  4. 现在它起作用了,这是代码的粗略实现:

    // 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 个答案:

答案 0 :(得分:4)

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

通过glTexGen计算纹理坐标时,首先通过当前GL_EYE_LINEAR矩阵将顶点坐标转换为眼睛空间。一旦进入眼睛空间,对于每个启用的分量(S,T,R,Q),顶点坐标通过调用GL_MODELVIEW时定义的GL_MODELVIEW矩阵的逆变换,然后获得结果坐标和发送到glTexGen的系数之间的点积。对于每个启用的组件,生成的标量值将成为纹理坐标的相应组件(S,T,R和/或Q),最终由glTexGen矩阵转换以生成最终纹理坐标。

对于每个纹理分量,发送到GL_TEXTURE的系数(a,b,c,d)定义平面ax + + + cz + d = 0.假设(a,b,c)是矢量在单位长度上,上述点积运算的结果表示该平面与正在处理的顶点之间的距离。如果为所有四个纹理分量启用glTexGen,则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),为每个纹理组件生成的纹理坐标与原始对象空间顶点坐标完全相同。因此,GL_EYE_LINEAR矩阵应包含将这些坐标从对象空间转换为纹理空间所需的任何操作:建模查看投影转换为从对象坐标转换为规范化设备坐标,再加上 scale bias 转换,从标准化设备坐标转换为纹理空间。