Package Hexel.rendering

Source Code of Hexel.rendering.ChunkRenderer

package Hexel.rendering;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.fixedfunc.GLPointerFunc;

import Hexel.Engine;
import Hexel.LogData;
import Hexel.chunk.Chunk;
import Hexel.chunk.Chunks;
import Hexel.math.HexGeometry;
import Hexel.math.Vector2d;
import Hexel.math.Vector3i;

import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.util.texture.awt.AWTTextureIO;

public class ChunkRenderer {

  private Chunks chunks;

  private Texture ttex;

  private LinkedBlockingQueue<GLChunk> glChunksToLoad = new LinkedBlockingQueue<GLChunk>();
  private HashMap<Vector3i, GLChunk> glChunkTable = new HashMap<Vector3i, GLChunk>();

  private Integer chunksToLoad = 0;
 
  private Engine engine;

  public HashMap<Vector3i, GLChunk> getGLChunkTable() {
    return this.glChunkTable;
  }
 
  private ShaderProgram transparentsShader;
  private int tsUPMatrix;
  private int tsUMVMatrix;
  private int tsTex;

  private ShaderProgram solidsShader;
  private int ssUPMatrix;
  private int ssUMVMatrix;
  private int ssTex;


  private ExecutorService chunkVertexBufferGeneratorThreadPool = Executors
      .newFixedThreadPool(8);

  public ChunkRenderer(Engine engine, Chunks chunks) {
    this.engine = engine;
    this.chunks = chunks;
  }

