158 lines
5.9 KiB
Java

package de.frajul.particlelab.rendering;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import de.frajul.particlelab.data.Color;
import de.frajul.particlelab.entities.Entity;
import de.frajul.particlelab.entities.particles.ParticleEffect;
import de.frajul.particlelab.entities.particles.ParticleSource;
import de.frajul.particlelab.entities.particles.ParticleSystem;
import de.frajul.particlelab.entities.textures.TexturePack;
import de.frajul.particlelab.main.GameLog;
import de.frajul.particlelab.main.Scene;
/**
* Created by Julian on 22.11.2015.
*/
public class GameRenderer implements GLSurfaceView.Renderer {
private Rendering rendering;
private MatrixCreator matrixCreator;
private boolean additiveBlending;
private Color emptyColor;
private Context context;
private Quad quad;
//GL Context
private ShaderProgram shaderProgram;
private TexturePack texturePack;
private Timer timer;
public GameRenderer(Context context, Rendering rendering) {
this.context = context;
this.rendering = rendering;
emptyColor = new Color(-1, -1, -1);
matrixCreator = new MatrixCreator();
quad = new Quad();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GameLog.d("onSurfaceCreated");
GLES20.glClearColor(0, 0, 0, 1.0f);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
try {
shaderProgram = new ShaderProgram(context);
texturePack = new TexturePack(context);
timer = new Timer();
} catch (Exception e) {
rendering.onException(e);
}
rendering.initiate(texturePack, timer);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GameLog.d("onSurfaceChanged: width=" + width + ", height=" + height);
GLES20.glViewport(0, 0, width, height);
matrixCreator.setMVPMSize(width, height);
rendering.setScreenSize(width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
timer.update();
rendering.update();
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
Scene scene = rendering.getScene();
ParticleSystem particleSystem = scene.getParticleSystem();
// GLES20.glClearColor(0, 0, 0, 0.0f);
// GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//
// shaderProgram.start();
// shaderProgram.loadMVPMatrix(matrixCreator, scene.cameraX);
// synchronized (scene.getParticleSystem().getEffects()) {
// for (ParticleEffect effect : scene.getParticleSystem().getEffects()) {
// gl.glActiveTexture(GL10.GL_TEXTURE0);
// gl.glBindTexture(GL10.GL_TEXTURE_2D, effect.getTexture().getId());
// shaderProgram.loadTextureAtlasInfos(effect.getTexture());
//
// switchAdditiveBlending(gl, effect.getOptions().isAdditive());
// synchronized (effect.getSources()) {
// for (ParticleSource source : effect.getSources()) {
// source.getActiveParticleLock().lock();
// for (Entity particle : source.getActiveParticles())
// renderParticle(gl, particle);
// source.getActiveParticleLock().unlock();
// }
// }
// }
// }
// disableAdditiveBlending(gl);
//
// shaderProgram.stop();
shaderProgram.start();
shaderProgram.loadMVPMatrix(matrixCreator, scene.cameraX);
for (ParticleEffect effect : particleSystem.getEffects()) {
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, effect.getTexture().getId());
shaderProgram.loadTextureAtlasInfos(effect.getTexture());
if (effect.getOptions().isAdditive() && !additiveBlending)
enableAdditiveBlending(gl);
if (!effect.getOptions().isAdditive() && additiveBlending)
disableAdditiveBlending(gl);
for (ParticleSource source : effect.getSources()) {
source.getActiveParticleLock().lock();
for (Entity particle : source.getActiveParticles())
renderParticle(gl, particle);
source.getActiveParticleLock().unlock();
}
}
shaderProgram.stop();
}
private void switchAdditiveBlending(GL10 gl, boolean effectAdditive) {
if (effectAdditive && !additiveBlending)
enableAdditiveBlending(gl);
if (effectAdditive && additiveBlending)
disableAdditiveBlending(gl);
}
private void renderEntity(GL10 gl, Entity entity) {
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, entity.getTexture().getId());
shaderProgram.loadTransformationMatrix(matrixCreator, entity);
shaderProgram.loadAlpha(entity.getAlpha());
shaderProgram.loadTextureAtlasInfos(entity.getTexture());
shaderProgram.loadColor(entity.getColor() != null ? entity.getColor() : emptyColor);
quad.draw();
}
private void renderParticle(GL10 gl, Entity entity) {
shaderProgram.loadTransformationMatrix(matrixCreator, entity);
shaderProgram.loadAlpha(entity.getAlpha());
shaderProgram.loadColor(entity.getColor() != null ? entity.getColor() : emptyColor);
quad.draw();
}
private void enableAdditiveBlending(GL10 gl) {
additiveBlending = true;
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
}
private void disableAdditiveBlending(GL10 gl) {
additiveBlending = false;
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
}
}