Compiling resources into exe (Code::Blocks and VC++)

A forum to store posts deemed exceptionally wise and useful
Post Reply
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Compiling resources into exe (Code::Blocks and VC++)

Post by puh »

SEE POSTS BELOW FOR MUCH SIMPLIER AND ENHANCED WAY.

Hello,

I was figured out how to compile all bitmaps used for toolbars buttons (for example), because i want to compile Example 9 (Meshviewer) with no external dependencies except for irrlicht.dll.

I use Code::Blocks with VC++ Toolkit 2003 compiler, don't know is this way usable for other tools though...

File 09.Meshviewer.rc

Code: Select all

#include "resource.h"
IDI_ICON1 ICON "icon.ico"
IDI_OPEN1 BITMAP "open.bmp"
IDI_HELP1 BITMAP "help.bmp"
IDI_TOOLS1 BITMAP "tools.bmp"
File resource.h

Code: Select all

#define IDI_ICON1                       1
#define IDI_OPEN1                       2
#define IDI_HELP1                       3
#define IDI_TOOLS1                      4
add files open.bmp, help.bmp and tools.bmp from media folder to the project

in file main.cpp add following code:

Code: Select all

....

#include <windows.h>
#include "resource.h"

....

// set icon for window (in left top corner)
    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 
    HICON hSmallIcon = (HICON) LoadImage ( hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR ); 
    irr::video::SExposedVideoData exposedData = driver->getExposedVideoData(); 
    HWND hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd);   
    SendMessage ( hWnd, WM_SETICON, ICON_SMALL, (long)hSmallIcon );
// end set icon

// set "open" button texture
// this is standard windows routine for loading resources
    HBITMAP hOpenIcon = (HBITMAP) LoadImage ( hInstance, MAKEINTRESOURCE(IDI_OPEN1), IMAGE_BITMAP, 16, 16, LR_CREATEDIBSECTION); 

// this is used for determening size of the resource
    BITMAP bitmap;
    GetObject(hOpenIcon,sizeof(BITMAP),&bitmap);
    int sizestrip = bitmap.bmHeight*bitmap.bmWidth*bitmap.bmBitsPixel/8;
    
// this is assigning byte array for the bitmap
    BYTE *strip = new BYTE[ sizestrip ];
// fill this array    
    GetBitmapBits((HBITMAP)hOpenIcon, sizestrip, strip );
    
// irrlicht native stuff for loading engine images from data (from byte array)
    video::IImage* image = driver->createImageFromData(video::ECF_R8G8B8, core::dimension2d<s32>(16,16), strip, false); 
// irrlicht native stuff for converting engine image to texture
    video::ITexture* iconOpen = driver->addTexture("open", image);
// end set "open" button texture

// set "help" button texture
    hOpenIcon = (HBITMAP) LoadImage ( hInstance, MAKEINTRESOURCE(IDI_HELP1), IMAGE_BITMAP, 16, 16, LR_CREATEDIBSECTION); 
    GetObject(hOpenIcon,sizeof(BITMAP),&bitmap);
    sizestrip = bitmap.bmHeight*bitmap.bmWidth*bitmap.bmBitsPixel/8;
    strip = new BYTE[ sizestrip ];
    GetBitmapBits((HBITMAP)hOpenIcon, sizestrip, strip );
    image = driver->createImageFromData(video::ECF_R8G8B8, core::dimension2d<s32>(16,16), strip, false); 
    video::ITexture* iconHelp = driver->addTexture("help", image); 
// end set "help" button texture

// set "tools" button texture    
    hOpenIcon = (HBITMAP) LoadImage ( hInstance, MAKEINTRESOURCE(IDI_TOOLS1), IMAGE_BITMAP, 16, 16, LR_CREATEDIBSECTION); 
    GetObject(hOpenIcon,sizeof(BITMAP),&bitmap);
    sizestrip = bitmap.bmHeight*bitmap.bmWidth*bitmap.bmBitsPixel/8;
    strip = new BYTE[ sizestrip ];
    GetBitmapBits((HBITMAP)hOpenIcon, sizestrip, strip );
    image = driver->createImageFromData(video::ECF_R8G8B8, core::dimension2d<s32>(16,16), strip, false); 
    video::ITexture* iconTools = driver->addTexture("tools", image);
// end set "tools" button texture

....

	//bar->addButton(1102, 0, driver->getTexture("../../media/open.bmp"));
	bar->addButton(1102, 0, iconOpen);
	//bar->addButton(1102, 0, driver->getTexture("../../media/help.bmp"));
	bar->addButton(1103, 0, iconHelp);
	//bar->addButton(1102, 0, driver->getTexture("../../media/tools.bmp"));
	bar->addButton(1104, 0, iconTools);
in linker options add following libs:
User32.Lib
Gdi32.Lib

in compiler options of course add MicrosoftSDK/include folder

