how to use glCopyImage2D
Asked Answered
W

4

10

I'm trying something like

glEnable(texture_2d)
glBindTexture
glCopyTexImage2D
glDisable(GL_TEXTURE_2D);

I think glCopyTexImage2D won't work with a non-power of two image, so that's one problem; I've also tried glReadPixels, but it's too slow for my purposes.

Washer answered 19/6, 2010 at 0:10 Comment(2)
Do you know if the problem is in creating the texture or later rendering it? Does glCopyTexImage2D followed by glGetTexImage yield the same result as glReadPixels? (not recommended as a long-term solution for performance reasons, but as a troubleshoot step to see what's going on with the texture)Kerstin
For the power-of-2 restriction, you can use glTexImage2D to allocate the texture with a power-of-2 size and passing NULL for the data, then glCopyTexSubImage2D which allows non power-of-2 dimensions.Kerstin
A
10

If glReadPixels is too slow for you, then glCopyTexImage2D and glCopyTexSubImage2D aren’t going to be a whole lot faster. On platforms with support for framebuffer objects, like iOS, the recommended (i.e. faster) way to get GPU-rendered image data into a texture is to use that texture as the color attachment for a framebuffer object and render directly into it. That said, if you still want to pursue this method, here’s what you need to do to fix it:

First, you’re passing bad arguments to glCopyTexImage2D. The third argument, internalformat, should probably be GL_RGBA instead of 0. If you had called glGetError after calling glCopyTexImage2D, you would probably have gotten GL_INVALID_OPERATION. See the OpenGL ES 1.1 man pages for glCopyTexImage2D and glCopyTexSubImage2D.

Second, as you’ve already observed, glCopyTexImage2D requires its width and height arguments to be power-of-two as well. The correct way to deal with this is to allocate a texture image using glTexImage2D (you can pass NULL for pixels here), then use glCopyTexSubImage2D to copy your framebuffer contents into a rectangle. Note that glCopyTexSubImage2D doesn’t take an internalformat argument—because it’s updating a subrectangle of a texture, it uses the texture’s existing format.

For the record, glGetTexImage doesn’t exist in OpenGL ES 1.1 or 2.0, which is why you’re getting an implicit declaration.

Apostrophize answered 19/6, 2010 at 17:33 Comment(1)
Sounds like I should look into framebuffer objects... ThanksWasher
R
2

You can check if the video card supports non-power of 2 textures if it supports the ARB_texture_non_power_of_two extension. See here for info.

Ramentum answered 21/6, 2010 at 16:49 Comment(0)
D
2

glCopyTexImage2D does work with NPOT image.

NPT image (non-power of two) is limited supported by OpenGLES 2/OpenGL 1 or WebGL, In OpenGLES 3/OpenGL 2 or later it is fully supported.

If you want to copy color attachment of fbo to newTexture.

glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, newTexture);
glTexImage2D(bindTarget, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glCopyTexSubImage2D(target, level, 0, 0, 0, 0, width, height);

NPT image will output black color in fragment shader sampling if texture mipmap, magnification filter and repeat mode setting is wrong.

Detect answered 22/3, 2019 at 7:43 Comment(0)
H
1

To help figure out if the "non-power of two" thing is a problem, use glGetError() like this:

printf("error: %#06x\n", glGetError());

Put that in different places in your code to make sure what line is causing the problem, then check the error code here: https://www.khronos.org/opengl/wiki/OpenGL_Error

To copy a texture I did:

glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0);
glGenerateMipmap(GL_TEXTURE_2D);

after binding the texture. Check the docs on those two functions for more info.

Hasp answered 18/2, 2018 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.