Screen Capture To Texture (OpenGL / Slick2D)

Alright, so I’m trying to capture the current screen to a Texture object that I can render in all kinds of fun ways… I’m using the LWJGL tutorial on taking a screenshot, but rather than save that ByteBuffer to a file, I’m trying to create a Slick2D Texture from it.


	public static org.newdawn.slick.opengl.Texture getTextureFromScreen()
	{
		// Copies the current screen.
		GL11.glReadBuffer(GL11.GL_FRONT);
		int width = Display.getDisplayMode().getWidth();
		int height= Display.getDisplayMode().getHeight();
		
		java.nio.ByteBuffer buffer = org.lwjgl.BufferUtils.createByteBuffer(width * height * 4);		
		GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);				
		
		int textureId = GL11.glGenTextures();
		TextureImpl tex = new TextureImpl("screen", GL11.GL_TEXTURE_2D, textureId);
		
		// produce a texture from the byte buffer
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);				
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MIN_FILTER,GL11.GL_LINEAR);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_LINEAR);
		GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);				
		
		return tex;			
	}

	public static void drawTexture(float x, float y, Texture texture, int width, int height, int srcX, int srcY, int srcWidth, int srcHeight, float red, float green, float blue, float alpha, float angle) 
	{		
		// If the provided texture string is null or empty, don't try to draw it. :)
		if(texture != null)
		{											
			texture.bind();
			
			float fSrcX = ((float)srcX / texture.getTextureWidth());
			float fSrcY = ((float)srcY / texture.getTextureHeight());
			float fSrcWidth = (((float)srcX + (float)srcWidth) / texture.getTextureWidth());
			float fSrcHeight = (((float)srcY + (float)srcHeight) / texture.getTextureHeight());			
			
			GL11.glPushMatrix();				
							
			// Rotation
			if(angle != 0)
			{
				GL11.glTranslatef(x + (width / 2), y + (height / 2), 0); // move to the proper position
				GL11.glRotatef(angle, 0, 0, 1); // now rotate
				GL11.glTranslatef(-1 *(x+ (width / 2)), -1 * (y+(height  / 2)), 0);				
			}
			
			GL11.glColor4f(red, green, blue, alpha);
			GL11.glBegin(GL11.GL_QUADS);
				// Top Left
				GL11.glTexCoord2f(fSrcX, fSrcY);
				GL11.glVertex2f(x,y);
				// Top Right
				GL11.glTexCoord2f(fSrcWidth, fSrcY);
				GL11.glVertex2f(x + width, y);
				// Bottom Right
				GL11.glTexCoord2f(fSrcWidth,fSrcHeight);
				GL11.glVertex2f(x + width,y + height);
				// Bottom Left
				GL11.glTexCoord2f(fSrcX,fSrcHeight);
				GL11.glVertex2f(x,y + height);
			GL11.glEnd();
			
			GL11.glPopMatrix();
		}			
	}

I’ve had some weird results thus far including the resulting texture only capturing one pixel’s color (at least that’s how it renders) and getting some errors about the ByteBuffer size. Any ideas??

  • Steve