HICON to Texture

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

HICON to Texture

Post by Acki »

Hi,
I have loaded an icon (HICON) and want to create a texture out of it...
unfortunately I have no clue how to achive this... :oops:

has someone an idea how to do this ???
(with Irrlicht 1.4.2 and WinXP)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

I guess you'd use DrawIconEx to draw it into a render target texture. Or you could use GetIconInfo to get the raw bitmap data, then copy that to an image - but you'd need to convert it from a colour key to a true-colour image and copy the mask bits into the alpha channel.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

bitplane wrote:I guess you'd use DrawIconEx to draw it into a render target texture.
no clue how to use it with an ITexture or IImage...
bitplane wrote:Or you could use GetIconInfo to get the raw bitmap data, then copy that to an image
I was experimenting with this, but got only distorted garphics datas so far...
like this, the small color pixled rect should be the icon (16x16):
Image
bitplane wrote:but you'd need to convert it from a colour key to a true-colour image and copy the mask bits into the alpha channel.
this seems to be the problem I have...
I'll try it again and search the web for infos... :lol:
if someone has a solution to this, let me know... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Hmm thinking about this some more, it would make more sense to write some code to extract the bitmaps directly from the .ico file, write them into ram as a file and then pass them to Irrlicht's bitmap loader-
http://msdn.microsoft.com/en-us/library/ms997538.aspx

If the bitmap loader doesn't like 1, 4 or 8 bit images (I've never tried it and I'm not at a dev PC at the moment) then patch the code into there instead :D
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

bitplane wrote:Hmm thinking about this some more, it would make more sense to write some code to extract the bitmaps directly from the .ico file, write them into ram as a file and then pass them to Irrlicht's bitmap loader-
http://msdn.microsoft.com/en-us/library/ms997538.aspx
hmm, interesting approach... ;)
unfortunately I don't have an icon file, I'm trying to get the icon assotiated with a file, this could be any file...

this is the code I have so far:

Code: Select all

#include <irrlicht.h>
#include <windows.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

static const int icoLarge = 256;
static const int icoSmall = 257;

ITexture* getFileIcon(char* filename, int size, IVideoDriver* driver){
  ITexture* ret = 0;
  SHFILEINFO sfi;
  SHGetFileInfo(filename, 0, &sfi, sizeof(SHFILEINFO), size);
  ICONINFO  icodat;
  if(GetIconInfo(sfi.hIcon, &icodat)){
    dimension2d<s32> icoSize = dimension2d<s32>(16,16);
    if(size == icoLarge) icoSize = dimension2d<s32>(32,32);

    // tried with all possible color formats (ECF_A1R5G5B5, ECF_R5G6B5, ECF_R8G8B8 and ECF_A8R8G8B8)
    IImage* txt = driver->createImageFromData(ECF_A1R5G5B5, icoSize, &icodat.hbmColor);

    stringc icn = filename;
    icn += size;
    ret = driver->addTexture(icn.c_str(), txt);
    txt->drop();
  }
  return ret;
}

int main(){
	IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, dimension2d<s32>(640, 480), 16, false, false, false, 0);
	IVideoDriver* driver = device->getVideoDriver();

  // be aware it only works with back slashes, not with forward slashes !!!
  ITexture* txt1 = getFileIcon("C:\\Programme\\CodeStuff\\Starter\\Starter.exe", icoSmall, driver);
  ITexture* txt2 = getFileIcon("C:\\Programme\\CodeStuff\\Starter\\Starter.exe", icoLarge, driver);

	while(device->run()){
		driver->beginScene(true, true, video::SColor(0,0,0,0));
		driver->draw2DImage(txt1, position2d<s32>(100,100));
		driver->draw2DImage(txt2, position2d<s32>(150,100));
		driver->endScene();
	}
	device->drop();
	return 0;
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
RoBaTte
Posts: 10
Joined: Thu Jun 07, 2007 2:34 pm

Post by RoBaTte »

The thread is some month old, but maybe someone has still to solve the same problem. I had to ;)

Here is my working code:

Code: Select all

void getIconTexture( const char* name, HICON icon)
{
    HDC hdc = GetDC( NULL);
    PICONINFO iconInfo;
    BITMAP bmpInfo;

    GetIconInfo( icon, iconInfo);
    GetObject( iconInfo->hbmColor, sizeof( bmpInfo), &bmpInfo);

    ITexture* texture = driver->addTexture( core::dimension2di(bmpInfo.bmWidth, bmpInfo.bmHeight), name);
    void* pTexPixel = texture->lock();

    BITMAPINFO lBitmapInfo;
    ZeroMemory(&lBitmapInfo, sizeof(BITMAPINFO));
    lBitmapInfo.bmiHeader.biSize  = sizeof(BITMAPINFOHEADER);
    lBitmapInfo.bmiHeader.biWidth    = bmpInfo.bmWidth;
    lBitmapInfo.bmiHeader.biHeight   = bmpInfo.bmHeight*-1;
    lBitmapInfo.bmiHeader.biPlanes   = 1;
    lBitmapInfo.bmiHeader.biBitCount = bmpInfo.bmBitsPixel;

    GetDIBits(hdc, iconInfo->hbmColor, 0, bmpInfo.bmHeight, pTexPixel, &lBitmapInfo, DIB_RGB_COLORS);
    texture->unlock();
    DeleteDC( hdc);
}
I still have to check it, but this code assumes that Irrlicht never will create a texture with the same name twice. I it still does, you have to check if the texture with this name already exists.

Using:

Code: Select all

HICON icon = LoadIcon (NULL, IDI_QUESTION); //Get your icon 
getIconTexture( "myIconTexture_1", icon);
...
node->setMaterialTexture(0, driver->getTexture("myIconTexture_1"));
node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
have fun. Rob
Post Reply