Can't get Lens Flares working

I'm trying to create a star with light and lens flare properties. After figuring out how to use RensParticleEditor, I was able to get something going and it looks good…except for the lens flare. For some reason I cannot get it to work. I've gotten to the point where I've stared at the code too long and can't really find what I'm doing wrong.



This is my first time on the boards and I'm quite new to jME…so be gentle :wink:



…any help on how to make it work is much appreciated.



Here's the code that I have to create the star:




private void buildSun() {

      /*Sphere star = new Sphere("Star", 30, 30, 1f);
      star.setModelBound(new BoundingSphere());
      star.updateModelBound();
      star.setLocalTranslation(300, 5, 5);
      star.setLocalScale(2);
      star.setSolidColor(ColorRGBA.white);
      star.setLightCombineMode(LightState.OFF);*/
      
      LightNode ln = new LightNode();
        ln.setLocalTranslation(300,5,5);
      
      //set up the star as a point light source
        PointLight pLight = new PointLight();
        pLight.setLocation(ln.getLocalTranslation());
        pLight.setEnabled(true);
        pLight.setShadowCaster(true);
        pLight.setAttenuate(true);
        pLight.setAmbient(ColorRGBA.white);
        pLight.setDiffuse(ColorRGBA.white);
        LightState lightstate = display.getRenderer().createLightState();
      lightstate.setEnabled(true);
      lightstate.attach(pLight);
      scene.setRenderState(lightstate);
      
      try {

         //import jme file from RenTextureEditor
         Spatial ogien = (Spatial) BinaryImporter.getInstance().load(
               CakeProto.class.getClassLoader().getResourceAsStream(
                     "starParticle.jme"));
         ogien.setLocalTranslation(ln.getLocalTranslation());

         ogien.setModelBound(new BoundingSphere());
         ogien.updateModelBound();
         ogien.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
         
         AlphaState as1 = display.getRenderer().createAlphaState();
           as1.setBlendEnabled(true);
           as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
           as1.setDstFunction(AlphaState.DB_ONE);
           as1.setEnabled(true);
           ogien.setRenderState(as1);
         
         //set the texture for the particle
           TextureState ts = display.getRenderer().createTextureState();
            ts.setTexture(
                TextureManager.loadTexture(
                TestPointParticles.class.getClassLoader().getResource(
                "flare1.png"),
                Texture.MM_LINEAR_LINEAR,
                Texture.FM_LINEAR));
            ts.setEnabled(true);
            ogien.setRenderState(ts);
           
            // enable point sprite mode, generate special texture coordinates for points
            GL11.glEnable(ARBPointSprite.GL_POINT_SPRITE_ARB);
            GL11.glTexEnvi(ARBPointSprite.GL_POINT_SPRITE_ARB, ARBPointSprite.GL_COORD_REPLACE_ARB, 1);
           
            // set up the distance attenuation
            FloatBuffer ceoff = BufferUtils.createFloatBuffer(0.0f, 0.00001f, 0.0f, 0.0f);
            ceoff.rewind();
            ARBPointParameters.glPointParameterARB(ARBPointParameters.GL_POINT_DISTANCE_ATTENUATION_ARB, ceoff);
         
         ZBufferState zbuf = DisplaySystem.getDisplaySystem().getRenderer()
               .createZBufferState();
         zbuf.setWritable(false);
         ogien.setRenderState(zbuf);
         ogien.updateRenderState();
         scene.attachChild(ogien);
           //ln.setLight(pLight);*/
         
         //set up lens flare effect
           TextureState[] textureState = new TextureState[4];
         textureState[0] = display.getRenderer().createTextureState();
         textureState[0].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare1.png"),
               Texture.MM_LINEAR_LINEAR,
               Texture.FM_LINEAR, Image.RGBA8888,
                   0.0f, true));
         //textureState[0].setEnabled(true);
         
         textureState[1] = display.getRenderer().createTextureState();
         textureState[1].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare2.png"),
               Texture.MM_LINEAR_LINEAR,
               Texture.FM_LINEAR));
         //textureState[1].setEnabled(true);
         
         textureState[2] = display.getRenderer().createTextureState();
         textureState[2].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare3.png"),
               Texture.MM_LINEAR_LINEAR,
               Texture.FM_LINEAR));
         //textureState[2].setEnabled(true);
         
         textureState[3] = display.getRenderer().createTextureState();
         textureState[3].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare4.png"),
               Texture.MM_LINEAR_LINEAR,
               Texture.FM_LINEAR));
         //textureState[3].setEnabled(true);
          
         LensFlare flare = LensFlareFactory.createBasicLensFlare("flare", textureState);
         flare.setRootNode(scene);
         //flare.setLocalTranslation(ln.getLocalTranslation());
         scene.attachChild(ln);
         ln.attachChild(flare);
         //scene.attachChild(flare);
         
      } catch (IOException ex) {
         ex.printStackTrace();
      }
         
      //scene.attachChild(star);
   }

