PDA

View Full Version : copy part of a texture to another bigger one



LR123
09-02-2009, 10:02 AM
Hi,

I just want to copy a part of a texture to another. (the original texture size is 640x480, but only the lower left quarter is used - thus the actual texture size is 320x240). Let's call this first texture texA. I want to store this 320x240 texture (lower right part of texA) to another (640x480) texture (called texB). Of course the texture will be magnified and look a bit "pixelated".

I bind texA, and map the texture to a quad. (assume the identity matrices). The current viewport is 640x480 (0,0,640,480) - I think it matters, doesn't it?



glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texA);

// draw to the framebuffer
glBegin(GL_QUADS);
//lower left
glTexCoord2f( 0, 0); glVertex2f(-1, -1);
//upper left
glTexCoord2f( 0, 0.5); glVertex2f(-1, 1);
//upper right
glTexCoord2f( 0.5, 0.5); glVertex2f(1, 1);
//lower right
glTexCoord2f( 0.5, 0); glVertex2f(1, -1);
glEnd();

// create init texB
glGenTextures(1,texB);
glBindTexture(GL_TEXTURE_2D, texB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, deltaWidth, deltaHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

// copy content
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 640, 480);


Then I copy the current framebuffer to the other (640x480) texture using glCopyTexSubImage2D. I expect that texB holds the magnified 320x240 texture of texA. Can anybody confirm this?

Later I use texB to finally draw the texture (again) to the framebuffer. (Actually I use 3 textures which get combined in a fragment shader) - In general it works, but the final result looks like texA. (only the lower left part of the screen shows the texture). Can anybody please give me a hint? - Do I miss something essential?




// draw the final texB, texC, and texD combined (see shader)
glBegin(GL_QUADS);
//lower left
glTexCoord2d(0.0, 0.0); glVertex2f(-1,-1);
//upper left
glTexCoord2d(0.0, 1.0); glVertex2f(-1,1);
//upper right
glTexCoord2d(1.0, 1.0); glVertex2f(1,1);
//lower right
glTexCoord2d(1.0, 0.0); glVertex2f(1,-1);
glEnd();



the vertex shader:


void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}


the fragment shader:


uniform sampler2D redTexture;
uniform sampler2D greenTexture;
uniform sampler2D blueTexture;
uniform float opacityR;
uniform float opacityG;
uniform float opacityB;
uniform float bypassShader; // is used to draw the source texture to the framebuffer. the redTexture holds the original frame in this case! TODO: change to boolean
void main( void )
{
if (bypassShader > 0.0f) {
vec4 colorRed = texture2D(redTexture,gl_TexCoord[0].st);
gl_FragColor = colorRed;
}
else {
vec4 colorRed = texture2D(redTexture, gl_TexCoord[0].st);
vec4 colorGreen = texture2D(greenTexture, gl_TexCoord[0].st);
vec4 colorBlue = texture2D(blueTexture, gl_TexCoord[0].st);
vec4 result;
result.r = colorRed.r * opacityR;
result.g = colorGreen.g * opacityG;
result.b = colorBlue.b * opacityB;
result.a = max(max(colorRed.a, colorGreen.a), colorBlue.a);
gl_FragColor = result;
}
}

ZbuffeR
09-02-2009, 01:50 PM
At first glance, the code posted above looks correct.

Then I copy the current framebuffer to the other (640x480) texture using glCopyTexSubImage2D. I expect that texB holds the magnified 320x240 texture of texA. Can anybody confirm this?
You can easily confirm it yourself by simply showing this first step onscreen, simply skip the copytex and second step.
You should have texA magnified to fill up the whole 640x480 viewport.
Maybe your projection and/or modelview matrix are messed up ?



glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, deltaWidth, deltaHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
instead of deltaWidth, deltaHeight, be sure to use 640 and 480.

LR123
09-04-2009, 05:03 AM
ZbuffeR, thank you for your reply! :)

I'll try this evening to skip the copyteximage and 2nd part, and will see if I get the expected result. Too bad I did not try this way of debugging before!

Regarding the shaders and the glMultiTexLocation, is it true, that glMultiTexLocation derives the location based on the glTexCoord2f( s, t) call? Sorry for this maybe stupid question, but I read the textureing chapter of the RedBook and also some parts of the OrangeBook, but still do not completely understand.

LR123
09-06-2009, 02:52 PM
okay, got it. :cool:

the problem was, that the host changed the viewport my plugin uses. Thus I've drawn the texture to a quad, which was mapped to the smaller 320x240 viewport. Later when I copied the content with glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 640, 480) only the lower left part (230x240) contained data.

I fixed this issue by changing the viewport to the size of the texture (texB) and after drawing the quad changed it back.

Again, thanks for your reply, it pointed me into the right direction.