I’ve been playing around with writing my own window manager in Linux similar to Compiz. I’ve managed to successfully create a texture out of the contents of a window, but now my problem is I can’t figure out how to draw that texture without making the texture look blurry (the blurriness is a result of the texture being scaled).
Basically I need a way to create a rectangle with the necessary dimensions so that the texture doesn’t end up scaled. Is this possible? How does Compiz do it?
You can stay with 2D textures with POW2 dimension. If image is 100x 60 pixels, make a texture of 128x64 and fit the image into the lower left corner of the texture. Texcoords would be
0.0 to 100.5/128.0 in the S direction
0.0 to 60.5/64.0 in the T direction
or if you have GL 2.0, just make a 100x60 GL_TEXTURE_2D
or if you have GL_ARB_texture_rectangle
I figured out how compiz does it, and it’s basically some simple perspective trickery. We can set the camera’s position such that the height/width of the viewport at Z = 0.0f is 1.0f. This means if we divide the width of the texture by the width of the screen, we’ll have the correct size of the primitive.
To determine where the camera needs to be to get this 1x1 size viewport, we use some simple trig. What we need is this: a plane of size 1.0f x 1.0f that, when positioned at Z=0.0f, will take up the whole screen. To do so, we draw a line from the center of this plane to the camera’s position. This line bisects the 60 degree fov to create two 30 degree angles. We then can determine the length of this line using trig in order to give us the Z coordinate of the camera. For the 60 degree fov example, we have Z = (1.0f / 2) / tan(30) = 0.866025404. moving the camera back by this amount now means we have a 1x1 viewport at Z=0.