your code does work for me.



if you move the lightnode further into the scene, you see it instantly and not only after turning around :slight_smile:

ln.setLocalTranslation(300,5,-500);

Thanks Core-dump.



I gave that a try and still no joy. Must be my implementation of this function in my main code.



hmmmm…



…and I assume that the flare is insane once it works considering that you see it not just turning around.

strange i just plugged your code into SimpleGame and it worked.

If you cant get it to work, you can post a complete simple TestCase to reproduce the problem.

ohhhhh…you plugged into SimpleGame?



My whole program is extending BaseGame. Could that be the issue?

It should be no issue, but as always you need to make sure that you have:

  • an enabled LightState with Light
  • call rootNode.updateRenderstate() after you attached everything to it.
  • a ZBufferState



    thats what i can think of right now

I do have that, but I'm not sure if I a) have it in the right areas or b) implementing it correctly if I do.



…so, here's my entire main program (…sorry…kinda long…)



package CakeProto;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.FloatBuffer;
import java.util.HashMap;

import jmetest.effects.TestPointParticles;

import org.lwjgl.opengl.ARBPointParameters;
import org.lwjgl.opengl.ARBPointSprite;
import org.lwjgl.opengl.GL11;

import com.jme.app.AbstractGame;
import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.input.ChaseCamera;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.thirdperson.ThirdPersonMouseLook;
import com.jme.light.DirectionalLight;
import com.jme.light.LightNode;
import com.jme.light.PointLight;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jme.util.export.binary.BinaryImporter;
import com.jme.util.geom.BufferUtils;
import com.jmex.effects.LensFlare;
import com.jmex.effects.LensFlareFactory;
import com.jmex.effects.particles.ParticlePoints;
import com.jmex.model.converters.MaxToJme;

public class CakeProto extends BaseGame {

   public void setDefaultDialogBehaviour() {
      setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
   }

   protected int width, height, depth, freq;
   protected boolean fullscreen;
   protected Camera cam;
   protected ChaseCamera chaser;
   protected Timer timer;
   protected Node scene;
   protected Skybox skybox;
   protected Vehicle ship;
   protected float numBullets;
   protected MaterialState bulletMaterial;
   protected Weapons bullet;
   protected ParticlePoints pPoints;

   protected SkySphere sol;
   protected InputHandler input;

   @Override
   protected void update(float interpolation) {
      // update the time to get the framerate
      timer.update();
      interpolation = timer.getTimePerFrame();

      input.update(interpolation);

      chaser.update(interpolation);

      // skybox.setLocalTranslation(cam.getLocation());
      // skybox.getLocalTranslation();
      sol.setLocalTranslation(cam.getLocation());
      sol.updateGeometricState(0, true);

      // if escape was pressed, we exit
      if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
         finished = true;
      }

