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

问题描述:

我想渲染我的四边形内使用着色器和一个对象文件(.pod)的纹理的一部分,这只是容器格式的持有顶点,法线和UV。如何渲染使用着色器的opengl中的四边形内的纹理的一部分

所以,试想一下,我使用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从右边。

我正在试图制作一个视频墙项目,电视将以不同的角度旋转。

+0

听起来像你想的着色信箱什么的。你可以做到这一点,但我个人会改变你映射到的几何图形来适应,即改变代表屏幕的矩形区域的方面,而不是在着色器中摆弄。 – Robinson

+0

你的计算看起来不对。我不确定你从哪里得到这个公式。 – BDL

从映射中的正确的计算frmo [0,1]对启动(S)和长度(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); 
+0

我相信唯一的问题是,如果我们从顶端做它不是'TexCoord.y = inTexCoord.y *(height/1024.0) - (top/1024.0);'?因为OpenGL坐标的BL角是0,0?或者'TexCoord.y = inTexCoord.y *(height/1024.0)+((top + height)/ 1024。0);' – Eddge

+0

@Eddge:它应该是“底部”而不是“顶部”(正如问题中所要求的那样)。你的两个公式中没有一个对我来说是正确的,这里有两个计数器例子:第一个为'y = 0'产生一个值为' - (top/1024)'的负值。第二个是'y = 1,top = 512,height = 512'(下半部分),'result = 1.5'。对于纹理内的有效参数组合,结果总是必须在[0,1]之间。 – BDL

+0

感谢您的快速回复和解决方案@BDL。它正在工作,但部分对我来说。我正在尝试的是仅在四边形中的位置渲染该部分纹理。 附加一个图像,您可以看到完整的纹理,并进行更改后,它将成为平铺纹理。 [http://imgur.com/a/JkJ4P] 'TexCoord.x = inTexCoord.x *(1024.0/1024.0)+(500.0/1024.0); TexCoord.y = inTexCoord.y *(128.0/128.0)+(64.0/128.0); ' – SIM

所以,我正在尝试更多的工作,无论是高效或低效的方式,下面是我已经在片段着色器中实现,似乎为我工作。请检查一次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

+0

如果@BDL解决了问题,您应该**接受**他的回答。 – Rabbid76

+1

@ Rabbid76:完成Sir .. – SIM