且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

纹理显示不正确 - 可能坐标错误OpenGL,C ++

更新时间:2022-10-22 12:01:48

罪魁祸首就是你没有在texel中心抽样。例如,如果您的像素纹理为32x32像素,则纹理中心会偏移1/64。



下面是4x4纹理的粗略图。正方形是图像的纹理像素(或像素)。

 
_________________ 1,1
| | | | |
| | | | |
| ___ | ___ | ___ | ___ | _0.75
| | | | |
| | | | |
| ___ | ___ | ___ | ___ | _0.5
| | | | |
| | | | |
| ___ | ___ | ___ | ___ | _0.25
| | | | |
| X | | | |
| ___ | ___ | ___ | ___ |
0,0 | 0.5 | 1
0.25 0.75

x =(0.125,0.125)

如果您抽样在其中一行上,您将得到一个恰好在两个纹素之间的值,这将会(如果您将纹理采样设置为线性混合)给您一个平均值。如果你想采样确切的texel值,你需要在texel的中心指定一个u,v。


I'll try to explain my problem with images. So this is a test texture I'm using for my OpenGL application:

As you can see, there is a 2-pixels wide border around the image with different colors for me to be able to see if coordinates are properly set in my application.

I'm using a 9-cell pattern so I'm drawing 9 quads with specific texture coordinates. At first sight everything works fine, but there is a small problem with displaying a texture:

In the picture I marked where is first quad, and where is the second one. As you can see, first one is displayed correctly, but second one smoothly goes from first quad's colors to it's own, but it should start with pure green and pink. So I'm guessing it's a problem with texture coordinates.

This is how they are set:

// Bottom left quad [1st quad]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(0.0f, 1.0);                
    glVertex2i(pos.x, pos.y + height);

    // Top left
    glTexCoord2f(0.0f, (GLfloat)1.0 - maxTexCoordBorderY);  
    glVertex2i(pos.x, pos.y + height - m_borderWidth);

    // Top right
    glTexCoord2f(maxTexCoordBorderX, (GLfloat)1.0 - maxTexCoordBorderY);
    glVertex2i(pos.x + m_borderWidth, pos.y + height - m_borderWidth);

    // Bottom right
    glTexCoord2f(maxTexCoordBorderX, 1.0);
    glVertex2i(pos.x + m_borderWidth, pos.y + height);
glEnd();

// Bottom middle quad [2nd quad]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(maxTexCoordBorderX, 1.0);          
    glVertex2i(pos.x + m_borderWidth, pos.y + height);

    // Top left
    glTexCoord2f(maxTexCoordBorderX, (GLfloat)1.0 - maxTexCoordBorderY);
    glVertex2i(pos.x + m_borderWidth, pos.y + height - m_borderWidth);

    // Top right
    glTexCoord2f((GLfloat)1.0 - maxTexCoordBorderX, (GLfloat)1.0 - maxTexCoordBorderY);
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height - m_borderWidth);

    // Bottom right
    glTexCoord2f((GLfloat)1.0 - maxTexCoordBorderX, 1.0);   
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height);
glEnd();

You can see that I'm using maxTexCoordBorderX variable which is calculated based on border and image size. Image width is 32 and border width is 2.

maxTexCoordBorderX = 2 / 32 = 0.0625

Could anyone please help with with finding out where the problem is?

Most likely culprit is that you are not sampling on the texel centers. For example, if you have a 32x32 pixel texture, the texel-centers are offset by 1/64.

Here's a rough diagram of a 4x4 texture. The squares are the texels (or pixels) of the image.

_________________1,1
|   |   |   |   |
|   |   |   |   |
|___|___|___|___|_0.75
|   |   |   |   |
|   |   |   |   |
|___|___|___|___|_0.5
|   |   |   |   |
|   |   |   |   |
|___|___|___|___|_0.25
|   |   |   |   |
| X |   |   |   |
|___|___|___|___|
0,0 |  0.5  |   1
   0.25    0.75

x = (0.125, 0.125)

If you sample on one of the lines, you will get a value exactly between two texels, which will (if you have texture sampling set to linear blend) give you an average value. If you want to sample the exact texel value, you need to specify a u,v in the center of the texel.