Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl透视失真_Opengl_Textures_Perspective_Distortion - Fatal编程技术网

Opengl透视失真

Opengl透视失真,opengl,textures,perspective,distortion,Opengl,Textures,Perspective,Distortion,我有一个奇怪的问题,我希望有人能帮我澄清这一点,这样我就可以理解什么是错的,并采取相应的行动。在OpenGL(固定函数)中,我在正交投影中渲染具有内表面的管 下图显示了结果。它由4个顶点环组成,这些顶点使用左侧显示的索引模式形成三角形。为了方便起见,我对管上的顶点进行了编号。右侧是正在使用的纹理: 如您所见,纹理正在严重扭曲。当我最初创建只有两个顶点环的管状体时,我认为增加环的数量可以修复扭曲,但没有乐趣。而且glHint似乎不会影响这个特定问题 纹理坐标看起来不错。此外,棋盘格图案似乎渲染正

我有一个奇怪的问题,我希望有人能帮我澄清这一点,这样我就可以理解什么是错的,并采取相应的行动。在OpenGL(固定函数)中,我在正交投影中渲染具有内表面的管

下图显示了结果。它由4个顶点环组成,这些顶点使用左侧显示的索引模式形成三角形。为了方便起见,我对管上的顶点进行了编号。右侧是正在使用的纹理:

如您所见,纹理正在严重扭曲。当我最初创建只有两个顶点环的管状体时,我认为增加环的数量可以修复扭曲,但没有乐趣。而且glHint似乎不会影响这个特定问题

纹理坐标看起来不错。此外,棋盘格图案似乎渲染正确,但我猜失真只是在非常特定的图案中不可见

请忽略交叉线,因为其中一条是不存在的边;我通过GL_LINE_LOOP渲染线框。

尝试一些细分:

template< typename Vec >
void glVec2d( const Vec& vec )
{
    glVertex2f( static_cast<float>( vec.x() ) , static_cast<float>( vec.y() ) );
}

template< typename Vec >
void glTex2d( const Vec& vec )
{
    glTexCoord2f( static_cast<float>( vec.x() ) , static_cast<float>( vec.y() ) );
}

template< typename Vec > 
void glQuad
    (
    const Vec& A,
    const Vec& B,
    const Vec& C,
    const Vec& D,
    unsigned int divs = 2,
    const Vec& At = Vec(0,0),
    const Vec& Bt = Vec(1,0),
    const Vec& Ct = Vec(1,1),
    const Vec& Dt = Vec(0,1)
    )
{
    // base case
    if( divs == 0 )
    {
        glTex2d( At );
        glVec2d( A );

        glTex2d( Bt );
        glVec2d( B );

        glTex2d( Ct );
        glVec2d( C );

        glTex2d( Dt );
        glVec2d( D );

        return;
    }

    Vec AB = (A+B) * 0.5;
    Vec BC = (B+C) * 0.5;
    Vec CD = (C+D) * 0.5;
    Vec AD = (A+D) * 0.5;
    Vec ABCD = (AB+CD) * 0.5;

    Vec ABt = (At+Bt) * 0.5;
    Vec BCt = (Bt+Ct) * 0.5;
    Vec CDt = (Ct+Dt) * 0.5;
    Vec ADt = (At+Dt) * 0.5;
    Vec ABCDt = (ABt+CDt) * 0.5;

    // subdivided point layout
    // D   CD   C
    // 
    // AD ABCD BC 
    //
    // A   AB   B

    // subdivide
    glQuad2d( A, AB, ABCD, AD, divs - 1, At, ABt, ABCDt, ADt );
    glQuad2d( AB, B, BC, ABCD, divs - 1, ABt, Bt, BCt, ABCDt );
    glQuad2d( ABCD, BC, C, CD, divs - 1, ABCDt, BCt, Ct, CDt );
    glQuad2d( AD, ABCD, CD, D, divs - 1, ADt, ABCDt, CDt, Dt );
}
template
无效glVec2d(常量向量和向量)
{
glVertex2f(静态_转换(vec.x())、静态_转换(vec.y());
}
模板
void glTex2d(常量向量和向量)
{
glTexCoord2f(静态_转换(vec.x())、静态_转换(vec.y());
}
模板
虚空glQuad
(
康斯特维卡酒店,
康斯特维克酒店,
const Vec&C,
康斯特维科与发展公司,
无符号整数divs=2,
常数Vec&At=Vec(0,0),
常数Vec&Bt=Vec(1,0),
常数Vec&Ct=Vec(1,1),
常数Vec&Dt=Vec(0,1)
)
{
//基本情况
如果(divs==0)
{
glTex2d(At);
glVec2d(A);
glTex2d(Bt);
glVec2d(B);
glTex2d(Ct);
glVec2d(C);
glTex2d(Dt);
glVec2d(D);
返回;
}
向量AB=(A+B)*0.5;
Vec-BC=(B+C)*0.5;
向量CD=(C+D)*0.5;
Vec AD=(A+D)*0.5;
向量ABCD=(AB+CD)*0.5;
Vec ABt=(At+Bt)*0.5;
Vec BCt=(Bt+Ct)*0.5;
Vec-CDt=(Ct+Dt)*0.5;
Vec ADt=(At+Dt)*0.5;
Vec ABCDt=(ABt+CDt)*0.5;
//细分点布局
//D CD C
// 
//公元前ABCD
//
//A AB B
//细分
glQuad2d(A、AB、ABCD、AD、divs-1、At、ABt、ABCDt、ADt);
glQuad2d(AB、B、BC、ABCD、divs-1、ABt、Bt、BCt、ABCDt);
glQuad2d(ABCD、BC、C、CD、divs-1、ABCDt、BCt、Ct、CDt);
glQuad2d(AD、ABCD、CD、D、divs-1、ADt、ABCDt、CDt、Dt);
}

我通常使用
Vec

这种特殊效果是由在三角形中插值纹理坐标的方式引起的。发生的情况是,一个方向成为主要组件,而另一个方向是倾斜的。你的标本碰巧很容易发生这种情况。这也是地板或墙上透视投影和纹理的问题。您需要的是所谓的“透视正确纹理”PCT。有一个
glHint
用于此,但我想,您已经尝试过了

坦率地说,避免这种情况的唯一方法是细分并应用透视校正。但幸运的是,这对于基于四边形的geoemtry(像您的一样)来说足够简单。细分边时,沿所有4条边在细分中心对纹理坐标进行插值,并使用其中4条边的平均值。仅沿一条边插值纹理坐标正是您想要避免的


如果要保持几何体数据不变,可以在片段着色器中实现PCT。

为什么要为此使用正交投影?如果您使用透视投影,OpenGL将为您校正纹理贴图。

当我尝试添加更多环时,我没有尝试为每个环添加更多顶点,这解决了问题。因此,细分确实是一条出路。谢谢这可能是因为您使用的是正交投影吗?