使用openGL着色器歪斜图像

时间:2014-02-07 15:44:14

标签: c++ opengl glsl sfml

为了减轻艺术家的工作负担,我正致力于为图像制作一个简单的骨骼动画系统。我已经概念化了所有部件的工作原理。但是为了让它成为我想要的动画,我需要能够实时扭曲图像。 (如果我不能这样做,我仍然知道如何使它工作,但如果我可以倾斜图像来增加视角,它会更漂亮)

我正在使用SFML,它不支持图像偏移。我被告知我需要在图像上使用OpenGL着色器,但我得到的所有建议都是“学习GLSL”。所以我想也许这边的人可以帮我一点。

有谁知道我应该从哪里开始?或者怎么做?

基本上,我希望能够为图像赋予视角(如下面的模型所示)

enter image description here 左侧的图像在顶部和底部倾斜。右侧的图像左右倾斜。

2 个答案:

答案 0 :(得分:2)

如何在GLSL中扭​​曲纹理的示例将是以下(优化程度很差)着色器。理想情况下,您可能希望在常规程序中预先计算变换矩阵并将其作为一个统一传递,这样您就不会在每次移动着色器时重新计算变换。如果您仍想在着色器中计算变换,请将偏斜因子作为制服传递。否则,每次要更改偏斜系数时,都必须打开着色器并进行编辑。

这也适用于屏幕对齐的四边形。

<强> Vert的

attribute vec3 aVertexPosition;

varying vec2 texCoord;

void main(void){
   // Set regular texture coords
   texCoord = ((vec2(aVertexPosition.xy) + 1.0) / 2.0);

   // How much we want to skew each axis by
   float xSkew = 0.0;
   float ySkew = 0.0;

   // Create a transform that will skew our texture coords
   mat3 trans = mat3(
      1.0       , tan(xSkew), 0.0,
      tan(ySkew), 1.0,        0.0,
      0.0       , 0.0,        1.0
   );

   // Apply the transform to our tex coords
   texCoord = (trans * (vec3(texCoord.xy, 0.0))).xy;

   // Set vertex position
   gl_Position = (vec4(aVertexPosition, 1.0));
}

<强>分片

precision highp float;

uniform sampler2D sceneTexture;

varying vec2 texCoord;

void main(void){
   gl_FragColor = texture2D(sceneTexture, texCoord);
}

答案 1 :(得分:1)

这最终比我想象的要简单得多。 SFML有一个vertexArray类,允许绘制自定义四边形而无需使用openGL。

我最终使用的代码如下(对于遇到此问题的其他人):

sf::Texture texture;
texture.loadFromFile("texture.png");
sf::Vector2u size = texture.getSize();

sf::VertexArray box(sf::Quads, 4);


box[0].position = sf::Vector2f(0, 0);      // top left corner position
box[1].position = sf::Vector2f(0, 100);    // bottom left corner position
box[2].position = sf::Vector2f(100, 100);  // bottom right corner position
box[3].position = sf::Vector2f(100, 100);  // top right corner position

box[0].texCoords = sf::Vector2f(0,0);
box[1].texCoords = sf::Vector2f(0,size.y-1);
box[2].texCoords = sf::Vector2f(size.x-1,size.y-1);
box[3].texCoords = sf::Vector2f(size.x-1,0);

要绘制它,只要您通常告诉窗口绘制内容,就可以调用以下代码。

window.draw(lines,&texture);

如果您想扭曲图像,只需更改角落的位置即可。效果很好。有了这些信息,您应该能够创建自定义可绘制类。你必须写一些代码(set_position,rotate,skew等),但你只需要改变角落的位置并绘制。