  public void init(GLAutoDrawable drawable, GL2 gl) {
    try {
      this.loadTex(gl);
    } catch(IOException e){
      System.out.println("unable to load atlas");
      e.printStackTrace();
      System.exit(1);
    }
   
    ShaderCode tsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(),
        "shaders", "shaders/bin", "transparents", true);
    ShaderCode tsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
        "shaders", "shaders/bin", "transparents", true);
    tsVp.defaultShaderCustomization(gl, true, true);
    tsFp.defaultShaderCustomization(gl, true, true);
   
    transparentsShader = new ShaderProgram();
    transparentsShader.add(tsVp);
    transparentsShader.add(tsFp);
        if(!transparentsShader.link(gl, System.err)) {
            throw new GLException("could not link program: " + transparentsShader);
        }
        gl.glBindAttribLocation(transparentsShader.program(), 0, "aVertexPosition");
        gl.glBindAttribLocation(transparentsShader.program(), 1, "aTextureCoord");
        tsUPMatrix = gl.glGetUniformLocation(transparentsShader.program(), "uPMatrix");
        tsUMVMatrix = gl.glGetUniformLocation(transparentsShader.program(), "uMVMatrix");
        tsTex = gl.glGetUniformLocation(transparentsShader.program(), "uSampler");

       
    ShaderCode ssVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(),
        "shaders", "shaders/bin", "solids", true);
    ShaderCode ssFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
        "shaders", "shaders/bin", "solids", true);
    ssVp.defaultShaderCustomization(gl, true, true);
    ssFp.defaultShaderCustomization(gl, true, true);
   
    solidsShader = new ShaderProgram();
    solidsShader.add(ssVp);
    solidsShader.add(ssFp);
        if(!solidsShader.link(gl, System.err)) {
            throw new GLException("could not link program: " + solidsShader);
        }
        gl.glBindAttribLocation(solidsShader.program(), 0, "aVertexPosition");
        gl.glBindAttribLocation(solidsShader.program(), 1, "aTextureCoord");
        gl.glBindAttribLocation(solidsShader.program(), 2, "aVertexColor");
        ssUPMatrix = gl.glGetUniformLocation(solidsShader.program(), "uPMatrix");
        ssUMVMatrix = gl.glGetUniformLocation(solidsShader.program(), "uMVMatrix");
        ssTex = gl.glGetUniformLocation(solidsShader.program(), "uSampler");
       
       
    gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
        GL.GL_NEAREST);
    gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
        GL.GL_NEAREST);
  }

  private void loadTex(GL2 gl) throws IOException{
    BufferedImage atlas = TextureAtlas.getAtlas();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(atlas, "png", baos);
    InputStream is = new ByteArrayInputStream(baos.toByteArray());
    TextureData data = TextureIO.newTextureData(gl.getGLProfile(), is, false, "png");
    this.ttex = TextureIO.newTexture(data);
  }

  public void loadChunks(final ArrayList<Vector3i> points) {
    if (points.size() == 0)
      return;
    for (Vector3i p : points) {
      if (!hasChunk(p))
        this.glChunkTable.put(p, null);
    }
    synchronized (chunksToLoad){
      chunksToLoad += points.size();
      LogData.set("chunksToLoad", "" + chunksToLoad);
    }
    this.chunkVertexBufferGeneratorThreadPool.execute(new Runnable() {
      @Override
      public void run() {
        for (Vector3i point : points) {
          Chunk chunk = ChunkRenderer.this.chunks.getChunk(point);
          GLChunk glChunk = new GLChunk(engine, chunk, ChunkRenderer.this.chunks);
          glChunk.position = new Vector3i(chunk.cx, chunk.cy,
              chunk.cz);
          glChunk.genArrayList();
          ChunkRenderer.this.loadGLChunk(glChunk);
          synchronized (chunksToLoad){
            chunksToLoad -= 1;
            LogData.set("chunksToLoad", "" + chunksToLoad);
          }
        }
      }
    });
  }

  public boolean hasChunk(Vector3i pos) {
    return this.glChunkTable.containsKey(pos);
  }

  public void loadGLChunk(GLChunk glChunk) {
    this.glChunksToLoad.add(glChunk);
  }

  public void unloadGLChunk(Vector3i pos) {
    this.glChunkTable.remove(pos);
  }

  public void update(GL2 gl) {
    int i = 0;
    LogData.set("chunksToBuffer", "" + this.glChunksToLoad.size());
    while (!this.glChunksToLoad.isEmpty()) {
      GLChunk glChunk = this.glChunksToLoad.poll();
      glChunk.initBuffer(gl);
      this.glChunkTable.put(glChunk.position, glChunk);
      i++;
      if (i > 10)
        break;
    }
    LogData.set("chunksToBuffer", "" + this.glChunksToLoad.size());
  }

  public void render(GL2 gl) {

    this.ttex.enable(gl);
    this.ttex.bind(gl);;

    Iterator<Map.Entry<Vector3i, GLChunk>> it = this.glChunkTable.entrySet().iterator();
    solidsShader.useProgram(gl, true);
    it = this.glChunkTable.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry<Vector3i, GLChunk> entry = it.next();
      Vector3i position = entry.getKey();
      GLChunk glChunk = entry.getValue();

      if (glChunk == null || glChunk.buffer == null)
        continue;

      gl.glPushMatrix();

      Vector2d hexPosition = new Vector2d();
      HexGeometry.hexToCartesian(position.x, position.y, hexPosition);

      gl.glTranslatef((float) (hexPosition.x * 16),
          (float) (hexPosition.y * 16), position.z * 16);

      gl.glBindBuffer(GL.GL_ARRAY_BUFFER, glChunk.buffer.id[0]);
      gl.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, 9*4, 0);
      gl.glVertexAttribPointer(1, 2, GL.GL_FLOAT, false, 9*4, 3*4);
      gl.glVertexAttribPointer(2, 4, GL.GL_FLOAT, false, 9*4, 5*4);
      gl.glEnableVertexAttribArray(0);
      gl.glEnableVertexAttribArray(1);
      gl.glEnableVertexAttribArray(2);
     
      float[] mv = new float[16];
      gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, mv, 0);
      gl.glUniformMatrix4fv(ssUMVMatrix, 1, false, mv, 0);
      float[] p = new float[16];
      gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX, p, 0);
      gl.glUniformMatrix4fv(ssUPMatrix, 1, false, p, 0);
     
      gl.glUniform1i(ssTex, 0);

      gl.glDrawArrays(GL.GL_TRIANGLES, 0, glChunk.buffer.size / (4 * 9));
     
      gl.glDisableVertexAttribArray(0);
      gl.glDisableVertexAttribArray(1);
      gl.glDisableVertexAttribArray(2);
      gl.glPopMatrix();
    }
    solidsShader.useProgram(gl, false);

    transparentsShader.useProgram(gl, true);
    it = this.glChunkTable.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry<Vector3i, GLChunk> entry = it.next();
      Vector3i position = entry.getKey();
      GLChunk glChunk = entry.getValue();

      if (glChunk == null || glChunk.buffer == null)
        continue;

      gl.glPushMatrix();

      Vector2d hexPosition = new Vector2d();
      HexGeometry.hexToCartesian(position.x, position.y, hexPosition);

      gl.glTranslatef((float) (hexPosition.x * 16),
          (float) (hexPosition.y * 16), position.z * 16);

      gl.glBindBuffer(GL.GL_ARRAY_BUFFER, glChunk.buffer.id[0]);
      gl.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, 9*4, 0);
      gl.glVertexAttribPointer(1, 2, GL.GL_FLOAT, false, 9*4, 3*4);
      gl.glEnableVertexAttribArray(0);
      gl.glEnableVertexAttribArray(1);
     
      float[] mv = new float[16];
      gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, mv, 0);
      gl.glUniformMatrix4fv(tsUMVMatrix, 1, false, mv, 0);
      float[] p = new float[16];
      gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX, p, 0);
      gl.glUniformMatrix4fv(tsUPMatrix, 1, false, p, 0);
     
      gl.glUniform1i(tsTex, 0);

      gl.glDrawArrays(GL.GL_TRIANGLES, 0, glChunk.buffer.size / (4 * 9));
     
      gl.glDisableVertexAttribArray(0);
      gl.glDisableVertexAttribArray(1);
      gl.glPopMatrix();
    }
    transparentsShader.useProgram(gl, false);

    this.ttex.disable(gl);
  }
}
TOP

Related Classes of Hexel.rendering.ChunkRenderer

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.