Ok, I'm here:
What User137 said is correct. You need to use mipmapped filtering, which essentially means that OpenGL generates a series of gradually smaller pre-scaled versions of a texture that it then automatically chooses from when rendering, based on the current coordinates of the current OpenGL matrix as well as the texture coordinates you supply it with. This prevents the ugly flickering that you would normally get otherwise using simple linear filtering (which can only do an "approximate" filter pass on the full size image in real time.)
To enable it in your version, you would first need to change the gls_PrepareOpenGLForPainting procedure to look like this:
procedure gls_PrepareOpenGLForPainting;
begin
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glClearColor(BackgroundR, BackgroundG, BackgroundB, 1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
end;
Your version also has a function called TextureFromBitmap that would need to be changed to look like this:
function TextureFromBitmap(Image: TBitmap): GLuint;
var
Texture: GLuint;
ATexture: array[0..0] of GLuint absolute Texture;
Viewport: array[0..3] of GLint;
begin
glGenTextures(1, ATexture);
glClearColor(BackgroundR, BackgroundG, BackgroundB, 1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glScalef(1, -1, 1);
DrawScene(Image);
glLoadIdentity;
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glGetIntegerv(GL_VIEWPORT, Viewport);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0,
Viewport[2], Viewport[3], 0);
glBindTexture(GL_TEXTURE_2D, 0);
Result := Texture;
end;
A note about the TextureFromBitmap function though: generating an entirely new texture every frame with glGenTextures is extremely slow. This is why my version creates all the textures before any rendering is done, and simply stores their handles as well as the filename, aspect ratio, width and height of the original image in a record. (Meaning, the TBGRABitmaps that they're created from are never stored anywhere, and only exist temporarily during the loading procedure.) From there, the records are passed to the rendering methods, which then just call glBindTexture on the handles to switch between them.
If you want to get an idea of the speed difference, load an image of around 3072x3072 or larger in your version and then try to use it with any of the Wipe, Blind, or Matrix transitions. Then do the same thing in mine.
I also added another checkbox to my version today that allows you to toggle instantaneously between mipmapped and non-mipmapped textures, to allow for easy comparisons. I've attached two screenshots below that pretty much recreate the last one you posted of J-Gs Snowflake images: one with mipmapping turned on, and one with it turned off. (The difference is more noticeable in the actual application when it's actually moving, of course, but it still comes through pretty clear in the PNGs.)
Lastly, I've uploaded a new zip file (which is also attached to this post) with the updated project files and source files for my version, for anyone who wants to get a better idea of how to go about implementing any of what I've just described. (One other thing I did today was add some Carbon and Cocoa widgetset specific defines/implementations throughout the code, and as far as I can tell it
should now compile/work on those platforms. So if any Mac users specifically want to give it a test as well, that would be quite helpful!)