2011-05-18 96 views
2

我总得有类似这样的帖子一个问题: glTexGen in OpenGL ES 2.0问题glTexGen中的Open GL ES 2.0

我抬头网站一对夫妇的其他网站上没有找到如何解决我的问题。

基本上,我想在建立正交投影后将纹理映射到2D四边形上。我的问题是,纹理被扭曲,你可以在这张照片,我用的彩色图案,而不是一个质地看:

enter image description here

我想纹理的线条留直上四,但正如你所看到的,他们是扭曲的。我想我应该修改顶点着色器为了纹理坐标来映射四边形,但我不知道如何。

非常感谢, 吉姆

回答

1

你需要的是一个不同类型的插值(我相信这将是二次插值),因为在这种情况下(在太空边缘长度不与纹理边长对应),线性插值不会削减它。

不幸的是,在OpenGL中执行任务非常复杂(尽管使用软件光栅化非常简单)。您正试图在屏幕空间中找到任意四边形的变换到纹理空间中的单位正方形上。你可以在这里找到你的问题的完整解决方案:http://alumni.media.mit.edu/~cwren/interpolator/这会得到一个矩阵,你需要乘以屏幕空间坐标来获得正确的纹理坐标(在片段着色器中)。因为这涉及相当讨厌的数学,我会建议一个简单的解决方案,实际上适用于简单的静态案例(需要手动调整)。在顶点着色器中计算的纹理坐标实际上只在中心边缘关闭,其余都是正确的。假设你的texcoords是(0,0),(1,0),(1,1)和(0,1),修正系数为:

u * v // for the first triangle 
(1 - u) * (1 - v) // for the second triangle 

你需要估计的修正向量,然后把它放在一起。我用一个简单的C++的OpenGL应用程序测试,我得出如下:

Vector2f ta(0, 1), tb(1, 1), tc(1, 0), td(0, 0); 
Vector2f a(-.1f, 1), b(1, .7f), c(1, .1f), d(0, 0); 
// quad texcoords and vertices 

Vector2f t_corr(-.01f, .5f); 
// correction for the above quad 

glBegin(GL_TRIANGLES); 
glMultiTexCoord2f(GL_TEXTURE1, 1, -1); // first triangle 
glTexCoord4f(ta.x, ta.y, t_corr.x, t_corr.y); 
glVertex2f(a.x, a.y); 
glTexCoord4f(tb.x, tb.y, t_corr.x, t_corr.y); 
glVertex2f(b.x, b.y); 
glTexCoord4f(tc.x, tc.y, t_corr.x, t_corr.y); 
glVertex2f(c.x, c.y); 

glMultiTexCoord2f(GL_TEXTURE1, 0, 1); // second triangle 
glTexCoord4f(ta.x, ta.y, t_corr.x, t_corr.y); 
glVertex2f(a.x, a.y); 
glTexCoord4f(tc.x, tc.y, t_corr.x, t_corr.y); 
glVertex2f(c.x, c.y); 
glTexCoord4f(td.x, td.y, t_corr.x, t_corr.y); 
glVertex2f(d.x, d.y); 
glEnd(); 

和顶点着色器看起来是这样的:

void main() 
{ 
    gl_Position = ftransform(); 
    gl_FrontColor = gl_Color; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    gl_TexCoord[1] = gl_MultiTexCoord1; // just copy coords, nothing else to do 
} 

片段着色器:

uniform sampler2D sam; 
void main() 
{ 
    vec2 corr = vec2(gl_TexCoord[1].x + gl_TexCoord[1].y * gl_TexCoord[0].x, 
        gl_TexCoord[1].x + gl_TexCoord[1].y * gl_TexCoord[0].y); 
    gl_FragColor = texture2D(sam, gl_TexCoord[0].xy + gl_TexCoord[0].zw * corr.x * corr.y); 
} 

这是非常简单的,但通过适当地调整校正矢量,可以使其成为:http://www.luki.webzdarma.cz/up/deskew.png

另一种选择是在3D中使用真正的四边形进行此操作,并将其手动旋转至如此的位置以使其看起来像您的2D四边形。或为您的四边形设计“深度”纹理坐标,在顶点着色器中计算1 /深度,插入(u /深度,v /深度,1 /深度),然后在片段着色器中用插值1 /深度除以得到好的值。虽然这看起来很简单,但请注意,想出良好的深度值是非常困难的。

+0

感谢您有关如何获得预期结果的非常详细的答案。 – JimN 2012-01-23 08:33:26