I am trying to copy my screen(everything rendered in the display, or part of it) to a texture. I use this function:
public void screenToTexture(){
GL11.glViewport(0, 0, 512, 512);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 0, 0, 512, 512, 0);
GL11.glViewport(0, 0, 1024, 768);
}
When later I bind this texture and map it on a square, all I get is a white texture. I know I am doing something wrong, could someone plz guide me?
you could always try testing glReadPixels instead. I have had problems with glCopyTestImage2D in the past
Thnx, I'll try that.
Quote from: manji on August 26, 2009, 21:12:15
(...)
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 0, 0, 512, 512, 0);
When later I bind this texture and map it on a square, all I get is a white texture. I know I am doing something wrong, could someone plz guide me?
You may have to invert textureID with the copyTexImage2D name, which is 0 i guess. Is that the screen you want to copy ? screen is 0, then must be bound instead.
@broumbroum I am sorry, but I didn't get what you suggest. If you say that I should bind the right texture, I already do that. Before rendering a cube, I am sure I bind the texture that this textureID refers to. textureID is defined by:
public int createTextureID(){
IntBuffer tmp = createIntBuffer(1);
GL11.glGenTextures(tmp);
return tmp.get(0);
}
and before drawing the cube, I do:
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
@bobjob I tried the function I saw here http://lwjgl.org/forum/index.php/topic,867.0.html (http://lwjgl.org/forum/index.php/topic,867.0.html) that uses glReadPixels to copy the screen to BufferedImage and then I copy it to a texture. I did saw an inverted texture of my screen once, so there is a hope here. I will check it more thoroughly later and will post the results.
I might explain further : What you want to do is copy the screen and render with a texture.
Quote from: glcopyteximage2d-docglCopyTexImage2D defines a two-dimensional texture image
with pixels from the current GL_READ_BUFFER.
that is you have to generate a buffer name, bind it : glbindbuffer to gl_pixel_pack_buffer and then read your screen frame buffer :
Quote from: glreadpixelsIf a non-zero named buffer object is bound to the GL_PIXEL_PACK_BUFFER target (see glBindBuffer) while a block of pixels is requested, data is treated as a byte offset into the buffer object's data store rather than a pointer to client memory.
then obviously the pixel data will stay in the newly created buffer for which it can be requested the copy to a texture.
genbuffer > bindbuffer > readpixels > copyteximage2d > bindtexture > render the cube :P
@broumbroum I really thank very much for your time, but I am not so sure how to implement this right now ???. So, for the time being I'll stick to the following.
I have gathered some functions I have found here and there, and the best I can do is copy the screen to a texture, but inverted. The procedure is the following:
At first, I take a screenshot in a BufferedImage object:
public BufferedImage screenShot(int width, int height){
BufferedImage screenshot = null;
// allocate space for RBG pixels
ByteBuffer fb = GLApp.allocBytes(width * height * 3);
int[] pixels = new int[width * height];
int bindex;
// grab a copy of the current frame contents as RGB
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, fb);
// convert RGB data in ByteBuffer to integer array
for (int i=0; i < pixels.length; i++) {
bindex = i * 3;
pixels[i] =
((fb.get(bindex) << 16)) +
((fb.get(bindex+1) << 8)) +
((fb.get(bindex+2) << 0));
}
// Create a BufferedImage with the RGB pixels then save as PNG
try {
screenshot = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
screenshot.setRGB(0, 0, width, height, pixels, 0, width);
//javax.imageio.ImageIO.write(screenshot, "png", new File("screenshot_test.png"));
}
catch (Exception e) {
System.out.println("ScreenShot() exception: " +e);
}
return screenshot;
}
Then I convert this byteBuffer to a Texture(from spaceinvaders source) object:
public Texture getTexture(BufferedImage image,
int target,
int dstPixelFormat,
int minFilter,
int magFilter) throws IOException
{
int srcPixelFormat = 0;
// create the texture ID for this texture
int textureID = createTextureID();
Texture texture = new Texture(target,textureID);
// bind this texture
GL11.glBindTexture(target, textureID);
BufferedImage bufferedImage = image;
texture.setWidth(bufferedImage.getWidth());
texture.setHeight(bufferedImage.getHeight());
if (bufferedImage.getColorModel().hasAlpha()) {
srcPixelFormat = GL11.GL_RGBA;
} else {
srcPixelFormat = GL11.GL_RGB;
}
// convert that image into a byte buffer of texture data
ByteBuffer textureBuffer = convertImageData(bufferedImage,texture);
if (target == GL11.GL_TEXTURE_2D)
{
GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter);
GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter);
}
// produce a texture from the byte buffer
GL11.glTexImage2D(target,
0,
dstPixelFormat,
get2Fold(bufferedImage.getWidth()),
get2Fold(bufferedImage.getHeight()),
0,
srcPixelFormat,
GL11.GL_UNSIGNED_BYTE,
textureBuffer );
return texture;
}
And finally I bind the texture before rendering. The weird thing is that the texture is rendered fire, but inverted. Any clue?
the java co-ordinate system is different to the OpenGL one.
so it may be that you are copying pixels from the bottom left in opengl
then drawing them from the top-right in bufferedImage object.
Quote from: manji on August 27, 2009, 15:51:00
@broumbroum I really thank very much for your time, but I am not so sure how to implement this right now ???. So, for the time being I'll stick to the following.
And finally I bind the texture before rendering. The weird thing is that the texture is rendered fire, but inverted. Any clue?
It's alright, yet I think openGL has some issues where it is hard to find your way out because opengl is not as handy as java. 8)
Quote
so it may be that you are copying pixels from the bottom left in opengl
then drawing them from the top-right in bufferedImage object.
then it might be the case to flip the buffer returned by converttobufferedimage.
I guess you mean flipping the BufferedImage object. I did that, using things from here, http://www.exampledepot.com/egs/java.awt.image/Flip.html (http://www.exampledepot.com/egs/java.awt.image/Flip.html) and here http://www.java2s.com/Code/Java/Advanced-Graphics/FlippingaBufferedImage.htm (http://www.java2s.com/Code/Java/Advanced-Graphics/FlippingaBufferedImage.htm), and also using GLImage class http://potatoland.org/code/gl/javadoc/glapp/GLImage.html#flipY(java.awt.image.BufferedImage (http://potatoland.org/code/gl/javadoc/glapp/GLImage.html#flipY(java.awt.image.BufferedImage) . The same inverted image appears. If I make any progress, I will post again.
Update: No wait, my mistake, this thing actually works! :
// Flip the image vertically
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -img.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
img = op.filter(img, null);
Thank you very much both of you! There is still an anomaly in the lower side of the texture(smth like clamping), but I hope I will fix it.