ITexture and EMT_TRANSPARENT_ADD_COLOR

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
tomhancocks
Posts: 15
Joined: Fri Jan 02, 2009 1:25 pm
Location: Around
Contact:

ITexture and EMT_TRANSPARENT_ADD_COLOR

Post by tomhancocks »

I've tried looking through the documentation on this one, and short of creating a 3D object and applying the Texture too it I can't figure out how to apply this flag to an ITexture.

Basically the game I'm creating uses a strange mix of 2D and 3D graphics. In the background is a pseudo 2d star field created with Billboards. These and spaced out along the z axis so that when they move they appear to move at different speeds giving the illusion of depth.

I then have a 3D layer. Planets, Particle effects and Nebula are going to get rendered in this layer.

Finally I have the 2D layer where ships, weapons and everything else is going. I've got the ships drawing nicely, extracting relevant sprites etc. The problem is the after burner effects. They need to look as if they are lighting things, not just solid blocks of colour. So how/is it possible to apply the EMT_TRANSPARENT_ADD_COLOR flag to an ITexture when you draw it via 2D methods.

Tom
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

ADD_COLOR is not supported by the 2d methods, only vertex alpha and alpha channel. The latter should work here as well, though. Just use your favorite painting program and let it create alpha channels from the black areas of your images.
tomhancocks
Posts: 15
Joined: Fri Jan 02, 2009 1:25 pm
Location: Around
Contact:

Post by tomhancocks »

hmm, ok.

Well since then I've noticed something that I'm not sure if its a bug or not. If 2 2D images are overlapping the bottom one is clipped, even after an alpha channel is applied.

I've applied an alpha channel with the following lines.

this->player_ship = this->driver->getTexture( shipTexture );
driver->makeColorKeyTexture(this->player_ship, core::position2d<s32>(0,0));

The code is based on the examples. The following image shows what's happening. The stars are been rendered in 3d, as explained in my first post, and you can see with the right hand sprite that alpha is definitely being applied, but its still clipping the left sprite.

Image

Appologies for the EV Nova graphics, have not yet got my own graphics sorted, want to get the engine out of the way first.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

How does your render loop look like?
tomhancocks
Posts: 15
Joined: Fri Jan 02, 2009 1:25 pm
Location: Around
Contact:

Post by tomhancocks »

The actual rendering is split across several classes, specific classes rendering specific aspects.

The actual loop (as it stands now)

Code: Select all

// Run Loop
	s32 lastFPS;
	while (device->run()) {
		driver->beginScene(true, true, video::SColor(0,0,0,0));
		
		s32 fps = driver->getFPS();
		if (lastFPS != fps) {
			core::stringw str = L"FPS: ";
			str += fps;
			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}
		
		player->update();
		player->drawShip();
		
		smgr->drawAll();
		driver->endScene();
	}
The drawShip() method is responsible for actually drawing the ship. For the test I simply just drew the same image twice, offsetting the second.

Code: Select all

void Player::drawShip() {
	if (this->rotation > 360) this->rotation -= 360;
	if (this->rotation < 0) this->rotation += 360;

	s32 spriteNumber = (s32)this->rotation / 10;
	s32 spriteNumberY = 0;

	while (spriteNumber >= this->sprites_x) {
		spriteNumberY++;
		spriteNumber -= this->sprites_x;
	}
	
	s32 x = this->ship_width * spriteNumber;
	s32 y = this->ship_height * spriteNumberY;
	
	this->driver->draw2DImage(this->player_ship, 
						  core::position2d<s32>((WIDTH - this->ship_width)/2, (HEIGHT - this->ship_height)/2), 
						  core::rect<s32>(x, y, x+this->ship_width, y+this->ship_height));
	this->driver->draw2DImage(this->player_ship, 
						  core::position2d<s32>((WIDTH)/2, (HEIGHT - this->ship_height)/2), 
						  core::rect<s32>(x, y, x+this->ship_width, y+this->ship_height));
}
In a world of code
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Ok, here's the correct order and params:
First draw 3d stuff (background), then draw 2d stuff (sprites).
Put your update method call outside the render part (before beginScene), because you will otherwise stall the pipeline.
Tell draw2DImage to use the alpha channel (right now it's just not visible because the transparent part is drawn black):

Code: Select all

draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
                        const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect =0,
                        SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false)
So add the following three params: 0, 0xffffffff, true
Not the final true, as it will enable alpha channel :!:
tomhancocks
Posts: 15
Joined: Fri Jan 02, 2009 1:25 pm
Location: Around
Contact:

Post by tomhancocks »

Thats working better. I've added the after burner effect to the ship now, but with out the additive blend effect its looking a little strange. I think I will tinker around and devise a way of doing that, because I absolutely need it in the 2d graphics for this game.

edit: Just a quick screen shot to indicate the kind of thing i'm meaning, 'cause I'm not 100% certain I'm explaining myself correctly :P

Image

I can get the blend mode on the right all well and good, but its the one on the left which I'm after.[/img]
In a world of code
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You could use a particle system to get this effect, put it into your sprites animation with a painting tool, or you use a 3d quad with additive transparency and ender that on top of the sprites.
Post Reply