1
votes

I am trying to render some part of the texture inside my quad using the shader and an object file (.pod) which is nothing but container format of holding the vertices, normals and UVs.

so, just imagine i made a simple quad using 3ds max and export it as .pod and load into my scene from world to MVP . it has UVs as (0,0)(1,0)(0,1)(1,1) .. now I have a texture(.pvr) of 1024x128 pixels. I have sent all the data from cpp to vertex shader using appropriate buffers and everything is working fine.

Now question is, I want to render only some of the texture, lets say, starting from 200,30(left,bottom) pixels to 500,100(width,height).

How can I achieve the above using the vertex shader. I have written some logic in vertex shader, which acc to me is working for (0,0) coordinates, but how can I define height, width as there is only one vec2 variable. Below is the logic in vertex shader...

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);

same logic and values are working for all the UVs, Dont know how to mention height, width in it. and above code is doing some trick but not what I am expecting. it is repeating the texture inside the quad. Instead I want to render only (200,30,500,100)(l,b,w,h) part of the texture and that too inside the quad showing black boundary on the side of the quad from 0-127 pixels and 0-30 pixels from left and bottom respectively and black border from 629th pixel to 1024 from right .

I am trying to make A video wall project where TVs will be rotated in diff diff angles.

2
Sounds like you're trying to letterbox or something in the shader. You can do it but personally I'd change the geometry you're mapping onto to suit, i.e. change the aspect of the rectangle area representing the screen, rather than fiddling about in the shaders.Robinson
Your calculation looks wrong. I'm not sure where you got this formula from.BDL

2 Answers

4
votes

The correct calculation from mapping frmo [0, 1] to a start (s) and a length (l) is

x_mapped = x * l + s

When looking at your special problem, you should be using:

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

So,I was trying more on this to work, either efficient or inefficient way, below is what I have implemented in the fragment shader and seems like working out for me..please check once n let me know any optimization can be made on this. Below code will draw only the part of the texture i want to see in screen at the same place in the quad.

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);

}

This below part in vertex shader will load only the part of texture which i want to see but covering the whole quad.

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

Thanks for solving this.. @BDL