sf::Texture被错误地应用了

14

在我的2D等距引擎中,我有以下类:

maps(variable)/layers(variable)/cubes(variable)/sides(6)/points(4)/coordinates(3)

在这里输入图片描述

  • 每个立方体有6个面,每个面有4个点(1个点=1个坐标(x,y,z))。
  • 我可以用同样大小的立方体创建任意大小的地图。

文件夹:

assets/numTexture/numLight.png

我使用numTexture和numLight计算一个数字,该数字是我在数组中加载的所有numLight.png(纹理)的纹理编号。

但是纹理出现了问题:

enter image description here

我在层类中定义我的立方体坐标:

for(int J = 0; J < mapSize; J++)
{
    for(int I = 0; I < mapSize; I++)
    {
        x = (J - I) * (cubeSize/2);
        y = (J + I) * (cubeSize/4);

        c = new cube(cubeSize, x, y, z, I, J);
        cs.push_back(*c);
    }
}

在side.cpp文件中,我使用了一个关于sideType的switch语句(如果它是顶部、左侧等,则会定义我的点的坐标不同)。 对于每个立方体,我有6个这样的switch语句(这里只提供数据)。

就像这样:

    switch(typeSide)
        {
            case 0://DOWN_SIDE
                light = 0;
    
                tmp_x = x + (size/2);
                tmp_y = y + (size/2);
                p0 = new point(tmp_x, tmp_y, tmp_z);
    
                tmp_x = x + size;
                tmp_y = y + (3 * (size/4));
                p1 = new point(tmp_x, tmp_y, tmp_z);
    
                tmp_x = x + (size/2);
                tmp_y = y + size;
                p2 = new point(tmp_x, tmp_y, tmp_z);
    
                tmp_x = x;
                tmp_y = y + (3 * (size/4));
                p3 = new point(tmp_x, tmp_y, tmp_z);
                break;

//ETC. ....

还有一个显示地图的 display() 函数:

void GRAPHICS_HANDLER::display()
{
    x = 0;
    y = 0;

    if(maps.size() > 0 && maps[0].layers().size() > 0)//If there is any map and layers to display
    {
        for(int l = 0; l <= getCurrentLayerID(); l++)//FOR EACH LAYER, WE STOP TO THE CURRENT EDITED LAYER
        {
            for(unsigned int c = 0; c < maps[currentMapID].layers()[l].cubes().size(); c++)//FOR EACH CUBES
            {
                if(maps[currentMapID].layers()[l].cubes()[c].getFlat())//If flat mode is enabled: to draw texture like grass, etc...(cf. screen): We draw only one side
                {
                    for(unsigned int p = 0; p < 4; p++)//FOR EACH POINTS
                    {
//--------------------------------------------------------------------------------------LOAD MAP-----------------------------------------------------------------------------------------------------------//
//--------------------------------------------------------------------------CUBE CLICK DETECTION::TEXTURE CHANGE--------------------------------------------------//
                        if(cubeClicked || brushMode && currentSelectedCube > -1 && currentSelectedCube < maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes().size())
                        {
                            maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes()[currentSelectedCube].setTexture(currentSelectedTexture);

                            if(!brushMode)
                                cubeClicked = false;
                        }
//--------------------------------------------------------------------------CUBE CLICK DETECTION::TEXTURE CHANGE--------------------------------------------------//
//--------------------------------------------------------------------------------------CURSOR - NOT WORKING-----------------------------------------------------------------------------------------------------------------//
                        //...
//--------------------------------------------------------------------------------------CURSOR - NOT WORKING-----------------------------------------------------------------------------------------------------------------*/

                        if(enableOffset)
                        {
                            x = maps[currentMapID].layers()[l].cubes()[c].sides()[0]->pointPosition(p)[0] + offsetLeft;//it's like doing something like point[p].x + offset left
                            y = maps[currentMapID].layers()[l].cubes()[c].sides()[0]->pointPosition(p)[1] + offsetTop;
                        }
                        else
                        {
                            x = maps[currentMapID].layers()[l].cubes()[c].sides()[0]->pointPosition(p)[0];//it's like doing something like point[p].x + offset left
                            y = maps[currentMapID].layers()[l].cubes()[c].sides()[0]->pointPosition(p)[1];
                        }

                        points[p].position = sf::Vector2f(x, y);
                        points[p].texCoords = sf::Vector2f(x, y);

//--------------------------------------------------------------------------------------GRID-----------------------------------------------------------------------------------------------------------------//
                        //GRID DISPLAY //MISS AN EDGE .
                        isoGrid[p].position = points[p].position;
                        isoGrid[p].color = sf::Color(195, 195, 195, gridOpacity);
//--------------------------------------------------------------------------------------GRID-----------------------------------------------------------------------------------------------------------------//

                        maps[currentMapID].layers()[l].cubes()[c].sides()[0]->setLight(5);
                        textureEntryNumber = (maps[currentMapID].layers()[l].cubes()[c].sides()[0]->getTexture() - 1) * 9 + (maps[currentMapID].layers()[l].cubes()[c].sides()[0]->getLight() - 1);//WRONG
//--------------------------------------------------------------------------------------GRID-----------------------------------------------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------LOAD MAP-----------------------------------------------------------------------------------------------------------//
                    }
//--------------------------------------------------------------------------------------DISPLAY MAP-----------------------------------------------------------------------------------------------------------//
                    if(grid && maps[currentMapID].layers()[l].cubes()[c].sides()[0]->getTexture() <= 1)//IF GRID = TRUE OR TEXTURE LESS OR EQUAL TO 1 => DISPLAY GRID
                    {
                        if(l == maps[currentMapID].currentLayerId())
                        {
                            window->draw(isoGrid);
                        }
                    }
                    else if(maps[currentMapID].layers()[l].cubes()[c].sides()[0]->getTexture() > 1)//IF THERE IS ANY TEXTURE TO DISPLAY(>1) => DISPLAY TEXTURE
                    {
                        window->draw(points, &textures[textureEntryNumber]);
                    }
//--------------------------------------------------------------------------------------DISPLAY MAP-----------------------------------------------------------------------------------------------------------//
                }
                else
                {
                    for(unsigned int s = 0; s < 6; s++)//FOR EACH SIDES(side number will always be 6, no need to make this dynamic
                    {
                        for(unsigned int p = 0; p < 4; p++)//FOR EACH POINTS
                        {
//--------------------------------------------------------------------------------------LOAD MAP-----------------------------------------------------------------------------------------------------------//
//--------------------------------------------------------------------------CUBE CLICK DETECTION::TEXTURE CHANGE--------------------------------------------------//
                            if(cubeClicked || brushMode && currentSelectedCube > -1 && currentSelectedCube < maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes().size())
                            {
                                maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes()[currentSelectedCube].setTexture(currentSelectedTexture);

                                if(flatMode)
                                    maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes()[currentSelectedCube].setFlat(true);
                                else
                                    maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes()[currentSelectedCube].setFlat(false);


                                if(!brushMode)
                                    cubeClicked = false;
                            }
//--------------------------------------------------------------------------CUBE CLICK DETECTION::TEXTURE CHANGE--------------------------------------------------//
//--------------------------------------------------------------------------------------CURSOR - NOT WORKING-----------------------------------------------------------------------------------------------------------------//
                            //...
//--------------------------------------------------------------------------------------CURSOR - NOT WORKING-----------------------------------------------------------------------------------------------------------------*/

                            if(enableOffset)
                            {
                                x = maps[currentMapID].layers()[l].cubes()[c].sides()[s]->pointPosition(p)[0] + offsetLeft;//it's like doing something like point[p].x + offset left
                                y = maps[currentMapID].layers()[l].cubes()[c].sides()[s]->pointPosition(p)[1] + offsetTop;
                            }
                            else
                            {
                                x = maps[currentMapID].layers()[l].cubes()[c].sides()[s]->pointPosition(p)[0];//it's like doing something like point[p].x + offset left
                                y = maps[currentMapID].layers()[l].cubes()[c].sides()[s]->pointPosition(p)[1];
                            }

                            points[p].position = sf::Vector2f(x, y);
                            points[p].texCoords = sf::Vector2f(x, y);

//--------------------------------------------------------------------------------------GRID-----------------------------------------------------------------------------------------------------------------//
                            //GRID DISPLAY //MISS AN EDGE
                            if(s ==3)
                            {
                                isoGrid[p].position = points[p].position;
                                isoGrid[p].color = sf::Color(195, 195, 195, gridOpacity);
                            }
//--------------------------------------------------------------------------------------GRID-----------------------------------------------------------------------------------------------------------------//

                            textureEntryNumber = (maps[currentMapID].layers()[l].cubes()[c].sides()[s]->getTexture() - 1) * 9 + (maps[currentMapID].layers()[l].cubes()[c].sides()[s]->getLight() - 1);//WRONG
//--------------------------------------------------------------------------------------GRID-----------------------------------------------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------LOAD MAP-----------------------------------------------------------------------------------------------------------//
                        }
//--------------------------------------------------------------------------------------DISPLAY MAP-----------------------------------------------------------------------------------------------------------//
                        if(grid && maps[currentMapID].layers()[l].cubes()[c].sides()[s]->getTexture() <= 1)//IF GRID = TRUE OR TEXTURE LESS OR EQUAL TO 1 => DISPLAY GRID
                        {
                            if(l == maps[currentMapID].currentLayerId())
                            {
                                window->draw(isoGrid);
                            }
                        }
                        else if(maps[currentMapID].layers()[l].cubes()[c].sides()[s]->getTexture() > 1)//IF THERE IS ANY TEXTURE TO DISPLAY(>1) => DISPLAY TEXTURE
                        {
                            window->draw(points, &textures[textureEntryNumber]);
                        }
//--------------------------------------------------------------------------------------DISPLAY MAP-----------------------------------------------------------------------------------------------------------//
                    }
                }
            }
        }
    }

    window->display();
}

滚动此处以查看评论和标签

问题:

  • 只有具有细节的纹理才会变大,单色纹理没有问题(可能是顶点绑定在一起,即使来自不同的sf ::VertexArray 。

注意:像maps / layers / cubes等类都只是数据。

应该在屏幕上显示的Textures(numLIght)图像如下所示:enter image description hereenter image description hereenter image description here

编辑:当图片只是一种颜色而没有细节时,纹理可以工作:

enter image description here

我不再知道我的代码有什么问题了。 也许我会重新编写display()函数...


1
你如何设置纹理坐标?重复加载相同的纹理不好,但不应该引起这种问题。 - Lukas
@Lukas 我编辑了我的帖子,关于我如何设置坐标和如何显示整个内容。反复加载会导致卡顿吗? - Madz
@Lukas 感谢你,我解决了我的延迟问题,现在我明白为什么一遍又一遍地加载纹理是错误的,谢谢 :).但这并没有解决纹理问题,可能是来自顶点?也许一些点由于等距视图而连接在一起,因为立方体具有一些相同的点? - Madz
一个精心撰写的问题 Madz - Drew
1
你能试试棋盘纹理吗?这可能会给你更多的暗示发生了什么。 - mindriot
显示剩余2条评论
1个回答

3

看起来纹理坐标可能超出了纹理范围。

如果pointPosition函数是指side.cpp中的p0、p1、p2和p3点,那么你似乎也在使用这些点作为纹理坐标。

考虑如何创建一个二维正方形-

//Create a VertexArray as quads.
sf::VertexArray vertices;
vertices.setPrimitiveType(sf::Quads);
vertices.resize(4);

//The square position values (same as sf::Vertex::position).
sf::Vector2f v0 = sf::Vector2f(10,  10);
sf::Vector2f v1 = sf::Vector2f(200, 10);
sf::Vector2f v2 = sf::Vector2f(200, 200);
sf::Vector2f v3 = sf::Vector2f(10,  200);

//The texture coordinates (same as sf::Vertex::texCoords).
sf::Vector2f tv0 = sf::Vector2f(0,                 0              );
sf::Vector2f tv1 = sf::Vector2f(0+tex.getSize().x, 0              );
sf::Vector2f tv2 = sf::Vector2f(0+tex.getSize().x, tex.getSize().y);
sf::Vector2f tv3 = sf::Vector2f(0,                 tex.getSize().y);

//Put them in vertices.
vertices[0] = sf::Vertex(v0,tv0);
vertices[1] = sf::Vertex(v1,tv1);
vertices[2] = sf::Vertex(v2,tv2);
vertices[3] = sf::Vertex(v3,tv3);

方形点不必与纹理坐标相同,因为纹理坐标将伸展到每个方形点。如果您更改其中一个方形点中的一个点,则可能会看起来像这样。

之前

enter image description here

之后(v2更改为200,300)

enter image description here

我们不需要改变纹理坐标,只需改变顶点位置。
我不确定这是否完全正确,因为我看不到pointPosition是什么,但这是我最好的猜测。
此外,试图在纹理范围之外绘制可能导致图像边框像素被拉伸(可能是您示例中发生的情况),有时甚至可以显示来自视频内存中其他信息的数据,因为超出了纹理的内存。

我正在重写我的引擎,因为里面有太多问题。 我完全不知道我们不必改变纹理坐标,非常感谢你的时间! - Madz
没问题。SFML网站上还有一个不错的顶点数组教程,可能会很有用:http://www.sfml-dev.org/tutorials/2.3/graphics-vertex-array.php - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接