PDA

View Full Version : Internal textures



Darhazer
03-03-2003, 02:37 PM
I'm developing Delphi/OpenGL game (I will post details about it leter in "your projects" forum and almost all is done. But it loads textures from external .bmp files. I want to use some internal format for the textures (probably RGB arrays), no matter if they be loaded from external file (but only one for all textures) or from exe itself. I was wondering if it is possible to do this. I've heard than there are programs that convert bmp and pcx files into RGB arrays. But the only solusion I found for now is to put all textures in archive and this is not what I want
Can you told me, please, how to create some type of RGB array or other internal texture type and render it to the scene
Thank you

lithander
03-03-2003, 04:57 PM
I don't know if i understood your question correctly. Do you want to know how to create a texture from your rgb array or do you want to know how to create these arrays? I guess both...

However, I don't know of a ready-to-use solution but it shouldn't be too hard do code it yourself...

I'd suggest you work with your own file format wich contains all the image-data you need. You could use a format like this:
First there is a header wich holds some general information and the amount of stored images.
Then follows information about every stored image. the name, the size in width and height and how many bytes the imagedata takes. You could also add information about the format if you want to support different types of images.
After these follows the Image-Data.

Let's say you want to load the 5th image with a filestream you'll do the following.
- read the header (aStream.Read(YourHeader,sizeOf(YourHeader));
- check the header for the number of stored images.
- read the image information of every image.
Now the byte data follows. you can calculate the position of the 5th image by summing up the size of the header, the size of all the image-information and size of the four images you want to skip. You set the Streams position to the just calculated position of your image. And are ready to ...
- Read the Image into a buffer (for example an array with the correct length).
- Now you can make a texture of it - similar to what you would do with a bmp you've loaded from file.
It's basically a call of glTexImage2D(GL_TEXTURE_2D, 0, 3, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);
with pData beeing a pointer to the buffer and width height beeing the size of your image.


To put a bunch of bmp's or whatever into your file you'd need to write your own converter. It shouldn't be to hard as you've nothing more to do than creating the header and the information-structures of all contained images and saving these together with the image data (rgb-arrays) into the file. (Using a file-stream)

This has been just a raw overview about how you could do it... hope it helps. ;)

-lith

Darhazer
03-03-2003, 06:44 PM
My question is how to convert BMP into array... I know how to make my own file format - all levels of the game are stored in such way. I have some ideas of how to convert BMP into array but realizing that will take me a lot of time (no, this is not so long way, but I have little time and I'll need few days to do conversion) Becouse of this I'm searching for existing code or better solution.
Thank you for reply. Your signature is nice :)

Darhazer
03-03-2003, 06:47 PM
Also, I'm using a console application with API calls to create the rendering window and I want to keep away as many Delphi units (Forms, controls, etc.) as possible. Becouse of this the solusion should not use VCL

lithander
03-03-2003, 09:29 PM
hmm... but where is the problem with bitmaps? uncompressed 24bit images (like bmp) store the image data allready in byte arrays. you just had to copy that part....

or do you use any more complicated imagefiles?

Darhazer
04-03-2003, 08:00 PM
I want to store all arrays in a file without the headers of the bitmaps (there are all 32x32 piksels). I wantesd just to save time. Also, I want to make them in some other format and let the game convert it to RGB array. I'm just seeking for tool or code that will read the bitmap in an array and write it to the file (conversion I will make myself; it's so easy)
But the harder question is how to create internal sounds

Alimonster
05-03-2003, 11:10 AM
You might want to save your bitmaps in .raw format from your chosen graphics editor instead of .bmp format, which is basically just the pixel data. It would be simple enough to load it in - just blockread for the required amount. The down side there, though, is that you have to have some way of knowing the width/height/bpp count for each pic, since it won't be stored in the .raw pic. You could either hard-code the sizes in your code or you could do some processing into a custom format (basically a tiny header containing ints for width,height,bpp, plus the raw data) and write a tiny off-line program to convert the data. I posted some RAW code elsewhere in these forums, so you might want to have a look at it (though I think it uses the VCL).

If you want, I could give you a work-in-progress .bmp loader that doesn't use the VCL (side note: I've only ever tested it with 24 bit pictures. Probably works for 32 bit pics too, but not any other depth). It'll take the bitmap and give you back an array of pixels to play around with.

Darhazer
05-03-2003, 11:54 AM
All textures are 32x32x24bits bmps. I will be pleased if you send me program that convert them into arrays. The solution should NOT use VCL. Also, it should read the image data for all textures from one file. Becouse of this I choose the RGB arrays stored consecutively in a file as the best solution. The only problem is converting
If I know how the data in RAW image is stored and can convert it into RGB array, then I can use them. All that I know about RAW is that is (as I know) gray-scale, isn't is?

Andreaz
05-03-2003, 12:02 PM
I would say that you should use the imagelist component from the GLXTreem package, it does just what you want, it saves textures in streams. The latest released version has support for bitmaps and jpegs of any size and bitdeapths, next version will also support targa files.

Or if you don't wont the component, the class TGLXGraphic does the trick aswell..

Alimonster
05-03-2003, 12:55 PM
I would say that you should use the imagelist component from the GLXTreem package, it does just what you want, it saves textures in streams. The latest released version has support for bitmaps and jpegs of any size and bitdeapths, next version will also support targa files.

Or if you don't wont the component, the class TGLXGraphic does the trick aswell..
Your imagelist component uses the VCL. Is a non-VCL version of the image list available?


