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); } }