      scene.updateGeometricState(interpolation, true);
   }

   @Override
   protected void render(float interprolation) {
      // clear the screen and render
      display.getRenderer().clearBuffers();
      display.getRenderer().draw(scene);
   }

   @Override
   protected void initSystem() {
      // store the properties information
      width = properties.getWidth();
      height = properties.getHeight();
      depth = properties.getDepth();
      freq = properties.getFreq();
      fullscreen = properties.getFullscreen();
      try {
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
         display.createWindow(width, height, depth, freq, fullscreen);

         cam = display.getRenderer().createCamera(width, height);
      } catch (JmeException e) {
         e.printStackTrace();
         System.exit(1);
      }

      // set the background to black
      display.getRenderer().setBackgroundColor(ColorRGBA.black.clone());

      // initialize the camera
      cam.setFrustumPerspective(45.0f, (float) width / (float) height, 1,
            3000);
      cam.setLocation(new Vector3f(200, 1000, 200));

      cam.update();

      timer = Timer.getTimer();

      display.getRenderer().setCamera(cam);

      KeyBindingManager.getKeyBindingManager().set("exit",
            KeyInput.KEY_ESCAPE);

   }

   @Override
   protected void initGame() {
      scene = new Node("Scene graph node");

      // create a ZBuffer
      ZBufferState buf = display.getRenderer().createZBufferState();
      buf.setEnabled(true);
      buf.setFunction(ZBufferState.CF_LEQUAL);
      scene.setRenderState(buf);

      CullState cs = display.getRenderer().createCullState();
      cs.setCullMode(CullState.CS_NONE);
      scene.setRenderState(cs);

      // light for space
      //buildLighting();

      // build space
      // buildSpace();
      buildSol();

      // put in ship
      buildShip();

      // buildBullet();

      // put in planet
      buildPlanet();

      buildSun();

      buildChaseCamera();

      buildInput();

      // update the scene graph for rendering
      scene.updateGeometricState(0.0f, true);
      scene.updateRenderState();

   }

   protected void buildLighting() {
      // setup a basic light
      DirectionalLight light = new DirectionalLight();
      light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
      light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
      // light.setLocation(new Vector3f(1,-1,1));
      light.setAttenuate(false);
      light.setShadowCaster(true);

      light.setDirection(new Vector3f(1, -2, 0));

      light.setEnabled(true);

      // attached light to a lightstate and the lightstate to the rootNode
      LightState lightstate = display.getRenderer().createLightState();
      lightstate.setEnabled(true);
      lightstate.attach(light);
      scene.setRenderState(lightstate);
   }

   /*
   protected void buildSpace() {
      skybox = new Skybox("skybox", 10, 10, 10);

      Texture north = TextureManager.loadTexture(CakeProto.class
            .getClassLoader()
            .getResource("jmetest/data/texture/space1.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      Texture south = TextureManager.loadTexture(CakeProto.class
            .getClassLoader()
            .getResource("jmetest/data/texture/space2.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      Texture east = TextureManager.loadTexture(CakeProto.class
            .getClassLoader()
            .getResource("jmetest/data/texture/space1.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      Texture west = TextureManager.loadTexture(CakeProto.class
            .getClassLoader()
            .getResource("jmetest/data/texture/space2.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      Texture up = TextureManager.loadTexture(CakeProto.class
            .getClassLoader()
            .getResource("jmetest/data/texture/space4.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      Texture down = TextureManager.loadTexture(CakeProto.class
            .getClassLoader()
            .getResource("jmetest/data/texture/space4.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      skybox.setTexture(Skybox.NORTH, north);
      skybox.setTexture(Skybox.SOUTH, south);
      skybox.setTexture(Skybox.EAST, east);
      skybox.setTexture(Skybox.WEST, west);
      skybox.setTexture(Skybox.UP, up);
      skybox.setTexture(Skybox.DOWN, down);
      skybox.setLightCombineMode(LightState.OFF);
      skybox.preloadTextures();
      scene.attachChild(skybox);
   }
   */

   private void buildShip() {
      Node model = null;
      try {
         MaxToJme C1 = new MaxToJme();
         ByteArrayOutputStream BO = new ByteArrayOutputStream();
         URL maxFile = CakeProto.class.getClassLoader().getResource(
               "Ship.3ds");
         C1.convert(new BufferedInputStream(maxFile.openStream()), BO);
         model = (Node) BinaryImporter.getInstance().load(
               new ByteArrayInputStream(BO.toByteArray()));
         // scale it to be MUCH smaller than it is originally
         model.setLocalScale(0.025f);
         model.setModelBound(new BoundingBox());
         model.updateModelBound();

         // scale it to be MUCH smaller than it is originally
         model.setLocalScale(.0025f);
      } catch (IOException e) {
         e.printStackTrace();
      }

      // set the vehicles attributes (these numbers can be thought
      // of as Unit/Second).

      ship = new Vehicle("Player Node", model);
      ship.setAcceleration(15);
      ship.setBraking(15);
      ship.setTurnSpeed(2.5f);
      ship.setWeight(25);
      ship.setMaxSpeed(25);
      ship.setMinSpeed(15);

      ship.setLocalTranslation(new Vector3f(100, 0, 100));
      scene.attachChild(ship);
      scene.updateGeometricState(0, true);
      ship.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
   }

   private void buildChaseCamera() {
      Vector3f targetOffset = new Vector3f();
      targetOffset.y = ((BoundingBox) ship.getWorldBound()).yExtent * 1.5f;
      HashMap<String, Object> props = new HashMap<String, Object>();
      props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "8");
      props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "2");
      props.put(ThirdPersonMouseLook.PROP_MAXASCENT, "" + 45
            * FastMath.DEG_TO_RAD);
      props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0,
            30 * FastMath.DEG_TO_RAD));
      props.put(ChaseCamera.PROP_TARGETOFFSET, targetOffset);
      props.put(ChaseCamera.PROP_DAMPINGK, "4");
      props.put(ChaseCamera.PROP_SPRINGK, "9");
      chaser = new ChaseCamera(cam, ship, props);
      chaser.setMaxDistance(8);
      chaser.setMinDistance(2);
   }

   private void buildPlanet() {
      Sphere s = new Sphere("Planet", 30, 30, 1f);
      s.setModelBound(new BoundingBox());
      s.updateModelBound();
      s.setLocalTranslation(5, 5, 5);
      s.setLocalScale(10);

      URL planetLOC;
      planetLOC = CakeProto.class.getClassLoader().getResource("mars.jpg");
      TextureState ts = display.getRenderer().createTextureState();
      Texture t = TextureManager.loadTexture(planetLOC, Texture.MM_LINEAR,
            Texture.FM_LINEAR);
      ts.setTexture(t);
      s.setRenderState(ts);

      scene.attachChild(s);
   }

   private void buildSun() {

      LightNode ln = new LightNode();
      ln.setLocalTranslation(300, 5, -500);

      // set up the star as a point light source
      PointLight pLight = new PointLight();
      pLight.setLocation(ln.getLocalTranslation());
      pLight.setEnabled(true);
      pLight.setShadowCaster(true);
      pLight.setAttenuate(true);
      pLight.setAmbient(ColorRGBA.white);
      pLight.setDiffuse(ColorRGBA.white);
      LightState lightstate = display.getRenderer().createLightState();
      lightstate.setEnabled(true);
      lightstate.attach(pLight);
      scene.setRenderState(lightstate);

      try {

         // import jme file from RenTextureEditor
         Spatial ogien = (Spatial) BinaryImporter.getInstance().load(
               CakeProto.class.getClassLoader().getResourceAsStream(
                     "starParticle.jme"));
         ogien.setLocalTranslation(ln.getLocalTranslation());

         ogien.setModelBound(new BoundingSphere());
         ogien.updateModelBound();
         ogien.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);

         AlphaState as1 = display.getRenderer().createAlphaState();
         as1.setBlendEnabled(true);
         as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
         as1.setDstFunction(AlphaState.DB_ONE);
         as1.setEnabled(true);
         ogien.setRenderState(as1);

         // set the texture for the particle
         TextureState ts = display.getRenderer().createTextureState();
         ts.setTexture(TextureManager.loadTexture(TestPointParticles.class
               .getClassLoader().getResource("flare1.png"),
               Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR));
         ts.setEnabled(true);
         ogien.setRenderState(ts);

         // enable point sprite mode, generate special texture coordinates
         // for points
         GL11.glEnable(ARBPointSprite.GL_POINT_SPRITE_ARB);
         GL11.glTexEnvi(ARBPointSprite.GL_POINT_SPRITE_ARB,
               ARBPointSprite.GL_COORD_REPLACE_ARB, 1);

         // set up the distance attenuation
         FloatBuffer ceoff = BufferUtils.createFloatBuffer(0.0f, 0.00001f,
               0.0f, 0.0f);
         ceoff.rewind();
         ARBPointParameters
               .glPointParameterARB(
                     ARBPointParameters.GL_POINT_DISTANCE_ATTENUATION_ARB,
                     ceoff);

         ZBufferState zbuf = DisplaySystem.getDisplaySystem().getRenderer()
               .createZBufferState();
         zbuf.setWritable(false);
         ogien.setRenderState(zbuf);
         ogien.updateRenderState();
         scene.attachChild(ogien);
         // ln.setLight(pLight);*/

         // set up lens flare effect
         TextureState[] textureState = new TextureState[4];
         textureState[0] = display.getRenderer().createTextureState();
         textureState[0].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare1.png"),
               Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
               Image.RGBA8888, 0.0f, true));
         // textureState[0].setEnabled(true);

         textureState[1] = display.getRenderer().createTextureState();
         textureState[1].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare2.png"),
               Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR));
         // textureState[1].setEnabled(true);

         textureState[2] = display.getRenderer().createTextureState();
         textureState[2].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare3.png"),
               Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR));
         // textureState[2].setEnabled(true);

         textureState[3] = display.getRenderer().createTextureState();
         textureState[3].setTexture(TextureManager.loadTexture(
               LensFlare.class.getClassLoader().getResource("flare4.png"),
               Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR));
         // textureState[3].setEnabled(true);

         LensFlare flare = LensFlareFactory.createBasicLensFlare("flare",
               textureState);
         flare.setRootNode(scene);
         // flare.setLocalTranslation(ln.getLocalTranslation());
         scene.attachChild(ln);
         ln.attachChild(flare);
         // scene.attachChild(flare);

      } catch (IOException ex) {
         ex.printStackTrace();
      }
   }

   // testing solar system without a box
   private void buildSol() {

      sol = new SkySphere("solTest", 100f);

      Texture solnorth = TextureManager.loadTexture(CakeProto.class
            .getClassLoader().getResource("space1.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
            Image.GUESS_FORMAT_NO_S3TC, 1.0f, true);

      sol.setTexture(solnorth);
      sol.preloadTextures();
      scene.attachChild(sol);
      sol.updateRenderState();
   }

   /*
   private void buildBullet() {
      Node model = null;
      Sphere bulletModel = new Sphere("bullet" + numBullets++, 8, 8, 0.25f);
      bulletModel.setModelBound(new BoundingSphere());
      bulletModel.updateModelBound();
      bulletMaterial = display.getRenderer().createMaterialState();
      bulletMaterial.setEmissive(ColorRGBA.red.clone());

      bullet = new Weapons("Bullet Node", model);

      bullet.setWeaponVelocity(100);

      bullet.setLocalTranslation(new Vector3f(ship.getWorldTranslation()));
      ship.attachChild(bullet);
      ship.updateGeometricState(0, true);
      bullet.updateRenderState();
   }
   */

   private void buildInput() {
      input = new shipInput(ship, properties.getRenderer());
   }

   @Override
   protected void reinit() {
      display.recreateWindow(width, height, depth, freq, fullscreen);
   }

   @Override
   protected void cleanup() {

   }
}


hmm well, i had to comment a few things out, to make it runnable and i added a firstperson controller to move around easy, but then i saw the particle effect and two lensflares.

what exactly is not working, is it not visible at all or not behaving as expected?

It's not visible at all.



I'm expecting it to come out of the star…of course…but I just don't see it. I've been searching on the forums and I'm thinking that maybe I'm not attaching it to the right parent…or maybe culling is a factor…or maybe some other light effect is taking precedence. Again…been staring at it for the better part of a day and I can't see it :wink:

Got it working.



Big thanks to Core-Dump for looking at my stuff and figuring it out. So yeah…I'll be coming here instead of waiting for my eyes to bleed