通过将近剪裁平面设置为1来固定,而不是0(不确定为什么它开始时)。请参阅骨架代码的问题,以及Adrian对其工作原理和原因的回答。
我有几个不同的相机位置,我的场景由一个四边形组成。
四边形是精确投影到第一帧中的视口/窗口。我想将纹理从这个相机位置投射到四边形上。纹理也完全覆盖了视口。
我做的第一件事是
// GL_QUADS...
glTexCoord2f( /*one corner of s,t space*/);
glVertex3f(/* appropriate vertex */);;
并最终得到类似(图片不是我的)
的内容然后我意识到是的,当然,它需要是一个投射转换。根据{{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
答案 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 转换,从标准化设备坐标转换为纹理空间。