Package com.badlogic.gdx.graphics.g3d.particles.batches

Source Code of com.badlogic.gdx.graphics.g3d.particles.batches.PointSpriteParticleBatch

package com.badlogic.gdx.graphics.g3d.particles.batches;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Renderable;
import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.DepthTestAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.g3d.particles.ParallelArray.FloatChannel;
import com.badlogic.gdx.graphics.g3d.particles.ParticleChannels;
import com.badlogic.gdx.graphics.g3d.particles.ParticleShader;
import com.badlogic.gdx.graphics.g3d.particles.ParticleShader.ParticleType;
import com.badlogic.gdx.graphics.g3d.particles.ResourceData;
import com.badlogic.gdx.graphics.g3d.particles.ResourceData.SaveData;
import com.badlogic.gdx.graphics.g3d.particles.renderers.PointSpriteControllerRenderData;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;

/** This class is used to draw particles as point sprites.
* @author Inferno */
public class PointSpriteParticleBatch extends BufferedParticleBatch<PointSpriteControllerRenderData> {
  private static boolean pointSpritesEnabled = false;
  protected static final Vector3 TMP_V1 = new Vector3();
  protected static final int sizeAndRotationUsage = 1 << 9;
  protected static final VertexAttributes CPU_ATTRIBUTES = new VertexAttributes(
    new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE),
    new VertexAttribute(Usage.Color, 4, ShaderProgram.COLOR_ATTRIBUTE),
    new VertexAttribute(Usage.TextureCoordinates, 4, "a_region"),
    new VertexAttribute(sizeAndRotationUsage, 3, "a_sizeAndRotation"));
  protected static final int CPU_VERTEX_SIZE = (short)(CPU_ATTRIBUTES.vertexSize / 4),
                    CPU_POSITION_OFFSET = (short)(CPU_ATTRIBUTES.findByUsage(Usage.Position).offset/4),
                    CPU_COLOR_OFFSET = (short)(CPU_ATTRIBUTES.findByUsage(Usage.Color).offset/4),
                    CPU_REGION_OFFSET = (short)(CPU_ATTRIBUTES.findByUsage(Usage.TextureCoordinates).offset/4),
                    CPU_SIZE_AND_ROTATION_OFFSET = (short)(CPU_ATTRIBUTES.findByUsage(sizeAndRotationUsage).offset/4);

  private static void enablePointSprites () {
    Gdx.gl.glEnable(GL20.GL_VERTEX_PROGRAM_POINT_SIZE);
    if(Gdx.app.getType() == ApplicationType.Desktop) {
      Gdx.gl.glEnable(0x8861); // GL_POINT_OES
    }
    pointSpritesEnabled = true;
  }
 
  private float[] vertices;
  Renderable renderable;
 
  public PointSpriteParticleBatch () {
    this(1000);
  }
 
  public PointSpriteParticleBatch (int capacity) {
    super(PointSpriteControllerRenderData.class);
   
    if(!pointSpritesEnabled)
      enablePointSprites();
     
    allocRenderable();
    ensureCapacity(capacity);
    renderable.shader = new ParticleShader(renderable, new ParticleShader.Config(ParticleType.Point));
    renderable.shader.init();
  }

  @Override
  protected void allocParticlesData(int capacity){
    vertices = new float[capacity * CPU_VERTEX_SIZE];
    if(renderable.mesh != null)
      renderable.mesh.dispose();
    renderable.mesh = new Mesh(false, capacity, 0, CPU_ATTRIBUTES);
  }
 
  protected void allocRenderable(){
    renderable = new Renderable();
    renderable.primitiveType = GL20.GL_POINTS;
    renderable.meshPartOffset = 0;
    renderable.material = new Materialnew BlendingAttribute(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA, 1f),
      new DepthTestAttribute(GL20.GL_LEQUAL, false),
      TextureAttribute.createDiffuse(null));
  }

  public void setTexture(Texture texture){
    TextureAttribute attribute = (TextureAttribute) renderable.material.get(TextureAttribute.Diffuse);
    attribute.textureDescription.texture = texture;
  }

  public Texture getTexture () {
    TextureAttribute attribute = (TextureAttribute) renderable.material.get(TextureAttribute.Diffuse);
    return attribute.textureDescription.texture;
  }
 
  @Override
  protected void flush(int[] offsets){
    int tp = 0;
    for(PointSpriteControllerRenderData data: renderData){
      FloatChannel scaleChannel = data.scaleChannel;
      FloatChannel regionChannel = data.regionChannel;
      FloatChannel positionChannel = data.positionChannel;
      FloatChannel colorChannel = data.colorChannel;
      FloatChannel rotationChannel = data.rotationChannel;
     
      for (int p = 0; p < data.controller.particles.size; ++p, ++tp) {
        int offset = offsets[tp]*CPU_VERTEX_SIZE;
        int regionOffset = p*regionChannel.strideSize;
        int positionOffset = p*positionChannel.strideSize;
        int colorOffset = p*colorChannel.strideSize;
        int rotationOffset = p*rotationChannel.strideSize;
       
        vertices[offset + CPU_POSITION_OFFSET] = positionChannel.data[positionOffset + ParticleChannels.XOffset];
        vertices[offset + CPU_POSITION_OFFSET+1] = positionChannel.data[positionOffset + ParticleChannels.YOffset];
        vertices[offset + CPU_POSITION_OFFSET+2] = positionChannel.data[positionOffset + ParticleChannels.ZOffset];
        vertices[offset + CPU_COLOR_OFFSET] = colorChannel.data[colorOffset + ParticleChannels.RedOffset];
        vertices[offset + CPU_COLOR_OFFSET+1] = colorChannel.data[colorOffset + ParticleChannels.GreenOffset];
        vertices[offset + CPU_COLOR_OFFSET+2] = colorChannel.data[colorOffset + ParticleChannels.BlueOffset];
        vertices[offset + CPU_COLOR_OFFSET+3] = colorChannel.data[colorOffset + ParticleChannels.AlphaOffset];
        vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET] = scaleChannel.data[p* scaleChannel.strideSize];
        vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET+1] = rotationChannel.data[rotationOffset + ParticleChannels.CosineOffset];
        vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET+2] = rotationChannel.data[rotationOffset + ParticleChannels.SineOffset];
        vertices[offset + CPU_REGION_OFFSET] = regionChannel.data[regionOffset + ParticleChannels.UOffset];
        vertices[offset + CPU_REGION_OFFSET+1] = regionChannel.data[regionOffset + ParticleChannels.VOffset];
        vertices[offset + CPU_REGION_OFFSET+2] = regionChannel.data[regionOffset + ParticleChannels.U2Offset];
        vertices[offset + CPU_REGION_OFFSET+3] = regionChannel.data[regionOffset + ParticleChannels.V2Offset];
      }
    }

    renderable.meshPartSize = bufferedParticlesCount;
    renderable.mesh.setVertices(vertices, 0, bufferedParticlesCount*CPU_VERTEX_SIZE);
  }

  @Override
  public void getRenderables (Array<Renderable> renderables, Pool<Renderable> pool) {
    if(bufferedParticlesCount > 0)
      renderables.add(pool.obtain().set(renderable));
  }

  @Override
  public void save (AssetManager manager, ResourceData resources) {
    SaveData data = resources.createSaveData("pointSpriteBatch");
    data.saveAsset(manager.getAssetFileName(getTexture()), Texture.class);
  }

  @Override
  public void load (AssetManager manager, ResourceData resources) {
    SaveData data = resources.getSaveData("pointSpriteBatch");
    if(data != null)
      setTexture((Texture)manager.get(data.loadAsset()));
  }
}
TOP

Related Classes of com.badlogic.gdx.graphics.g3d.particles.batches.PointSpriteParticleBatch

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.