PDA

View Full Version : Upside-down bitmap



PkK
05-21-2006, 04:54 AM
I have bitmap data ordered top rows first.

I'm looking for an efficient way to draw it using OpenGL, something like
a "glBitmapZoom()".

There are 32 bitmaps of different color and independent position.
The size of these bitmaps is 16x16.

So far I see three ways to do this:
1) Draw a polygon using the bitmap as stipple pattern. Then I have to use 3D functionality for a pure 2D task, which will slow my program down on systems without hardware acceleration.
2) Convert the bitmap to RGBA in my program, then use glDrawPixels() with glPixelZoom(). Then my program has to do some of the work I'd like OpenGl to do.
3) Use glDrawPixels() with type parameter set to GL_BITMAP, format GL_COLOR_INDEX. Then I have to set 4 colors maps (G_MAP_INDEX_TO_R, etc) for each bitmap.

Is there a better way?

I'd like something like
glRasterPos() to set the position,
glColor4f() to set the color,
glBitmap() to draw it,
but then it's drawn upside-down.

I'd prefer to do this without shaders, since I want my application to use OpenGL 1.2 without extensions only, so it works on every system out there.

Philipp

Overmind
05-21-2006, 09:17 AM
I think the best solution will still be loading the bitmap into a texture and draw a textured polygon. It will definitely be faster than any of your suggested solutions with hardware acceleration, even on the really old cards.

And even without hardware acceleration, it's still likely that it's faster... But I don't think there are any systems out there that don't have at least basic hardware acceleration.

Using textures would also solve your upside down problem, you just have to reverse the vertical texture coordinates.

Bob
05-21-2006, 10:01 AM
Originally posted by PkK:
I have bitmap data ordered top rows first.
That's actually the source of your problem. OpenGL uses the origin in the bottom left corner for everything that have an origin. That includes images, which are drawn bottom up. There are some ways to simulate top down drawing, but I strongly suggest you adapt to OpenGL and store your images bottom up in the first place instead of top down. Flip the image when you load the image, if the image format is a top down format that is.

If you don't play on OpenGL's rules, you have to be very careful as "solving" one problem can cause other problems. If you do, everything will come out nicely and be consistent throughout the program.

PkK
05-21-2006, 10:19 AM
But I don't think there are any systems out there that don't have at least basic hardware acceleration.There's lots of them. There's no free drivers for Nvidia cards and newer ATI cards, since they're non-free that means additional effort each time you update your kernel. The free DRI drivers are still experimental for anything newer than a Radeon 9250 and thus not enabled by default on most distributions. So many Linux users just don't have hardware-accelerated OpenGL.
I want my program to work on every Linux system out there, so it has to work with software rendering and with OpenGL 1.2 (every Linux driver supports OpenGL 1.2 or higher).

The situation with textures is the same as with glDrawPixels(): I have to convert the data to RGBA every frame or use GL_BITMAP with GL_COLOR_INDEX and set the color map for every bitmap.



If you don't play on OpenGL's rules, you have to be very careful as "solving" one problem can cause other problems. If you do, everything will come out nicely and be consistent throughout the program.I'm writing an emulator, so I have to work with top-rows-first-ordered data.

I think I solved the problem though: A modification of 3) should work and be fast enough: I instead of changing the 4 maps for each bitmap I could just set GL_INDEX_OFFSET for each bitmap. With this solution there would be only 3 OpenGL calls per bitmap just as if I had used glBitmap().

Philipp

PkK
05-21-2006, 10:31 AM
A thought later the solution seems a bit more complicated: I'll have to use maps of double size where all even entries are transparent and my colors at the odd entries.
Then I'd set GL_INDEX_OFFSET to select the color:
Where there's a 0 in my bitmap the resulting index should point to the transparent color at the even entry, where there's a 1 in my bitmap the index should point to the color entry.

Philipp

Bob
05-21-2006, 10:46 AM
Originally posted by PkK:


If you don't play on OpenGL's rules, you have to be very careful as "solving" one problem can cause other problems. If you do, everything will come out nicely and be consistent throughout the program.I'm writing an emulator, so I have to work with top-rows-first-ordered data.
I can accept that you cannot do anything about the data itself. But unless the library you use to load the images actually pass them to OpenGL aswell, you will have access to the data at some point. At that point, replace the data with a modified copy suitable for OpenGL. You don't have to draw exactly what you load, you know :rolleyes:

PkK
05-21-2006, 11:14 AM
These bitmaps are written by the processor of the emulated system into emulated graphics memory under program control.
Thus they can theoretically change every frame. I'd have to replace the data with the copy suitable for use with OpenGL every frame. That would be solution 2) in the initial post. I'm looking for a way to not do this replacement myself. It seems glDrawPixels() with GL_INDEX_OFFSET, glPixelZoom() is the way to do this.

Antorian
05-22-2006, 01:47 AM
Drawing a textured quad doesn't mean that HW acceleration is Active.
It depends on how implemented graphic card driver is.
So the best way for you is:
draw a simple textured quad with inverting texture coordinates on Y axis (0,0 for bottom left corner and 1,-1 for top right corner instead of 0,0 and 1,1).
98% of opengl drivers support simple texturing, (so if not, you should use SDL library instead)

This way I use, works with the most systems.
So I think it's what you need.

(Rem: Simple texturing is OpenGL 1.1 specs so if you need to be really fully compatible use SDL with OpenGL.In this case even if you don't have a system with OpenGL drivers, you will be able to draw your sprites or bitmaps with standard SDL functions.)

Regards.

Overmind
05-22-2006, 03:23 AM
I have to convert the data to RGBA every frame or use GL_BITMAP with GL_COLOR_INDEX and set the color map for every bitmap.No. You only have to convert the data once each time it changes. Just put some sort of "hardware breakpoint" into the emulator that reacts when the user program changes the graphics memory. This breakpoint would trigger a data conversion and texture upload.

Most likely this won't happen very often.