That's all i hope. Compile and notice that colors for the icons are somehow changed...
Image
That's because of flipping Red and Blue bytes (probably in Irrlicht). So in order to have same images loaded from resources you should use external image editor to swap thouse colors...
Last edited by puh on Sun Sep 25, 2005 10:58 pm, edited 1 time in total.
Guest

Post by Guest »

Puh rocks, even if i dont understand that completely yet. Cheers. I need to try harder.
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Improved way

Post by puh »

Hello,

I've found the way to compile and load not only Bitmaps but any format which Irrlicht can read. Forget my previous post, start this from the scratch.

Much simplier now:

Code: Select all

#include <windows.h> 
#include "resource.h"
#include "CMemoryReadFile.h"
....
HRSRC hRes = FindResource(hInstance, MAKEINTRESOURCE(IDB_SKY1), "PNG");
DWORD rsize  = SizeofResource(hInstance, hRes); 
HGLOBAL hPngResource = (HGLOBAL) LoadResource ( hInstance, hRes);
char * lp = (char *) LockResource(hPngResource);
io::IReadFile* sky1 = new io::CMemoryReadFile( lp, rsize, "sky001.png", false );
Now you have a standard IReadFile which you can use as usual (driver->getTexture(sky1))

For this example in .rc file i've added following code:

Code: Select all

IDB_SKY1 PNG "resources/sky_wasteland02bk.png"
and in resource.h:

Code: Select all

#define IDB_SKY1                        210
All this is just an example as you see, you can now compile in exe any type of media: textures, meshes, fonts etc.

Don't forget to add to the project two files from Irrlicht source: CMemoryReadFile.h and CMemoryReadFile.cpp
genesisrage
Posts: 93
Joined: Tue Feb 08, 2005 12:19 pm

Post by genesisrage »

could this be used to compile the irrlicht.dll into the program as well, so you only need the one .exe file?

and also, not really sure i understand what you wrote. i get most of it, but problem im having is knowing what code goes in what file, whether it be cmemoryreadfile.cpp, what goes in the main source, etc...

(i know this thread has been dormant for some time, but give me a break, i actually used the search :) )
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Post by puh »

could this be used to compile the irrlicht.dll into the program as well, so you only need the one .exe file?
Technically - no. Practically - yes, but with workaround. You can compile Irrlicht.dll into your exe but when you will start your program it'll extract it to temporary directory... Not the perfect solution i think...
whether it be cmemoryreadfile.cpp
it's standard irrlicht file, you'll find it in source, something like this:
irrlicht-0.12.0\source\Irrlicht\CMemoryReadFile.cpp
jimowns
Posts: 62
Joined: Thu Sep 28, 2006 5:28 pm
Location: X-Gamers

Post by jimowns »

can you helpeing me how i make my open.bmp in a DLL file .
i trying and trying and its dont working by me .

i useing only Visual C++ 2005 Express edition .
i hope you can correction me .

|-- Sorry For my bad englishe --|

thanks in advance

here is my code .

resource.h

Code: Select all


#ifndef IDI_OPEN1 

#endif 
app.rc

Code: Select all

#include "resource.h"
IDI_OPEN1 BITMAP "open.bmp" 

#define APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon placed first or with lowest ID value becomes application icon

LANGUAGE 19, 2
#pragma code_page(1252)
1           ICON         "app.ico"

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE  
BEGIN
    "resource.h\0"
    "\0"
END

2 TEXTINCLUDE  
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE  
BEGIN
    "\0"
END

#endif    // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

test.cpp

Code: Select all

#include "stdafx.h"
#include "test.h"



int main ()
{

      return 0;
}
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

couldn't you just compile irrlicht into a static lib?
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

I know this is an old topic, but it's the closest I've found to what I want to do.

I've tried to use the code posted by puh above to put all my textures in the exe, but I don't understand where the 210 in resource.h comes from, and I get an error when I run the code;

Unhandled exception at 0x004176db in Tester.exe: 0xC0000005: Access violation writing location 0x00000018.

Any idea what that means?

btw, I've compacted the code a bit, but I don't think it should matter:

resource.h:

Code: Select all

#define IDB_CURSOR			210
HRSRC hRCursor;
io::IReadFile* r_cursor;
main:

Code: Select all

	hRCursor = FindResource( hInst, MAKEINTRESOURCE( IDB_CURSOR ), "PNG" );
	r_cursor = new io::CMemoryReadFile(
		(char *) LockResource( (HGLOBAL) LoadResource( hInst, hRCursor ) ),
		SizeofResource( hInst, hRCursor ),
		"cursor.png",
		false
	);
	cursor = guienv->addImage( driver->getTexture( r_cursor ), position2d<s32>( 0, 0 ) );
resources.rc:

Code: Select all

IDB_CURSOR PNG "cursor.png"

btw, changing the

Code: Select all

cursor = guienv->addImage( driver->getTexture( r_cursor ), position2d<s32>( 0, 0 ) );
line to

Code: Select all

cursor = guienv->addImage( driver->getTexture( "cursor.png" ), position2d<s32>( 0, 0 ) );
even without removing the other lines stops the error, but then I'm back where I started :?
Post Reply