平铺+ OpenGL纹理翻转

时间:2015-10-22 01:41:54

标签: c++ opengl

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

SDL2 rendering

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

OpenGL with no texture flipping

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

OpenGL with texture flipped

我应该在哪里用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 ;

1 个答案:

答案 0 :(得分:0)

如果我没有正确理解问题,请忽略这篇文章。如果我正确地理解了问题,而不是在工作代码中调整现成的图形和计算,我会改变OpenGL透视转换以匹配SDL。 OpenGL对坐标系没有任何偏好,因此您可以自由调整它以适合您的目的。

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

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()。

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

编辑:以防万一...你可以更加调整透视转换,以适应更好的基于平铺的2D游戏。让我们说你的对象的“单位大小”就像是32x32(精灵,背景瓷砖等)。摆脱sprite width&amp;的乘法和除法。 length(将地图数组索引转换为屏幕坐标,反之亦然),只需将坐标“单位大小”与切片大小匹配:

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位图blit到窗口,您可以使用以下两个三角形构建的跟随矩形:

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),“参考”点也可以更改为居中。此外:您可以使用“unitbox”(0,0) - (1,1)或(-0.5,-05) - (0.5,0.5),并使用传递给着色器的模型矩阵将其缩放到正确的尺寸。这使您可以轻松地使用相同的框来以任何尺寸进行blit纹理。

如果你不喜欢改变透视,你也可以通过将你使用的矩形翻转为“倒置”来进行翻转,并将位置缩小到32 /宽度和32 /高度(例如在模型矩阵中) 。这会影响缠绕,因此您可能需要调整面部剔除参数(glCullFace,glFrontFace,glPolygonMode)。

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