Author: numenzq Source: http://www.j2medev.com/Article/ShowArticle.asp? ArticleID = 1096
Original address link
This example demonstrates how to create smoke effects without using the advanced particle engine. It is mainly implemented using some transparent texture Sprite. And let these genie move up, clockwise or counter-clockwise. The advantage of this is that the genie is always on the camera. Although this example is implemented in mascot capsule V3, the same technology can be used in JSR-184.
Download source code
Program, smoke effect generated using smoke texture
The following is the code of the smoke class:
Import com. mascotcapsule. micro3d. V3 .*;
Import java. util .*;
Public class smoke extends v3object {
Private figurelayout layout;
Private effect3d effect;
Private affinetrans trans;
// The Point sprite command used when rendering the smoke.
Private Final int command = graphics3d. primitve_point_sprites |
Graphics3d. pdata_point_sprite_params_per_cmd |
Graphics3d. pattr_blend_add |
Graphics3d. pattr_colorkey;
// The number of sprites used.
Private Final int num_point_sprites = 10;
Private smokeitem [] smokeitem = new smokeitem [num_point_sprites];
// Randomize the sprite rotation.
Private random R;
// The smoke texture.
Private texture = NULL;
Private long ticks = 0; // frame counter.
Public smoke (int w, int h ){
Try {
Texture = new texture ("/RES/smoke.bmp", true );
} Catch (exception e ){
E. printstacktrace ();
}
Layout = new figurelayout ();
Effect = new effect3d ();
Trans = new affinetrans ();
Trans. setidentity ();
Effect. setshadingtype (effect3d. normal_shading );
Effect. setsemitransparentenabled (true );
Layout. setaffinetrans (trans );
Layout. setperspective (1, 4096,512 );
Layout. setcenter (W/2, H/2 );
Trans. Mul (lookat); // The lookat is from the super class.
// Create the smoke sprites.
Smokeitem [0] = new smokeitem (null );
For (INT I = 1; I smokeitem [I] = new smokeitem (smokeitem [I-1]);
}
Smokeitem [NUM_POINT_SPRITES-1]. Start ();
}
Public void Update (){
Trans. setidentity ();
Trans. Mul (lookat );
}
Public void draw (graphics3d g3d ){
Ticks ++;
For (INT I = 0; I smokeitem [I]. Render (g3d );
}
}
Private class smokeitem {
// Each item has a reference to the next item so it can
// Be started after a certain time or in this case when the item // reaches a certain point.
Private smokeitem next = NULL;
Private int [] Point = {0, 0, 0}; // position of the sprite
Private int [] texture = {10, 10,512, 0, 0,128,128,
Graphics3d. point_sprite_perspective };
Private int rot; // the rotation of the Point Sprite,
// This is randomized
// W0, H0, A0, x00, y00, x01, Y01, F0,
// W1, H1, A1, x10, Y10, X11, y11, F1 ,...
Private int [] Normal = new int [] {4096 };
Private int [] color = new int [] {0x00 };
Private Boolean started = false;
Private random r = new random ();
Private int MOD;
Public smokeitem (smokeitem next ){
This. Next = next;
Reset ();
}
Public void start (){
Started = true;
}
/*
* Reset the size and position of the sprite
*/
Private void reset (){
Texture [0] = 10;
Texture [1] = 10;
Point [1] = 0;
Rot =-16 + R. nextint (32 );
}
/*
* The sprite is scaled and moved before rendered to the screen.
*/
Protected void render (graphics3d g3d ){
If (started & FPS. FPS> 0 ){
MoD = FPS. FPS/5;
MoD = mod <1? 1: MOD;
If (ticks % mod = 0 ){
If (texture [0] <80 ){
// Make the size of the sprite bigger.
Texture [0] ++;
Texture [1] ++;
}
}
MoD = FPS. FPS/10;
MoD = mod <1? 1: MOD;
If (ticks % mod = 0 ){
Point [1] ++; // Add 1 to the Y position.
If (point [1] = 180 ){
Reset (); // start over.
}
If (point [1]> 18 & next! = NULL ){
Next. Start (); // start moving the next Sprite
}
}
Texture [2] + = rot;
}
// Render the sprite.
G3d. renderprimitives (texture, 0, 0, layout, effect, command,
1, point, normal, texture, color );
}
}
}