2015-10-22 112 views
2

我正在尝试将平铺从SDL2转换为OpenGL。这是来自SDL2的图像;平铺+ OpenGL纹理翻转

SDL2 rendering

而使用没有纹理在Y轴翻转的OpenGL呈现的相同的图像;

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 ; 
+0

如果我理解正确,那么你只有y轴的问题。尝试使用此行为y:'srcRect.y =(float)(imageHeight - tileY *(tileHeight + spacing) - margin)/ imageHeight'/ –

+0

@Danil,谢谢你的回复。我刚刚尝试了您的建议,但仍然失败(http://imgur.com/DCIrJeE.png)。 – user2924261

+0

好的,这个'srcRect.y =(float)(tileHeight - tileY *(tileHeight + spacing) - margin)/ imageHeight'或'srcRect.y =(float)tileHeight - (float)(tileY *(tileHeight +间距)+边距)/ imageHeight'? –

回答

0

如果我没有正确理解问题,请忽略此帖。如果我正确地理解了这个问题,而不是在工作代码中调整现成的图形和计算,我会改变OpenGL透视转换以匹配SDL。 OpenGL对坐标系没有任何偏好,所以你可以自由地调整它以适应你的目的。我假设你正在使用现代OpenGL(可编程着色器,无固定管道)和一些OpenGL数学库(例如用于C++的glm)。大多数图书馆都使用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(精灵,背景瓷砖等)。为了摆脱相乘,并与子画面宽度除以&长度(转换地图数组索引到屏幕坐标,并且反之亦然),只是匹配坐标“单元大小”,以平铺尺寸:

glm::ortho(
    0, width/tile.width, // +1 X is +tile.width 
    height/tile.height, 0, // +1 Y is +tile.height 
    -1, 1)     // near & far 

EDIT(见注释):让假设您使用正交(0,宽度,高度,0)以像素为单位获得“传统”屏幕坐标。到32×32的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)更改为居中。此外:您可以使用“单元箱”(0,0) - (1,1)或(-0.5,-05) - (0.5,0。5),并通过将模型矩阵传递给着色器来对其进行缩放以修正尺寸。这使您可以轻松使用相同的盒子来涂抹任何尺寸的纹理。

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

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

+0

我会接受你的答复作为答案,因为它是的确是一个有效的解决方法。是不是一个翻转的OpenGL纹理应该得到srcRect计算的权利和SDL的版本,除了在OpenGL的uv空间规范化的数值没有改变?或者是我的理解在这方面是错误的?谢谢。 – user2924261

+0

嗯,是的,的确,这比有点翻转的角度更有毛,因为这也涉及到你用来纹理纹理的矩形的坐标。所以,你也可以通过转动矩形来“翻转” - 我添加这个解释我的答案在第二。但是UV坐标无论如何都是标准化的:D – MaKo

+0

我写了一些关于用于纹理贴图的多边形的描述。在OpenGL中,您可以调整坐标的许多不同位置:您可以使用任何变换矩阵(模型,视图透视图),也可以在设置多边形时进行调整。我个人更倾向于改变视角以匹配原始SDL代码中使用的视角:SDL(在OpenGL的顶端)最有可能原本是翻转坐标以便为您提供“传统”坐标系。 – MaKo