我正在尝试将图块渲染从SDL2转换为OpenGL。这是来自SDL2的图像;

并且使用OpenGL渲染的同一图像没有在Y轴上翻转的纹理;

这是来自OpenGL渲染的图像,纹理在Y轴上翻转了;

我应该在哪里用Y形翻转纹理补偿坐标,并使其在OpenGL坐标系中正确渲染?这是我用来获取纹理uv以在OpenGL中渲染第二张图片(纹理未翻转)和第三张图片(翻转纹理)的代码;

glm::vec4 srcRect;
srcRect.x = (float)((tileLayer->GetTileId(x, y) - (tileY * tilesPerRow))* (tileWidth+ spacing) )/imageWidth;
srcRect.y = (float)(tileY * (tileHeight + spacing)+ margin)/imageHeight;
srcRect.z = (float)tileWidth/imageWidth;
srcRect.w = (float)tileHeight/imageHeight ;

最佳答案

如果我对问题的理解不正确,请忽略此帖子。如果我正确地理解了问题,那么我将更改OpenGL透 View 转换以匹配SDL,而不是在工作代码中调整现成的图形和计算。 OpenGL对坐标系没有任何偏好,因此您可以自由调整它以适应您的目的。

我假设您正在使用现代的OpenGL(可编程着色器,没有固定的管道)和一些OpenGL数学库(例如,C++的glm)。大多数库都具有ortho()来创建具有坐标变换的正交透 View 。语法为:

glm::ortho(left, right, bottom, top, near, far)

只需翻转底部和顶部,就可以翻转y。对于2D图形,近场和远场可以关闭任何东西,因为对象的z坐标都为零:
glm::ortho(
    -1,  1,    // X goes -1 to 1
     1, -1,    // Y goes 1 (at bottom!) to -1 (at top!)
    -1, 1)     // -1 < 0 < 1

但是你会变得更好。使用窗口大小参数,然后可以使用基于像素的常规坐标(而不是-1 ... 1范围):
glm::ortho(
    0, width,   // X goes 0 to width
    height, 0,  // Y goes 0 (top) to height (bottom)
    -1, 1)      // near & far

要使用固定管线(旧的OpenGL)制作,请使用glOrtho()。

希望这是问题所在,如果是的话,希望这会有所帮助。

编辑:以防万一...您可以甚至更调整透 View 转换,以适应更好的基于图块的2D游戏。假设您的对象“单位大小”就像32x32(精灵,背景图块等)。要消除用子画面宽度和长度进行乘除(将 map 数组索引转换为屏幕坐标,反之亦然),只需将坐标“单位大小”与图块大小匹配即可:
glm::ortho(
    0, width / tile.width,    // +1 X is +tile.width
    height / tile.height, 0,  // +1 Y is +tile.height
    -1, 1)                    // near & far

编辑(请参阅评论):假设您使用ortho(0,width,height,0)来获取“传统”屏幕坐标(以像素为单位)。要将32x32位图映射到窗口,必须具有以下由两个三角形构成的矩形:
uv (0, 0)               uv( 1, 0)
pos(0, 0)              pos(32, 0)
     +-----------------+
     |A               D|
     |                 |
     |B               C|
     +-----------------+
pos(0,32)              pos(32, 32)
uv (0, 1)              uv ( 1,  1)

默认绕组为逆时针(三角形ABC,CDA)。也可以使用矩形(-16,-16)-(16,16)将“引用”点更改为中心。此外:您可以使用“单位框”(0,0)-(1,1)或(-0.5,-05)-(0.5,0.5),并使用传递给着色器的模型矩阵将其放大到正确的尺寸。这使您可以轻松地使用同一框将任何大小的纹理变薄。

如果您不希望更改视角,还可以通过翻转用于翻转的矩形来翻转(上下颠倒),然后将位置缩小到32 /宽度和32 /高度(例如,在模型矩阵中)。这会影响缠绕,因此您可能需要调整面部剔除参数(glCullFace,glFrontFace,glPolygonMode)。

但是,IMO对于2D图形调整透 View 并继续使用您以前使用的“默认”窗口坐标要方便得多。 3D方面是不同的野兽。

关于c++ - 平铺+ OpenGL纹理翻转,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33272091/

10-12 07:40
查看更多