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:
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.