How to update the pixels in the rectangular section of a texture with zooming?

Hello !

This is quite a specific question, I know, but using the glCopyPixels or equivent (glReadPixel and glDrawPixels), I was able with glPixelZoom to update the section of a FrameBuffer with pixels, while allowing for interpolation and resizing.

For the same program, I need a specific function that copies the pixels of part of an image (stored as an OpenGL Texture)

glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, *pixelRaster);

And I then want to update part of another texture with this pixel array, but allowing for zooming and repositionning.

I’ve already come across the glTexSubImage2D Function, but as far as I tested it only copies the pixels 1-to-1 and doesn’t allow for resizing.

Is there a way to do this ? Note that I am using JOGL, a Java implementation of OpenGL.

To be more specific (perhaps it could help) I want to create a function copy :

copy(int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh);

that takes the section defined by (sx, sy, sw, sh) of a texture and updating another (or the same) texture with these pixels on the region (dx, dy, dw, dh)

If you are copying texels between textures you can use glBlitFramebuffer, after attaching your source and destination textures to Frame Buffer Objects (FBO) and making them the draw and read buffer (glDrawBuffer/glReadBuffer) respectively.

If your source texels are in main memory (not part of a texture object) you can attach the destination texture to a FBO, set the FBO as draw buffer, and use glRasterPos and glPixelZoom together with glDrawPixels.

1 Like

Hm alright I think I understand haha

I’m still pretty new to FBOs, how would I attach textures to FBOs as draw and read buffers ?

Textures are attached to FBOs using glFrameBufferTexture or glFrameBufferTexture2D. FBOs are bound as the draw and/or read framebuffers using glBindFramebuffer. Draw and read buffers are selected with glDrawBuffer and glReadBuffer.

If you want to perform a zoomed blit between textures, you can either:

  1. Bind the source to the read FBO, bind the destination to the draw FBO, and use glBlitFramebuffer.
  2. Bind the source to a texture unit, bind the destination to the draw FBO, and draw a texture-mapped quad (triangle pair).
1 Like

Thank you both ! I haven’t had time to dive into FrameBuffers and rendering, and I need to do it at some point for this project so I guess I’ll just have to do that now haha.

If I could, I’d also like to ask (just to make understanding FBOs easier) what can they be used for ? I understand that they can be used as target buffers as for textures, and I also understand that they can be used for off-screen rendering (with RenderBuffers ? Correct me if I’m wrong).

If you had any documentation that could help me understand them I’d be really greateful (I always seem to be led back to the official OpenGL documentation, but without a grasp on the basic concept of what is a framebuffer and how to use it it’s pretty hard to decypher).

NB : Actually, while searching, I found this site : Does it correspond to what you explained ?

Thanks a lot :smiley:

That’s option 2, using a texture as the draw framebuffer. Option 1 also uses a texture as the read framebuffer.

1 Like

Alright, and on option 2 I’d have to draw the texture with a quad right ? As in with something like this :

public void image(SImage img, float a, float b, float c, float d) {
	gl.glBindTexture(GL.GL_TEXTURE_2D, img.getTexture());
	float x0 = getXScreen(a);
	float y0 = getYScreen(b);
	float x1 = getXScreen(a + c);
	float y1 = getYScreen(b + d);
	gl.glColor4f(1f, 1f, 1f, 1f);
	gl.glTexCoord2f(0f, 0f);
	gl.glVertex2f(x0, y0);
	gl.glTexCoord2f(0f, 1f);
	gl.glVertex2f(x0, y1);
	gl.glTexCoord2f(1f, 1f);
	gl.glVertex2f(x1, y1);
	gl.glTexCoord2f(1f, 0f);
	gl.glVertex2f(x1, y0);
	gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);

Thank you both for your help, I’ll get to it today :slight_smile:

Alright well nevermind it works, I just don’t understand how these FrameBuffer coordinates work ^^

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.