All textures are 32x32x24bits bmps. I will be pleased if you send me program that convert them into arrays. The solution should NOT use VCL. Also, it should read the image data for all textures from one file. Becouse of this I choose the RGB arrays stored consecutively in a file as the best solution. The only problem is converting
If I know how the data in RAW image is stored and can convert it into RGB array, then I can use them. All that I know about RAW is that is (as I know) gray-scale, isn't is?
A RAW can be literally anything you want. There's no predefined "RAW" which means that what you use depends entirely on what you need. The colour depth depends on what colour depth you originally use for drawing the bitmap. For example, if you use RGB mode in Photoshop and save a RAW, you'll see that it totals width * height * 3 bytes. You'd only end up with a greyscale if you were... drawing a greyscale pic ;).

I'll see what I can send about the BMP loader later on tonight. No promises that there won't be a bug or two in the files, though. I may wrap in some imagelist stuff too. I'm in the middle of a small project, though, so I may not have too much time for this.

Andreaz
05-03-2003, 03:32 PM
The TGLXGraphic class is a non vcl class, it handles the internal image routines in the imagelist, saving and so on, it will solve it.

Alimonster
05-03-2003, 04:09 PM
Hmm, are you certain. :? I had a look at some of the code for it:

------------------------------------------------------------------------------
Type TGLXGraphic = class(TPersistent)
private
{ Private declarations }
FGraphicType: TGLXGraphicType;
FBitmap : TBitmap;
FJpeg : TJPEGImage;
FData: TTextureData;
procedure SetBitmap(const Value: TBitmap);
procedure SetJpeg(const Value: TJPEGImage);
procedure CreateBlankBitmap(Bitmap: TBitmap);
function GetHeight: Integer;
function GetWidth: Integer;
public
{ Public declarations }
constructor Create;
destructor Destroy; override;
Procedure Assign(Source: TPersistent); override;

Function BuildTexture: glUint;
procedure LoadGraphic(FileName: String);
Procedure DeleteTexture(Texture: glUint);

Darhazer means "non-VCL", which I take to mean "using no VCL classes." There may be some confusion here - from the above snippet, I see TPersistent, TBitmap, TJPEGImage, etc., which are contained in VCL units. Are you thinking in other terms (components or whatnot)?

Andreaz
05-03-2003, 05:01 PM
Well, i might have missplaced the names a bit =) you're right =)

Darhazer
05-03-2003, 06:01 PM
What I mean is that I want to include as few as possible units. My project for now uses only units
Windows,
Messages,
BMP //handlung loading the bmp file into texture
OpenGL;
I want .exe file is keept as little as possible
I think there should be a way to save the RGB array from the loaded texture but I don't know how. I think if the function provided by the BMP unit returns the texture, than the texture is RGB array and can be saved. Any ideas?
I know how to solve the problem with the ImageList but no one VCL component (Image list is VCL component) should be used.
If I can separate only that part of the library that is needed and it will no add to the .exe more than 15-20KB the solution is acceptable as a last resor. Also, any solution that can write BMP into arrays (as an external program, not used in the game) is more than acceptable
The goal is to make little but quality game, whis not used external files and player can edit them easly

Alimonster
06-03-2003, 12:33 AM
Here's my non-VCL bitmap loader that can load from file or memory: http://www.alistairkeys.co.uk/NonVCLBitmap.pas.

I checked it with 3 or 4 24bit pictures and it seems to work. It probably handles 32 bit fine as well, though I've not tested that out.

You can combine that loader by packing your bitmaps onto the end of your exe file (link (http://www.alistairkeys.co.uk/packing.shtml)). (I can't remember if the example for that uses the VCL, but it's trivial to convert to non-VCL by using dynamic arrays + BlockRead/BlockWrite as appropriate).

Blah. Off to bed. Have fun!

Alimonster
06-03-2003, 09:23 AM
I think that the original padding calculation is wrong and only works by chance. The following should be correct:

[background=#FFFFFF][comment=#0000FF][normal=#000000]
[number=#C00000][reserved=#000000][string=#00C000]// calculate padding -- row width must be padded to 4 byte boundary
Padding := WidthInBytes and 3;
if Padding and 1 <> 0 then Padding := 4 - Padding;

That should be correct. There's probably a more elegant method for this, but I'm not sure because my brain has turned into mush from one too many late nights...

I've uploaded the changed version and tested it with a few bitmaps w/ different widths.

Useless Hacker
06-03-2003, 01:13 PM
How exactly do you define 'VCL'? I have always thought of VCL as being descendants of TComponent, that you drop onto your form at design-time. Alimonster seems to be condemning all Delphi classes as VCL.

Alimonster
06-03-2003, 01:40 PM
At the simplest level, I use "VCL" to mean "anything in a VCL unit". So yeah, basically most of the stuff that comes with Delphi, and any class that's TPersistent or below. TPersistent is part of the VCL (in the unit "classes"). Not every class - you can derive your own heirarchies from TObject, as long as they don't descend from VCL classes.

c:\program files\borland\delphi*\source\vcl <--- that's the VCL code right there!

I do admit that I unfairly lump some non-VCL units as "VCL code" (like the SysUtils unit, which is actually in the RTL, and sometimes the math unit). I prefer units containing one or two (max) classes, or a small modicum of functions, having a clearly defined purpose. Sprawling utliity files are an easy way to bloat your exe and I'm highly allergic to code size.

Anything in the delphi*\source\rtl\sys dirs go under the category of "non VCL", even if I sometimes mistakenly say otherwise.

Btw, I should have mentioned this before, but I forgot: the BPP in the non-VCL bitmap loader is bytes per pixel, not bits per pixel. I may rename that var later so it's clear, and/or provide another var for bits per pixel. I said my brain was mush and I wasn't joking.