|

OpenGL/ FPC - Chapter 19 - by Delax
Well, this chapter is about loading bitmap pictures which are linked into your executable as resources. Now one might wonder why I don't explain external bitmap files as this would be easier to use for most of the newbies out there. The reason is: there are many libs and units which load bitmaps, TGAs, JPG and whatever file format into memory, so I won't cover this in detail - just go to www.freepascal.org and look at the contributed units. Resource files on the other hand are something different and are not well explained out there.
Resource files are normal files that are linked into your exe. It doesn't matter if these files are graphics files, sound files or whatever. After they are linked into the executable you can access them through the WinAPI. It provides almost everything you will need - even loading these graphic files into memory for you. Unfortunately these graphic files have to be bitmaps, which makes the executables quite big, but what the hell.
Again to the question "Why use resource files?". I'd say they are a pretty good way to include content into your executable without having to use external files or archives. This way you can keep your programs to just one file. You won't have to hassle with external file loading as the WinAPI does all the suff for you. Besides they are relatively easy to use.
So let's start. For those people who never worked with resource files, here is a quick update on Windows resources. Resource files are written much like a script. Actually, a resource file starts out as a "resource script" and is then compiled into a "resource file" that is then linked into the executable by FPC. But we need to compile the resource script first.
Lucky for us, FPC provides us with a resource compiler calles "WindRES". But unfortunately I won't use WindRES in this tutorial. Instead, I use GoRC. You can get GoRC on http://www.GoDevTool.com. It is easier to use and fairly small. The real problem is, that the resource scripts for WindRES and GoRC are a bit different. So it is not possible to use the code from this tutorial with WindRES. Sorry for that.
Fortunately we don't need to go deeper into resource scripting as we only need one line to add a bitmap. If you are interested in resources files though, you may take a look at the Win32/ FPC tutorial.
Now create a new file with your favourite editor. Just add one line:
2 BITMAP texture.bmp
Now save it as "source19.rc". Let's have a look at that line. The first number is the ID of this resource. With this ID you can use the resources from your application. Next ist the type of the resource. In this case the type is "BITMAP" as we include a bitmap image as resource. This is important as we could have included the bitmap as simple file without special type. But then Windows would not have access to it through the usual WinAPI calls for bitmaps. And the third parameter is the name of the actual file. Of course you should replace "texture.bmp" with the name of your bitmap you want to include.
Now we have to compile the resource script. GoRC is a console application, just like FPC. This means you have to enter the command for compilation manually. Of course you can also use your favourite editor and tell him to remote control GoRC. But for now I will explain how to do it "by hand".
Open a new DOS shell. Change into the directory of your resource script. Now enter "GoRC /r source19.rc". Of couse you need a path to GoRC or GoRC should be in the same directory as the rc. If everything went well you should have a file called "source19.res" in your directory now. If not, check if GoRC works and that you have the script as well as the icon file in the same directory.
Now we have a compiled resource file. Note that it has about the size of the icon. But how do we tell FPC that it should link this file into our application? That's easy. Just add the following line to the source (preferably after the units).
{$r source19.res}
With this, FPC will link the given resource file into your executable. And that's it - your bitmap will be linked into the executable the next time. And of course the size of your application will grow the size of the bitmap file.
Just some little things about including bitmaps. First off: remember that the textures have to have a size of 2^n, meaning something like 64*64, 128*128, 256*256 or whatever. Second, take care that the bitmaps have a bit depth of more than 8 bit. If bitmaps have 8 bit (meaning 256 colors), they contain a palette for coloring instead of using the RGB space directly. So make sure you use 24/ 32 bit bitmaps.
Now that we have our bitmap, we load it as a texture. It works pretty straight forward if you know a bit about the WinAPI. As usual you need a handle and a structure that will be filled with the values and the content.
procedure Texture_Init();
var
i : longint;
hBitmap : hBitmap;
sBitmap : Bitmap;
begin
Don't worry that the name of the variable is the same as the type. It's bad style, but it works anyway. Now we are binding the image to our handle. Note that although the name of the function might indicate it, we are NOT loading the actual content of the bitmap. This is done by the second line. Here we are filling the bitmap structure with the content of the bitmap file, such as width, height, bit depth and of course the actual pixel data.
hbitmap := LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(2), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
GetObject(hbitmap, sizeof(sbitmap), @sbitmap);
Now we are creating the texture the usual way. Two things are different though. First we have to tell OpenGL how that data is aligned and how to unpack it. Secondly, note how we are loading the texture into OpenGL memory. We are using only the content from the bitmap structure. No need for an extra pointer.
glEnable(GL_TEXTURE_2D);
glGenTextures(1, @TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, 3, sbitmap.bmWidth, sbitmap.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, sbitmap.bmBits);
glBindTexture(GL_TEXTURE_2D, TextureID);
And that's about it. Now you have loaded the bitmap image into OpenGL memory and can use it as a normal texture. Get the example here. It's a .zip file this time as there are some extra files (one bitmap and a resource file) that come with the source.
Delax/ Sundancer Inc.
[delax@sundancerinc.de]
Back to previous page
|