如何使用着色器在opengl中渲染四边形内的部分纹理

时间:2017-08-10 13:00:26

标签: c++ c opengl-es glsl

我正在尝试使用着色器和目标文件(.pod)渲染我的四边形内部纹理的一部分,该文件只是容纳顶点,法线和UV的容器格式。

所以,想象一下我使用3ds max制作了一个简单的四边形并将其导出为.pod并加载到我的场景中,从世界到MVP。它的UV为(0,0)(1,0)(0,1)(1,1) ..现在我有一个1024x128像素的纹理(.pvr)。我已经使用适当的缓冲区将cpp中的所有数据发送到顶点着色器,一切正常。

现在的问题是,我想只渲染一些纹理,比如从200,30(left,bottom)像素到500,100(width,height)

如何使用顶点着色器实现上述功能。我在顶点着色器中编写了一些逻辑,这对我来说适用于(0,0)坐标,但是如何定义高度和宽度,因为只有一个vec2变量。下面是顶点着色器中的逻辑......

varying mediump vec2   TexCoord;
attribute mediump vec2  inTexCoord;

TexCoord.x = inTexCoord.x * (1024.0/(1024.0-200.0))-(200.0/1024.0);
TexCoord.y = inTexCoord.y * (128.0/(128.0-30.0))-(30.0/128.0);

相同的逻辑和值适用于所有UV,不知道如何提及它的高度,宽度。以上代码正在做一些技巧,但不是我所期待的。它重复四边形内的纹理。  相反,我想只渲染纹理的(200,30,500,100)(l,b,w,h)部分,并且四边形内部也显示左边和底部分别来自0-127像素和0-30像素的四边形的黑色边界。从629th像素到右边的1024的黑色边框。

我正在制作一个视频墙项目,其中电视将以差异角度旋转。

2 个答案:

答案 0 :(得分:3)

从frmo [0,1]映射到start(s)和length(l)的正确计算是

x_mapped = x * l + s

在查看您的特殊问题时,您应该使用:

TexCoord.x = inTexCoord.x * (width/1024.0)  + (left/1024.0);
TexCoord.y = inTexCoord.y * (height/1024.0) + (bottom/1024.0);

答案 1 :(得分:0)

所以,我正在尝试更多这个工作,无论是高效还是低效的方式,下面是我在片段着色器中实现的并且似乎正在为我工​​作..请检查一次n让我知道任何优化都可以就此而言。下面的代码将只绘制我希望在四边形中的同一位置的屏幕中看到的纹理部分。

const float MAX_WIDTH = 1280.0;
const float MAX_HEIGHT = 720.0;

const float LEFT = 00.0;
const float TOP = 00.0;
const float WIDTH = 500.0;
const float HEIGHT = 500.0;

void main()
{
    vec2 p = TexCoord;
    float xx,xw,yy,yh,b;

    xx = (LEFT/MAX_WIDTH);
    xw = ((LEFT + WIDTH)/MAX_WIDTH);
    yy = (TOP/MAX_HEIGHT);
    yh = ((TOP + HEIGHT)/MAX_HEIGHT);

    if((p.x > xx) && (p.x < xw) && (p.y > yy) && (p.y < yh))
            b = 1.0;
    else
            b = 0.0;
    gl_FragColor = vec4((texture2D(sTexture, TexCoord).rgb),texture2D(sTexture,TexCoord).a * b);

}

顶点着色器的下面部分只会加载我想要看到但覆盖整个四边形的纹理部分。

    TexCoord.x = inTexCoord.x * (WIDTH/MAX_WIDTH)+(LEFT/MAX_WIDTH);
    TexCoord.y = inTexCoord.y * (HEIGHT/MAX_HEIGHT)+(TOP/MAX_HEIGHT);

感谢您解决此问题.. @BDL

相关问题