Transparency issues in P3D

Hello everyone, I am trying to code a voxel game in java with processing, but when generating structures like trees with transparent leaves and textures, the textures always have a weird blue color (the color of the sky). It’s even worse when drawing a sprite (a kind of x shape) because it’s a blue rectangle with textures scribbled onto it. Here is the source code for the cube class:

import processing.core.PApplet;
import processing.core.PVector;
import processing.core.PConstants;
public class Cube {
	float size;
	  public boolean isTransparent;
//	  PVector frontPos, backPos, topPos, leftPos, rightPos, bottomPos;
//	  ArrayList<Vector4> vertices;
  boolean wireframe;
  PVector position = new PVector(0, 0, 0);
  Chunk belongsTo;
  MultiTexture textures;
  AABB collisionBox;
  PApplet app;
  float x1, y1, z1, x2, y2, z2;
  public static enum renderType{BLOCK, SPRITE};
  public renderType type;
  boolean isSolid;
  TextureManager manager;
  String name;
//  ArrayList<Vector4> vertices = new ArrayList<Vector4>();
  Cube(float s, PApplet p, Chunk c) {
	    size = s;
	    x1 = y1 = z1 = -s/2;
	    x2 = y2 = z2 = s/2;
	    collisionBox = new AABB(new PVector(x1, y1, z1), new PVector(x2, y2, z2));
	    isTransparent = false;
	    name = "";
//	    frontPos = backPos = topPos = leftPos = rightPos = bottomPos = new PVector(0, 0, 0);
	    /*
	    vertices = new ArrayList<Vector4>();
	    vertices.add(new Vector4(-1, -1, -1));
	    vertices.add(new Vector4(1, -1, -1));
	    vertices.add(new Vector4(1, 1, -1));
	    vertices.add(new Vector4(-1, 1, -1));
	    
	    vertices.add(new Vector4(1, -1, -1));
	    vertices.add(new Vector4(1, -1, 1));
	    vertices.add(new Vector4(1, 1, 1));
	    vertices.add(new Vector4(1, 1, -1));
	    
	    vertices.add(new Vector4(1, -1, 1));
	    vertices.add(new Vector4(-1, -1, 1));
	    vertices.add(new Vector4(-1, 1, 1));
	    vertices.add(new Vector4(1, 1, 1));
	    
	    vertices.add(new Vector4(-1, -1, 1));
	    vertices.add(new Vector4(-1, -1, -1));
	    vertices.add(new Vector4(-1, 1, -1));
	    vertices.add(new Vector4(-1, 1, 1));
	    
	    vertices.add(new Vector4(-1, -1, 1));
	    vertices.add(new Vector4(1, -1, 1));
	    vertices.add(new Vector4(1, -1, -1));
	    vertices.add(new Vector4(-1, -1, -1));
	    */
	app = p;
	textures = new MultiTexture();
	belongsTo = c;  
    wireframe = false;
    isSolid = true;
    manager = Minecraft.manager;
    app.textureMode(PConstants.NORMAL);
  }
  public void setRenderType(renderType type) {
		this.type = type;
	}
  public void generateMesh() {
	  belongsTo.mesh.noStroke();
	  belongsTo.mesh.noFill();
	  belongsTo.mesh.tint(255);
	  if(type == renderType.BLOCK) {
	  if(name == "Leaves") {
	    	belongsTo.mesh.tint(72, 181, 24);
	    }
	    if (!isFaceAt(position.x, position.y, position.z - 1)) {
	    	belongsTo.mesh.vertex(x1, y1, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	        belongsTo.mesh.vertex(x2, y1, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	        belongsTo.mesh.vertex(x2, y2, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	        belongsTo.mesh.vertex(x1, y2, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    belongsTo.mesh.tint(255);
	    if(name == "Leaves") {
	    	belongsTo.mesh.tint(72, 181, 24);
	    }
	    if (!isFaceAt(position.x + 1, position.y, position.z)) {
	    	belongsTo.mesh.vertex(x2, y1, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x2, y1, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x2, y2, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x2, y2, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    belongsTo.mesh.tint(255);
	    if(name == "Leaves") {
	    	belongsTo.mesh.tint(72, 181, 24);
	    }
	    if (!isFaceAt(position.x, position.y, position.z + 1)) {
	    	belongsTo.mesh.vertex(x2, y1, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y1, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y2, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x2, y2, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    belongsTo.mesh.tint(255);
	    if(name == "Leaves") {
	    	belongsTo.mesh.tint(72, 181, 24);
	    }
	    if (!isFaceAt(position.x - 1, position.y, position.z)) {
	    	belongsTo.mesh.vertex(x1, y1, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y1, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y2, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x1, y2, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    belongsTo.mesh.tint(255);
	    if(name == "GrassBlock") {
	    belongsTo.mesh.tint(100, 255, 100);
	    } else if(name == "Leaves") {
	    	belongsTo.mesh.tint(72, 181, 24);
	    }
		    if (!isFaceAt(position.x, position.y - 1, position.z)) {
		    	belongsTo.mesh.vertex(x1, y1, z2, manager.getTextureIndex(textures.TOP).minX, manager.getTextureIndex(textures.TOP).minY);
		    	belongsTo.mesh.vertex(x2, y1, z2, manager.getTextureIndex(textures.TOP).maxX, manager.getTextureIndex(textures.TOP).minY);
		    	belongsTo.mesh.vertex(x2, y1, z1, manager.getTextureIndex(textures.TOP).maxX, manager.getTextureIndex(textures.TOP).maxY);
		    	belongsTo.mesh.vertex(x1, y1, z1, manager.getTextureIndex(textures.TOP).minX, manager.getTextureIndex(textures.TOP).maxY);
		    }
	   belongsTo.mesh.tint(255);
	  } else if(type == renderType.SPRITE) {
		  if(name == "TallGrass") {
			  belongsTo.mesh.tint(100, 255, 100);
		  }
	    	belongsTo.mesh.vertex(x1, y1, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x2, y1, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x2, y2, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x1, y2, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    	
	    	belongsTo.mesh.vertex(x1, y1, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x2, y1, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x2, y2, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x1, y2, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    	
	    	belongsTo.mesh.vertex(x2, y1, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y1, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y2, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x2, y2, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    	
	    	belongsTo.mesh.vertex(x2, y1, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y1, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	belongsTo.mesh.vertex(x1, y2, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	belongsTo.mesh.vertex(x2, y2, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
		  }
  }
  public void setPosition(float a, float b, float c) {
	  position = new PVector(a, b, c);
//	  position.add(belongsTo.position);
//	  backPos = new PVector(position.x, position.y, (float) (position.z + 0.5f));
//	  frontPos = new PVector(position.x, position.y, (float) (position.z - 0.5f));
//	  rightPos = new PVector((float) (position.x + 0.5f), position.y, position.z);
//	  leftPos = new PVector((float) (position.x - 0.5f), position.y, position.z);
//	  topPos = new PVector(position.x, (float) (position.y - 0.5f), position.z);
//	  bottomPos = new PVector(position.x, (float) (position.y + 0.5f), position.z);
//	  for(int i = 0; i < vertices.size(); i++) {
//		  vertices.get(i).x += x;
//		  vertices.get(i).y += y;
//		  vertices.get(i).z += z;
//	  }
	  x1 += a * size;
	  y1 += b * size;
	  z1 += c * size;
	  x2 += a * size;
	  y2 += b * size;
	  z2 += c * size;
  }
  public float round3(float x) {
	  float a = Math.round(x);
	  float b = a / size;
	  float c = Math.round(b);
	  float d = c * size;
	  return d;
	}
  public PVector getPixelPosition() {
	return new PVector(position.x*size, position.y*size, position.z*size);  
  }
  public void show() {
	  /*
	    if (!wireframe) {
	      app.noStroke();
	    } else {
	      app.stroke(0);
	      app.noFill();
	      app.noTexture();
	    }
	    if(isTransparent) {
	    	app.tint(255, 200);
	    } else {
	    	app.noTint();
	    }
	    app.beginShape(PConstants.QUADS);
	    if(!wireframe) {
	    app.texture(Minecraft.textureAtlas);
	    }
	    // front
	    if (!isFaceAt(position.x, position.y, position.z - 1)) {
	    	app.vertex(x1, y1, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	        app.vertex(x2, y1, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	        app.vertex(x2, y2, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	        app.vertex(x1, y2, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    // right
	    if (!isFaceAt(position.x + 1, position.y, position.z)) {
	    	app.vertex(x2, y1, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	app.vertex(x2, y1, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	app.vertex(x2, y2, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	app.vertex(x2, y2, z1, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    // back
	    if (!isFaceAt(position.x, position.y, position.z + 1)) {
	    	app.vertex(x2, y1, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	app.vertex(x1, y1, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	app.vertex(x1, y2, z2, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	app.vertex(x2, y2, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    // left
	    if (!isFaceAt(position.x - 1, position.y, position.z)) {
	    	app.vertex(x1, y1, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).minY);
	    	app.vertex(x1, y1, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).minY);
	    	app.vertex(x1, y2, z1, manager.getTextureIndex(textures.SIDES).maxX, manager.getTextureIndex(textures.SIDES).maxY);
	    	app.vertex(x1, y2, z2, manager.getTextureIndex(textures.SIDES).minX, manager.getTextureIndex(textures.SIDES).maxY);
	    }
	    // top
	    if (!isFaceAt(position.x, position.y - 1, position.z)) {
	    	app.vertex(x1, y1, z2, manager.getTextureIndex(textures.TOP).minX, manager.getTextureIndex(textures.TOP).minY);
	    	app.vertex(x2, y1, z2, manager.getTextureIndex(textures.TOP).maxX, manager.getTextureIndex(textures.TOP).minY);
	    	app.vertex(x2, y1, z1, manager.getTextureIndex(textures.TOP).maxX, manager.getTextureIndex(textures.TOP).maxY);
	    	app.vertex(x1, y1, z1, manager.getTextureIndex(textures.TOP).minX, manager.getTextureIndex(textures.TOP).maxY);
	    }
	    // bottom
	    if (!isFaceAt(position.x, position.y + 1, position.z)) {
	      app.beginShape(PConstants.QUAD);
	    	if(!wireframe) {
	    	app.texture(Minecraft.textureAtlas);
	    	}
	      app.vertex(x1, y2, z1, manager.getTextureIndex(textures.TOP).minX, manager.getTextureIndex(textures.TOP).minY);
		  app.vertex(x2, y2, z1, manager.getTextureIndex(textures.TOP).maxX, manager.getTextureIndex(textures.TOP).minY);
		  app.vertex(x2, y2, z2, manager.getTextureIndex(textures.TOP).maxX, manager.getTextureIndex(textures.TOP).maxY);
		  app.vertex(x1, y2, z2, manager.getTextureIndex(textures.TOP).minX, manager.getTextureIndex(textures.TOP).maxY);
	      app.endShape(PConstants.CLOSE);
		    }
	    app.endShape(PConstants.CLOSE);
	    */
  }
  public boolean isFaceAt(double x, double y, double z) {
	  Cube[][][] c = belongsTo.chunk;
	  PVector pos = new PVector((float) x, (float) y, (float) z);
	  for (int i = 0; i < Chunk.h; i++) {
	    for (int j = 0; j < Chunk.w; j++) {
	      for (int k = 0; k < Chunk.d; k++) {
	    	if(c[j][i][k] != null) {
	          if (c[j][i][k].position.equals(pos) && c[j][i][k].isOpaque()) {
	            return true;
	            }
	          if(!isOpaque() && !c[j][i][k].isOpaque() && c[j][i][k].position.equals(pos)) {
	        	  return true;
	          }/* 
	          }
	          if (c[j][i][k].frontPos.equals(pos)) {
		            return true;
		            } else if (c[j][i][k].backPos.equals(pos)) {
			            return true;
		            } else if (c[j][i][k].rightPos.equals(pos)) {
			            return true;
		            } else if (c[j][i][k].leftPos.equals(pos)) {
			            return true;
		            } else if (c[j][i][k].topPos.equals(pos)) {
			            return true;
		            } else if (c[j][i][k].bottomPos.equals(pos)) {
			            return true;
		            }
		            */
	    	  }
	        }
	      }
	    }
	  return false;
	  }
  public boolean isOpaque() {
	  return !isTransparent;
  }
  public boolean isSolid() {
	  return isSolid;
  }
  public MultiTexture getTexture() {
	return textures;  
  }
}

Here is the source code for the chunk class:

import processing.core.PApplet;
import processing.core.PVector;
import processing.core.PShape;
import processing.core.PConstants;
class Chunk {
  Cube[][][] chunk;
  static int w = 8, h = 24, d = 8;
  public int size;
  PApplet app;
  PVector position = new PVector(0, 0, 0);
  int maxValue;
  PShape mesh;
  public Chunk(PApplet p, float x, float y, float z) {
	  app = p;
	  mesh = app.createShape();
	  mesh.setTexture(Minecraft.textureAtlas);
	  position = new PVector(x, y, z);
	  chunk = new Cube[w][h][d];
	  size = Minecraft.size;
	  generateTerrain(this);
	  generateMesh();
  }
  public void setPosition(int x, int y, int z) {
	position = new PVector(x, y, z);
  }
  public int[][] generateHeightMap() {
	int[][] map = new int[w][d];
	for(int i = 0; i < w; i++) {
		for(int j = 0; j < d; j++) {
		    int x = (int) (i + position.x);
		    int y = (int) (j + position.y);
			float e = Minecraft.generator.GetNoise(x, y);
//`			e *= 4;
			map[j][i] = (int) e;
		}
	}
	return map;
  }
  public void setTreeBlock(int x, int y, int z) {
	  if(inBounds(x, y, z)) {
		  chunk[z][y][x] = new OakBlock(size, app, this);
		  chunk[z][y][x].setPosition(z, y, x);
	  }
  }
  public void setLeavesBlock(int x, int y, int z, int xPos, int height, int zPos) {
	  if(inBounds(x, y, z)) {
		  chunk[z][y][x] = new Leaves(size, app, this);
		  chunk[z][y][x].setPosition(zPos, height, xPos);
	  }
  }
  public boolean isBlockAt(double x, double y, double z) {
		PVector pos = new PVector((float) x, (float) y, (float) z);
		if(!inBounds(pos.x, pos.y, pos.z)) {
			return false;
		}
		  for (int i = 0; i < w; i++) {
		    for (int j = 0; j < h; j++) {
		      for (int k = 0; k < d; k++) {
		    	if(chunk[j][i][k] != null && chunk[j][i][k].position.equals(pos)) {
				            return true;
		    	  }
		        }
		      }
		    }
		  return false;
	}
  public void generateTerrain(Chunk c) {
	int[][] map = generateHeightMap();
	  for (int i = 0; i < w; i++) {
		for (int j = 0; j < d; j++) {
			for(int k = 0; k < h; k++) {
				/*
			      int y2 = map[j][i];
			      if(y2 > 7) {
			    	  y2 = 7;
			      }
			      if(y2 < 0) {
			    	  y2 = 0;
			      }
			      chunk[j][i][y2] = new GrassBlock(size, app, c);
				  chunk[j][i][y2].setPosition(j,  y2,  i);
			      if(y2 >= k) {
			    	  chunk[j][i][k] = new WaterBlock(size, app, c);
			    	  chunk[j][i][k].setPosition(j, k, i);
			      }
			      */
				if(k == 15) {
			  chunk[j][k][i] = new GrassBlock(size, app, c);
			  chunk[j][k][i].setPosition(i, k, j);
				} else if (k >= 16 && k <= 17) {
					chunk[j][k][i] = new DirtBlock(size, app, c);
					chunk[j][k][i].setPosition(i, k, j);
				} else if(k >= 18 && k <= 22) {
					chunk[j][k][i] = new StoneBlock(size, app, c);
					chunk[j][k][i].setPosition(i, k, j);
				} else if(k == 23) {
					chunk[j][k][i] = new Bedrock(size, app, c);
					chunk[j][k][i].setPosition(i, k, j);
				}
				if(app.random(0, 1) <= 0.00025) {
					   generateTree(j, 15, i);	
					}
				if(app.random(0, 1) <= 0.0005) {
					chunk[j][14][i] = new TallGrass(size, app, c);
					chunk[j][14][i].setPosition(i, 14, j);
				}
		}
	  }
	}
  }
  public void generateTree(int x, int y, int z) {
	  int height = (int) (Math.round(app.random(4, 10)));
	  for(int i = 1; i < height; i++) {
		  chunk[z][y - i][x] = new OakBlock(size, app, this);
		  chunk[z][y - i][x].setPosition(x, y - i, z);
		if(i == height - 1) {
		  if(inBounds(z, y - i, x + 1)) {
		  chunk[z][y - i][x + 1] = new Leaves(size, app, this);
		  chunk[z][y - i][x + 1].setPosition(x + 1, y - i, z);
		    }
		  if(inBounds(z - 1, y - i, x + 1)) {
			  chunk[z - 1][y - i][x + 1] = new Leaves(size, app, this);
			  chunk[z - 1][y - i][x + 1].setPosition(x + 1, y - i, z - 1);
			    }
		  if(inBounds(z - 1, y - i, x - 1)) {
			  chunk[z - 1][y - i][x - 1] = new Leaves(size, app, this);
			  chunk[z - 1][y - i][x - 1].setPosition(x - 1, y - i, z - 1);
			    }
		  if(inBounds(z, y - i, x - 1)) {
			  chunk[z][y - i][x - 1] = new Leaves(size, app, this);
			  chunk[z][y - i][x - 1].setPosition(x - 1, y - i, z);
			    }
		  if(inBounds(z + 1, y - i, x)) {
			  chunk[z + 1][y - i][x] = new Leaves(size, app, this);
			  chunk[z + 1][y - i][x].setPosition(x, y - i, z + 1);
			    }
		  if(inBounds(z - 1, y - i, x)) {
			  chunk[z - 1][y - i][x] = new Leaves(size, app, this);
			  chunk[z - 1][y - i][x].setPosition(x, y - i, z - 1);
			    }
		  if(inBounds(z + 1, y - i, x + 1)) {
			  chunk[z + 1][y - i][x + 1] = new Leaves(size, app, this);
			  chunk[z + 1][y - i][x + 1].setPosition(x + 1, y - i, z + 1);
			    }
		  if(inBounds(z + 1, y - i, x - 1)) {
			  chunk[z + 1][y - i][x - 1] = new Leaves(size, app, this);
			  chunk[z + 1][y - i][x - 1].setPosition(x - 1, y - i, z + 1);
			    }
		  if(inBounds(z, y - i - 1, x)) {
			  chunk[z][y - i - 1][x] = new Leaves(size, app, this);
			  chunk[z][y - i - 1][x].setPosition(x, y - i - 1, z);
			    }
		  }
	  }
  }
  public PVector getPixelPosition() {
	  PVector p = new PVector(0, 0, 0);
		            p.x = position.x * (w*size);
		            p.y = position.y * (h*size);
		            p.z = position.z * (d*size);
		            return p;
		          }
  public float round3(float x) {
	  float a = Math.round(x);
	  float b = a / size;
	  float c = Math.round(b);
	  float d = c * size;
	  return d;
	}
  public PVector round2(PVector p) {
	  return new PVector(round3(p.x), round3(p.y), round3(p.z));
  }
  boolean inBounds(float a, float b, float c) {
	  return a < w && b < h && c < d && a > 0 && b > 0 && c > 0;
  }
  public void generateMesh() {
	  mesh.beginShape(PConstants.QUADS);
	  for (int i = 0; i < Chunk.h; i++) {
		    for (int j = 0; j < Chunk.w; j++) {
		      for (int k = 0; k < Chunk.d; k++) {
		    	  if(chunk[j][i][k] != null) {
		    		  chunk[j][i][k].generateMesh();
		    	  }
	    }
	  }
	}
	  mesh.endShape(PConstants.CLOSE);
  }
  public void render() {
	app.pushMatrix();
    app.translate(position.x * (w*size), position.y * (h*size), position.z * (d*size));
    app.shape(mesh);
    app.popMatrix();
  }
}

Here is the main class:

import processing.core.PApplet;
import processing.core.PVector;
import processing.core.PImage;
import processing.opengl.*; 
import com.jogamp.opengl.GL; 
import com.jogamp.opengl.GL2ES2;
public class Minecraft extends PApplet {
PJOGL pgl;
GL2ES2 gl;
public PImage clouds;
public Camera camera;
public static Chunk[][] chunks = new Chunk[16][16];
public static PImage textureAtlas;
public static int size = 100;
public static FastNoise generator = new FastNoise();
RayCaster caster;
MemoryProfiler profiler;
public static TextureManager manager;
Sky sky;
public void settings() {  
	size(displayWidth, displayHeight, P3D); 
	noSmooth();
	}
public static void main(String[] passedArgs) {
  String[] appletArgs = new String[] { "Minecraft" };
  if (passedArgs != null) {
    PApplet.main(concat(appletArgs, passedArgs));
  } else {
    PApplet.main(appletArgs);
  }
}
public static float round50(float x) {
    return Math.round((x+49)/50) * 50;
}
boolean inBounds(float a, float b, float c) {
	  return a < Chunk.w && b < Chunk.h && c < Chunk.d;
}
public void setup() {
    generator.SetSeed((int)random(Integer.MAX_VALUE));
    generator.SetNoiseType(FastNoise.NoiseType.Simplex);
	profiler = new MemoryProfiler(this);
	clouds = loadImage("assets/clouds.png");
	surface.setLocation(0, 0);
	hint(DISABLE_TEXTURE_MIPMAPS);
    ((PGraphicsOpenGL)g).textureSampling(2);
  camera = new Camera(this);
  sky = new Sky(this, clouds);
  sky.setColor(0, 255, 255);
  textureAtlas = loadImage("assets/terrain2.png");
  manager = new TextureManager();
  for(int i = 0; i < chunks.length; i++) {
	  for(int j = 0; j < chunks.length; j++) {
	chunks[j][i] = new Chunk(this, j, 0, i);
	  }
  }
  for(int i = 0; i < chunks.length; i++) {
	  for(int j = 0; j < chunks.length; j++) {
	chunks[j][i].generateMesh();
	  }
  }
  pgl = (PJOGL) beginPGL();
  caster = new RayCaster(this);
}
public void keyPressed() {
if (key == ' ') {
  for(int x = 0; x < chunks.length; x++) {
	  for(int y = 0; y < chunks.length; y++) {
    for (int i = 0; i < Chunk.h; i++) {
      for (int j = 0; j < Chunk.w; j++) {
        for (int k = 0; k < Chunk.d; k++) {
        	if(chunks[y][x].chunk[j][i][k] != null) {
          chunks[y][x].chunk[j][i][k].wireframe = !chunks[y][x].chunk[j][i][k].wireframe;
              }
            }
          }
        }
	  }
    }
  }
}
public static float round2(float x) {
  float a = (float) Math.round(x);
  float b = a / (8*size);
  float c = (float) Math.round(b);
  float d = c * (8*size);
  return d;
}
public static float round3(float x) {
	float a = x / size;
	float b = Math.round(a);
	float c = b * size;
	return c;
	}
public static Cube getBlock(double a, double b, double z) {
	PVector pos = new PVector((float) a, (float) b, (float) z);
	  for(int x = 0; x < chunks.length; x++) {
		  for(int y = 0; y < chunks.length; y++) {
		  for (int i = 0; i < Chunk.h; i++) {
		    for (int j = 0; j < Chunk.w; j++) {
		      for (int k = 0; k < Chunk.d; k++) {
		    	  if(chunks[y][x].chunk[j][i][k] != null) {
		          if (chunks[y][x].chunk[j][i][k].position.equals(pos)) {
		            return chunks[y][x].chunk[j][i][k];
		            }
		    	  }
		        }
		      }
		    }
		  }
	  }
		  return null;
}
public static PVector PRound2(PVector p) {
    PVector x = new PVector(round3(p.x), round3(p.y), round3(p.z));
    x.div(Minecraft.size);
    return x;
}
public static void removeBlock(double x, double y, double z) {
	PVector pos = new PVector((float) x, (float) y, (float) z);
outer:	for(int a = 0; a < chunks.length; a++) {
		for(int b = 0; b < chunks.length; b++) {
	  for (int i = 0; i < chunks[b][a].chunk.length; i++) {
	    for (int j = 0; j < chunks[b][a].chunk.length; j++) {
	      for (int k = 0; k < chunks[b][a].chunk.length; k++) {
	    	if(chunks[b][a].chunk[j][i][k] != null) {
	          if (chunks[b][a].chunk[j][i][k].position.equals(pos)) {
	            chunks[b][a].chunk[j][i][k] = null;
	            break outer;
	            }
	          /*
	          if (chunks[b][a].chunk[j][i][k].frontPos.equals(pos)) {
	            	chunks[b][a].chunk[j][i][k] = null;
		            break outer;
		            } else if (chunks[b][a].chunk[j][i][k].rightPos.equals(pos)) {
		            	chunks[b][a].chunk[j][i][k] = null;
			            break outer;
		            } else if (chunks[b][a].chunk[j][i][k].backPos.equals(pos)) {
		            	chunks[b][a].chunk[j][i][k] = null;
			            break outer;
		            } else if (chunks[b][a].chunk[j][i][k].leftPos.equals(pos)) {
		            	chunks[b][a].chunk[j][i][k] = null;
			            break outer;
		            } else if (chunks[b][a].chunk[j][i][k].topPos.equals(pos)) {
		            	chunks[b][a].chunk[j][i][k] = null;
			            break outer;
		            } else if (chunks[b][a].chunk[j][i][k].bottomPos.equals(pos)) {
		            	chunks[b][a].chunk[j][i][k] = null;
			            break outer;
		            }
		            */
	    	  }
	        }
	      }
	    }
	  }
	}	
}
public static void placeBlock(float x, float y, float z) {
outer:	for(int a = 0; a < chunks.length; a++) {
		for(int b = 0; b < chunks.length; b++) {
	  for (int i = 0; i < chunks[b][a].chunk.length; i++) {
	    for (int j = 0; j < chunks[b][a].chunk.length; j++) {
	      for (int k = 0; k < chunks[b][a].chunk.length; k++) {
	    	if(chunks[b][a].chunk[j][i][k] != null) {
	          if (chunks[b][a].chunk[j][i][k].position.x == x && chunks[b][a].chunk[j][i][k].position.y == y && chunks[b][a].chunk[j][i][k].position.z == z) {
	        	  if(k > 0) {
	            chunks[b][a].chunk[j][i][k - 1] = new DirtBlock(size, chunks[b][a].chunk[j][i][k].app, chunks[b][a]);
	            chunks[b][a].chunk[j][i][k - 1].setPosition(x, y - 1, z);
	            break outer;
	        	  }
	            }
	    	  }
	        }
	      }
	    }
	  }
	}	
}
public static boolean isBlockAt(double x, double y, double z) {
	PVector pos = new PVector((float) x, (float) y, (float) z);
	for(int a = 0; a < chunks.length; a++) {
		for(int b = 0; b < chunks.length; b++) {
	  for (int i = 0; i < Chunk.w; i++) {
	    for (int j = 0; j < Chunk.h; j++) {
	      for (int k = 0; k < Chunk.d; k++) {
	    	if(chunks[b][a].chunk[j][i][k] != null && chunks[b][a].chunk[j][i][k].position.equals(pos)) {
			            return true;
		          /*
		          if (chunks[b][a].chunk[j][i][k].frontPos.equals(pos)) {
		            return true;
		            } else if (chunks[b][a].chunk[j][i][k].rightPos.equals(pos)) {
			            return true;
		            } else if (chunks[b][a].chunk[j][i][k].backPos.equals(pos)) {
			            return true;
		            } else if (chunks[b][a].chunk[j][i][k].leftPos.equals(pos)) {
			            return true;
		            } else if (chunks[b][a].chunk[j][i][k].topPos.equals(pos)) {
			            return true;
		            } else if (chunks[b][a].chunk[j][i][k].bottomPos.equals(pos)) {
			            return true;
		            }
		            */
	    	  }
	        }
	      }
	    }
	  }
	}
	  return false;
}
public static PVector roundPVector(PVector p) {
	  return new PVector(round50(p.x), round50(p.y), round50(p.z));
}
public void mousePressed() {
    	if(mouseButton == LEFT) {
    		Ray ray = caster.fireRay(roundPVector(camera.position), camera.getForward(), 10);
    		PVector pos = ray.hitPosition;
    		removeBlock(pos.x, pos.y, pos.z);
    	} else if(mouseButton == RIGHT) {
    		Ray ray = caster.fireRay(roundPVector(camera.position), camera.getForward(), 10);
    		PVector pos = ray.hitPosition;
    		placeBlock(pos.x, pos.y, pos.z);
    }
}
public void loadChunk(float x, float y, float z) {
	PVector pos = new PVector((float) x, (float) y, (float) z);
	  for(int i = 0; i < chunks.length; i++) {
		  for(int j = 0; j < chunks.length; j++) {
			  if(chunks[j][i].getPixelPosition().equals(pos)) {
			  	chunks[j][i].render(); 
			}
		  }
	    }	
}
public Chunk getChunk(float x, float y, float z) {
	PVector pos = new PVector((float) x, (float) y, (float) z);
	  for(int i = 0; i < chunks.length; i++) {
		  for(int j = 0; j < chunks.length; j++) {
			  if(chunks[j][i].position.equals(pos)) {
			  	return chunks[j][i];
			}
		  }
	    }	
	  return null;
}
public void draw() {
  System.out.println("FPS:" + round(frameRate));
  profiler.printMemoryUsage();
  sky.draw();
  gl = pgl.gl.getGL2ES2();
  gl.glEnable(GL.GL_CULL_FACE);
  gl.glCullFace(GL.GL_FRONT);
  PVector position = new PVector(round2(camera.position.x), 0, round2(camera.position.z));
  for(int i = 0; i < chunks.length; i++) {
	  for(int j = 0; j < chunks.length; j++) {
		  if(dist(position.x, position.z, chunks[j][i].getPixelPosition().x, chunks[j][i].getPixelPosition().z) <= 8000) {
			  chunks[j][i].render();
		  }
	  }
  }
  /*
  loadChunk(position.x - (8*size), position.y, position.z - (8*size));
  loadChunk(position.x - (8*size), position.y, position.z + (8*size));
  loadChunk(position.x + (8*size), position.y, position.z - (8*size));
  loadChunk(position.x + (8*size), position.y, position.z + (8*size));
  loadChunk(position.x - (8*size), position.y, position.z);
  loadChunk(position.x + (8*size), position.y, position.z);
  loadChunk(position.x, position.y, position.z - (8*size));
  loadChunk(position.x, position.y, position.z + (8*size));
  loadChunk(position.x, position.y, position.z);
  */
  /*
  Ray ray = caster.fireRay(camera.position, camera.getForward(), 10);
  PVector pos = ray.hitPosition.mult(size);
  stroke(0);
  noFill();
  pushMatrix();
  translate(pos.x, pos.y, pos.z);
  box(size)
  popMatrix();
  noStroke();
  */
  }
}

Tall Grass class (having transparency issues with textures):

import processing.core.PApplet;
public class TallGrass extends Cube {
	TallGrass(float s, PApplet p, Chunk c) {
		super(s, p, c);
		isTransparent = true;
		name = "TallGrass";
		setRenderType(renderType.SPRITE);
		textures.setTOP(7,2);
        textures.setSIDES(7,2);
        textures.setBOTTOM(7,2);
	}
}

And finally, the texture atlas:
terrain2

I don’t know why the textures aren’t transparent, and I can’t seem to figure it out. Please note that I left out many other classes in my game, such as the texture manager, the camera, and the sky.

1 Like

Here is a picture of the problem

The reason this happens is because processing tries to improve performance by calculating a transparent shape’s color only when it is drawn. So, if the transparent shape is drawn on top of the sky, it will have the sky’s color. I could be getting the reasoning wrong, but I do have a solution.
You need to draw all transparent shapes after drawing all non-transparent shapes so they calculate their transparency using the most “up to date” information. Depending on how you coded your program, this can be difficult. The way Unity handles this problem is by splitting it’s rendering into layers, then drawing the layers in a certain order. A way I did this for a simpler program is by sorting all of the drawn shapes by whether or not they are labeled transparent.

1 Like

Thanks, once I seperated the transparent and non-transparent meshes, transparent blocks appeared actually transparent. However, this only works when I’m rendering blocks, but with rendering sprites, some have full transparency while others have half-transparency, like this: