在OpenGL中投射纹理
通过将裁剪平面设置为1而不是0来固定(不知道为什么它是这样开始的)。 查看关于框架代码的问题,以及Adrian关于如何以及为何运作的答案。
我有几个不同的摄像头位置,我的场景由一个四边形组成。
四边形是这样的,它正好投影到第一帧的视口/窗口上。 我想从这个相机位置投影到四边形上。 纹理也完全覆盖视口。
我做的第一件事是
// GL_QUADS...
glTexCoord2f( /*one corner of s,t space*/);
glVertex3f(/* appropriate vertex */);;
并最终以类似的东西(图片不是我的)
然后我意识到是的,当然,它需要是一个投影转换。 根据这些笔记:
现在它起作用了,下面是代码的粗略实现:
// 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
看看glTexGen的文档(在你的情况下,你想要使用GL_EYE_LINEAR
和适当的一组系数,如下所述)和glEnable( GL_TEXTURE_GEN_*
)。 当为特定的纹理坐标组件(S,T,R和/或Q)启用texgen功能时,您为这些组件指定的值(通过glTexCoord
)将被忽略,并且纹理坐标将根据指定的glTexGen
模式生成。
当通过GL_EYE_LINEAR
计算纹理坐标时,首先通过当前GL_MODELVIEW
矩阵将顶点坐标转换为眼图空间。 一旦在眼睛空间中,对于每个启用的分量(S,T,R,Q),顶点坐标由在调用glTexGen
时定义的GL_MODELVIEW
矩阵的逆来glTexGen
,并且所得到的坐标然后获得发送给glTexGen
的系数。 对于每个启用的组件,得到的标量值将成为纹理坐标的相应分量(S,T,R和/或Q),最终由GL_TEXTURE
矩阵进行变换,以生成最终的纹理坐标。
对于每个纹理分量,发送给glTexGen
的系数(a,b,c,d)定义一个平面ax + by + cz + d = 0。假设(a,b,c)是单位长度的向量,上述点积操作表示该平面与正在处理的顶点之间的距离。 如果对所有四个纹理分量都启用了GL_EYE_LINEAR
,并且S,T,R和Q的平面方程分别定义为( GL_EYE_LINEAR
),(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_TEXTURE
矩阵应包含将这些坐标从对象空间转换为纹理空间所需的任何操作:建模,查看和投影转换以将对象坐标转换为标准化的设备坐标,以及将标准化设备坐标转换为标尺和偏移转换纹理空间。