Basic chunking done

This commit is contained in:
satellite 2021-04-04 14:58:22 -04:00
parent 5d4e5bc775
commit 4ced329a47
9 changed files with 537 additions and 166 deletions

View File

@ -44,6 +44,7 @@ public class EntityUtil {
} }
public static void cleanUpDrawableEntity(Entity e){ public static void cleanUpDrawableEntity(Entity e){
Globals.entityManager.deregisterEntity(e);
getEntityModel(e).free(); getEntityModel(e).free();
} }
} }

View File

@ -23,6 +23,7 @@ public class CellManager {
DrawCell[][] cells; DrawCell[][] cells;
boolean[][] valid; boolean[][] valid;
boolean[][] drawable; boolean[][] drawable;
boolean[][] updateable;
@ -31,16 +32,18 @@ public class CellManager {
int drawStepdownInterval = 2; int drawStepdownInterval = 2;
int drawStepdownValue = 10; int drawStepdownValue = 10;
public CellManager(TerrainManager terrainManager, float realX, int realY){ public CellManager(TerrainManager terrainManager, float realX, float realY){
this.terrainManager = terrainManager; this.terrainManager = terrainManager;
this.miniCellWidth = miniCellWidth; this.miniCellWidth = miniCellWidth;
cells = new DrawCell[drawRadius * 2 + 1][drawRadius * 2 + 1]; cells = new DrawCell[drawRadius * 2 + 1][drawRadius * 2 + 1];
valid = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; valid = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
drawable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; drawable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
updateable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
for(int x = 0; x < drawRadius * 2 + 1; x++){ for(int x = 0; x < drawRadius * 2 + 1; x++){
for(int y = 0; y < drawRadius * 2 + 1; y++){ for(int y = 0; y < drawRadius * 2 + 1; y++){
valid[x][y] = false; valid[x][y] = false;
drawable[x][y] = false; drawable[x][y] = false;
updateable[x][y] = false;
} }
} }
cellX = transformRealSpaceToCellSpace(realX); cellX = transformRealSpaceToCellSpace(realX);
@ -90,9 +93,17 @@ public class CellManager {
currentCellY >= 0 && currentCellY >= 0 &&
currentCellY < terrainManager.getWorldDiscreteSize() currentCellY < terrainManager.getWorldDiscreteSize()
){ ){
cells[targetX][targetY] = new DrawCell(terrainManager.getTerrainAtChunk(cellX, cellY),cellX,cellY,terrainManager.getChunkWidth()); cells[targetX][targetY] = new DrawCell(
terrainManager.getAugmentedTerrainAtChunk(currentCellX, currentCellY),
terrainManager.getAugmentedChunkWidth(),
currentCellX,
currentCellY,
terrainManager.getChunkWidth()
);
} }
valid[targetX][targetY] = true; valid[targetX][targetY] = true;
drawable[targetX][targetY] = false;
updateable[targetX][targetY] = false;
} }
} }
@ -123,14 +134,50 @@ public class CellManager {
currentCellY >= 0 && currentCellY >= 0 &&
currentCellY < terrainManager.getWorldDiscreteSize() currentCellY < terrainManager.getWorldDiscreteSize()
){ ){
int dist = Math.abs(cellX - drawRadius) * Math.abs(cellY - drawRadius); int dist = Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
int stride = Math.max(100, dist / drawStepdownInterval * drawStepdownValue); int stride = 20;//Math.max(100, dist / drawStepdownInterval * drawStepdownValue);
cells[targetX][targetY].generateDrawableEntity(stride); cells[targetX][targetY].generateDrawableEntity(stride);
} }
drawable[targetX][targetY] = true; drawable[targetX][targetY] = true;
} }
} }
public void updateCellModel(){
int targetX = 0;
int targetY = 0;
boolean found = false;
for(int x = 0; x < drawRadius * 2 + 1; x++){
targetX = x;
for(int y = 0; y < drawRadius * 2 + 1; y++){
targetY = y;
if(updateable[x][y]){
found = true;
break;
}
}
if(found){
break;
}
}
if(found){
int currentCellX = cellX - drawRadius + targetX;
int currentCellY = cellY - drawRadius + targetY;
if(
currentCellX >= 0 &&
currentCellX < terrainManager.getWorldDiscreteSize() &&
currentCellY >= 0 &&
currentCellY < terrainManager.getWorldDiscreteSize()
){
int dist = Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
int stride = 20;//Math.max(100, dist / drawStepdownInterval * drawStepdownValue);
cells[targetX][targetY].generateDrawableEntity(stride);
}
updateable[targetX][targetY] = false;
drawable[targetX][targetY] = true;
}
}
public boolean containsInvalidCell(){ public boolean containsInvalidCell(){
for(int x = 0;x < drawRadius * 2 + 1; x++){ for(int x = 0;x < drawRadius * 2 + 1; x++){
@ -154,9 +201,81 @@ public class CellManager {
return false; return false;
} }
public boolean containsUpdateableCell(){
for(int x = 0;x < drawRadius * 2 + 1; x++){
for(int y = 0; y < drawRadius * 2 + 1; y++){
if(updateable[x][y]){
return true;
}
}
}
return false;
}
public void shiftChunksNegX(){
for(int y = 0; y < drawRadius * 2 + 1; y++){
cells[drawRadius * 2][y].retireCell();
}
for(int x = drawRadius * 2; x > 0; x--){
for(int y = 0; y < drawRadius * 2 + 1; y++){
cells[x][y] = cells[x-1][y];
updateable[x][y] = true;
}
}
for(int y = 0; y < drawRadius * 2 + 1; y++){
valid[0][y] = false;
}
}
public void shiftChunksPosX(){
for(int y = 0; y < drawRadius * 2 + 1; y++){
cells[0][y].retireCell();
}
for(int x = 0; x < drawRadius * 2; x++){
for(int y = 0; y < drawRadius * 2 + 1; y++){
cells[x][y] = cells[x+1][y];
updateable[x][y] = true;
}
}
for(int y = 0; y < drawRadius * 2 + 1; y++){
valid[drawRadius * 2][y] = false;
}
}
public void shiftChunksNegY(){
for(int x = 0; x < drawRadius * 2 + 1; x++){
cells[x][drawRadius * 2].retireCell();
}
for(int x = 0; x < drawRadius * 2 + 1; x++){
for(int y = drawRadius * 2; y > 0; y--){
cells[x][y] = cells[x][y-1];
updateable[x][y] = true;
}
}
for(int x = 0; x < drawRadius * 2 + 1; x++){
valid[x][0] = false;
}
}
public void shiftChunksPosY(){
for(int x = 0; x < drawRadius * 2 + 1; x++){
cells[x][0].retireCell();
}
for(int x = 0; x < drawRadius * 2 + 1; x++){
for(int y = 0; y < drawRadius * 2; y++){
cells[x][y] = cells[x][y+1];
updateable[x][y] = true;
}
}
for(int x = 0; x < drawRadius * 2 + 1; x++){
valid[x][drawRadius * 2] = false;
}
}
public int transformRealSpaceToCellSpace(float input){ public int transformRealSpaceToCellSpace(float input){
return (int)input / terrainManager.getChunkWidth(); return (int)(input / terrainManager.getChunkWidth());
} }

View File

@ -4,6 +4,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtil; import electrosphere.entity.EntityUtil;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.ModelUtils;
import electrosphere.util.Utilities; import electrosphere.util.Utilities;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -12,7 +13,9 @@ import org.joml.Vector3f;
* @author satellite * @author satellite
*/ */
public class DrawCell { public class DrawCell {
float[][] elevation; float[][] drawArray;
int drawWidth;
int cellX; int cellX;
int cellY; int cellY;
@ -20,8 +23,9 @@ public class DrawCell {
Entity modelEntity; Entity modelEntity;
public DrawCell(float[][] elevation, int cellX, int cellY, int cellWidth){ public DrawCell(float[][] drawArray, int drawWidth, int cellX, int cellY, int cellWidth){
this.elevation = elevation; this.drawArray = drawArray;
this.drawWidth = drawWidth;
this.cellX = cellX; this.cellX = cellX;
this.cellY = cellY; this.cellY = cellY;
this.cellWidth = cellWidth; this.cellWidth = cellWidth;
@ -35,10 +39,14 @@ public class DrawCell {
if(modelEntity != null){ if(modelEntity != null){
Globals.entityManager.deregisterEntity(modelEntity); Globals.entityManager.deregisterEntity(modelEntity);
} }
Model terrainModel = Utilities.create_terrain_model(elevation, stride); Model terrainModel = ModelUtils.createTerrainModel(drawArray, stride);
modelEntity = EntityUtil.spawnDrawableEntity(terrainModel); modelEntity = EntityUtil.spawnDrawableEntity(terrainModel);
// System.out.println("New cell @ " + cellX * cellWidth + "," + cellY * cellWidth); // System.out.println("New cell @ " + cellX * cellWidth + "," + cellY * cellWidth);
EntityUtil.getEntityPosition(modelEntity).set(new Vector3f(cellX * cellWidth, 0, cellY * cellWidth)); EntityUtil.getEntityPosition(modelEntity).set(new Vector3f(cellX * cellWidth, 0, cellY * cellWidth));
} }
public void retireCell(){
EntityUtil.cleanUpDrawableEntity(modelEntity);
}
} }

View File

@ -19,20 +19,25 @@ public class TerrainManager {
//The size of the world in discrete units * must be multiple of 200 //The size of the world in discrete units * must be multiple of 200
int worldSizeDiscrete = 2000; int worldSizeDiscrete = 2000;
//The vertical multiplier applied to the statically generated terrain
int verticalInterpolationRatio = 20;
int dynamicInterpolationRatio = 1000; int dynamicInterpolationRatio = 1000;
TerrainModel model; TerrainModel model;
public TerrainManager(int worldSizeDiscrete, int dynamicInterpolationRatio){ public TerrainManager(int worldSizeDiscrete, int verticalInterpolationRatio, int dynamicInterpolationRatio){
this.worldSizeDiscrete = worldSizeDiscrete; this.worldSizeDiscrete = worldSizeDiscrete;
this.verticalInterpolationRatio = verticalInterpolationRatio;
this.dynamicInterpolationRatio = dynamicInterpolationRatio; this.dynamicInterpolationRatio = dynamicInterpolationRatio;
} }
public void generate(){ public void generate(){
TerrainGen terrainGen = new TerrainGen(); TerrainGen terrainGen = new TerrainGen();
terrainGen.setInterpolationRatio(worldSizeDiscrete/200); terrainGen.setInterpolationRatio(worldSizeDiscrete/200);
terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio);
terrainGen.setDynamicInterpolationRatio(dynamicInterpolationRatio); terrainGen.setDynamicInterpolationRatio(dynamicInterpolationRatio);
terrainGen.setRandomSeed(0); terrainGen.setRandomSeed(0);
model = terrainGen.generateModel(); model = terrainGen.generateModel();
@ -57,6 +62,10 @@ public class TerrainManager {
return model.getElevationForChunk(x, y); return model.getElevationForChunk(x, y);
} }
public float[][] getAugmentedTerrainAtChunk(int x, int y){
return model.getAugmentedElevationForChunk(x, y);
}
public float getHeightAtPosition(float x, float y){ public float getHeightAtPosition(float x, float y){
//get chunk coordinate space of input x,y //get chunk coordinate space of input x,y
int chunkX = (int)Math.floor(x / dynamicInterpolationRatio); int chunkX = (int)Math.floor(x / dynamicInterpolationRatio);
@ -98,8 +107,16 @@ public class TerrainManager {
return dynamicInterpolationRatio; return dynamicInterpolationRatio;
} }
public int getAugmentedChunkWidth(){
return dynamicInterpolationRatio + 1;
}
public int getWorldDiscreteSize(){ public int getWorldDiscreteSize(){
return worldSizeDiscrete; return worldSizeDiscrete;
} }
public float getDiscreteValue(int x, int y){
return model.getElevation()[x][y];
}
} }

View File

@ -12,6 +12,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtil; import electrosphere.entity.EntityUtil;
import electrosphere.game.cell.CellManager; import electrosphere.game.cell.CellManager;
import electrosphere.game.terrain.TerrainManager; import electrosphere.game.terrain.TerrainManager;
import electrosphere.renderer.ModelUtils;
import electrosphere.terraingen.TerrainGen; import electrosphere.terraingen.TerrainGen;
import electrosphere.terraingen.models.TerrainModel; import electrosphere.terraingen.models.TerrainModel;
import java.util.ArrayList; import java.util.ArrayList;
@ -88,8 +89,8 @@ public class Main {
public static boolean CAMERA_IS_ORBIT = true; public static boolean CAMERA_IS_ORBIT = true;
public static float camera_Orbit_Length = 1.0f; public static float camera_Orbit_Length = 1.0f;
static final int playerStartRealX = 1000; static final int playerStartRealX = 580 * 200;
static final int playerStartRealY = 1000; static final int playerStartRealY = 900 * 200;
// public static Camera cam_Player_Orbit; // public static Camera cam_Player_Orbit;
//Camera angles using theta-phi system //Camera angles using theta-phi system
@ -103,7 +104,6 @@ public class Main {
public static void main(String args[]){ public static void main(String args[]){
Utilities.loadMainConfig(); Utilities.loadMainConfig();
@ -131,8 +131,11 @@ public class Main {
initPlayer(); initPlayer();
Entity unitCube = EntityUtil.spawnDrawableEntity(ModelUtils.createUnitCube());
EntityUtil.getEntityPosition(unitCube).set(playerStartRealX - 0.5f,10,playerStartRealY - 0.5f);
RenderUtils.recaptureScreen();
/// ///
/// C A M E R A C R E A T I O N /// C A M E R A C R E A T I O N
@ -188,6 +191,8 @@ public class Main {
} }
} }
Vector3f oldPos = new Vector3f(EntityUtil.getEntityPosition(Globals.player));
if(glfwGetKey(Globals.window, GLFW_KEY_W) == GLFW_PRESS){ if(glfwGetKey(Globals.window, GLFW_KEY_W) == GLFW_PRESS){
EntityUtil.getEntityPosition(Globals.player).add(new Vector3f(-camera_Current.pos_Center.x,0,-camera_Current.pos_Center.z)); EntityUtil.getEntityPosition(Globals.player).add(new Vector3f(-camera_Current.pos_Center.x,0,-camera_Current.pos_Center.z));
} }
@ -206,6 +211,35 @@ public class Main {
if(glfwGetKey(Globals.window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS){ if(glfwGetKey(Globals.window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS){
EntityUtil.getEntityPosition(Globals.player).add(new Vector3f(0,-0.6f,0)); EntityUtil.getEntityPosition(Globals.player).add(new Vector3f(0,-0.6f,0));
} }
Vector3f newPos = EntityUtil.getEntityPosition(Globals.player);
if(Globals.cellManager.transformRealSpaceToCellSpace(newPos.x()) < Globals.cellManager.transformRealSpaceToCellSpace(oldPos.x())){
Globals.cellManager.shiftChunksNegX();
Globals.cellManager.setCellX(Globals.cellManager.transformRealSpaceToCellSpace(newPos.x()));
Globals.cellManager.setCellY(Globals.cellManager.transformRealSpaceToCellSpace(newPos.z()));
} else if(Globals.cellManager.transformRealSpaceToCellSpace(newPos.x()) > Globals.cellManager.transformRealSpaceToCellSpace(oldPos.x())){
Globals.cellManager.shiftChunksPosX();
Globals.cellManager.setCellX(Globals.cellManager.transformRealSpaceToCellSpace(newPos.x()));
Globals.cellManager.setCellY(Globals.cellManager.transformRealSpaceToCellSpace(newPos.z()));
}
if(Globals.cellManager.transformRealSpaceToCellSpace(newPos.z()) < Globals.cellManager.transformRealSpaceToCellSpace(oldPos.z())){
Globals.cellManager.shiftChunksNegY();
Globals.cellManager.setCellX(Globals.cellManager.transformRealSpaceToCellSpace(newPos.x()));
Globals.cellManager.setCellY(Globals.cellManager.transformRealSpaceToCellSpace(newPos.z()));
} else if(Globals.cellManager.transformRealSpaceToCellSpace(newPos.z()) > Globals.cellManager.transformRealSpaceToCellSpace(oldPos.z())){
Globals.cellManager.shiftChunksPosY();
Globals.cellManager.setCellX(Globals.cellManager.transformRealSpaceToCellSpace(newPos.x()));
Globals.cellManager.setCellY(Globals.cellManager.transformRealSpaceToCellSpace(newPos.z()));
}
if(Globals.cellManager.containsUpdateableCell()){
Globals.cellManager.updateCellModel();
} else if(Globals.cellManager.containsUndrawableCell()){
Globals.cellManager.makeCellDrawable();
} else if(Globals.cellManager.containsInvalidCell()){
Globals.cellManager.updateInvalidCell();
}
// camera_player_chase.pos_Center = new Vector3f(EntityUtil.getEntityPosition(player)).sub(EntityUtil.getEntityRotation(player).transform(new Vector3f(-1,1,0))); // camera_player_chase.pos_Center = new Vector3f(EntityUtil.getEntityPosition(player)).sub(EntityUtil.getEntityRotation(player).transform(new Vector3f(-1,1,0)));
@ -304,7 +338,7 @@ public class Main {
static void initWorld(){ static void initWorld(){
float[][] elevation; float[][] elevation;
terrainManager = new TerrainManager(2000,200); terrainManager = new TerrainManager(2000,200,200);
if(Globals.mainConfig.loadTerrain){ if(Globals.mainConfig.loadTerrain){
terrainManager.load(); terrainManager.load();
} else { } else {
@ -312,9 +346,6 @@ public class Main {
terrainManager.save(); terrainManager.save();
} }
//init cell manager
int cellX = 0;
int cellY = 0;
Globals.cellManager = new CellManager(terrainManager, playerStartRealX, playerStartRealY); Globals.cellManager = new CellManager(terrainManager, playerStartRealX, playerStartRealY);
@ -333,7 +364,7 @@ public class Main {
static void initPlayer(){ static void initPlayer(){
Globals.player = new Entity(); Globals.player = new Entity();
Globals.player.putData("position", new Vector3f(playerStartRealX,6f,playerStartRealY)); Globals.player.putData("position", new Vector3f(playerStartRealX,1900f,playerStartRealY));
Globals.cellManager.setCellX(GL_S); Globals.cellManager.setCellX(GL_S);
} }

View File

@ -0,0 +1,331 @@
package electrosphere.renderer;
import electrosphere.renderer.texture.Texture;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
/**
*
* @author satellite
*/
public class ModelUtils {
public static Model createTerrainModel(float[][] heightfield, int stride){
Model rVal = new Model();
rVal.meshes = new ArrayList();
Mesh m = new Mesh();
int width = heightfield.length;
int height = heightfield[0].length;
int actualWidth = (int)Math.ceil(1.0 * width / stride);
int actualHeight = (int)Math.ceil(1.0 * height / stride);
// System.out.println(actualWidth + " " + actualHeight);
// System.out.println((actualWidth - 1) * (actualHeight - 1));
FloatBuffer vertices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 3);
FloatBuffer normals = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 3);
IntBuffer faces = BufferUtils.createIntBuffer((actualWidth - 1) * (actualHeight - 1) * 2 * 3);
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 2);
for(int x = 0; x < width; x = x + stride){
for(int y = 0; y < height; y = y + stride){
//deal with vertex
vertices.put(x);
vertices.put(heightfield[x][y]);
vertices.put(y);
//deal with normal
if(x / stride < actualWidth - 1){
if(y / stride < actualHeight - 1){
float hL;
if(x > 0){
hL = heightfield[x-1][y];
} else {
hL = heightfield[x][y];
}
float hR = heightfield[x+1][y];
float hD = heightfield[x][y+1];
float hU;
if(y > 0){
hU = heightfield[x][y-1];
} else {
hU = heightfield[x][y];
}
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
} else {
float hL;
if(x > 0){
hL = heightfield[x-1][y];
} else {
hL = heightfield[x][y];
}
float hR = heightfield[x+1][y];
float hD = heightfield[x][y];
float hU = heightfield[x][y-1];
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
}
} else {
if(y / stride < actualHeight - 1){
float hL = heightfield[x-1][y];
float hR = heightfield[x][y];
float hD = heightfield[x][y+1];
float hU;
if(y > 0){
hU = heightfield[x][y-1];
} else {
hU = heightfield[x][y];
}
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
} else {
float hL = heightfield[x-1][y];
float hR = heightfield[x][y];
float hD = heightfield[x][y];
float hU = heightfield[x][y-1];
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
}
}
//deal with texture coordinates
if(x / stride % 2 == 0){
if(y / stride % 2 == 0){
texture_coords.put(0);
texture_coords.put(0);
} else {
texture_coords.put(0);
texture_coords.put(1);
}
} else {
if(y / stride % 2 == 0){
texture_coords.put(1);
texture_coords.put(0);
} else {
texture_coords.put(1);
texture_coords.put(1);
}
}
//deal with faces
if(x / stride < actualWidth - 1 && y / stride < actualHeight - 1){
faces.put((x / stride + 0) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 1));
}
}
}
vertices.flip();
normals.flip();
faces.flip();
texture_coords.flip();
m.vertexArrayObject = glGenVertexArrays();
glBindVertexArray(m.vertexArrayObject);
//buffer vertices
m.buffer_vertices(vertices);
//buffer normals
m.buffer_normals(normals);
//buffer faces
m.buffer_faces(faces);
//buffer texture coords
m.buffer_texture_coords(texture_coords);
m.shader = ShaderProgram.smart_assemble_shader(false,true);
glBindVertexArray(0);
m.parent = rVal;
Material groundMat = new Material();
Texture groundTex = new Texture("Textures/Ground/Dirt1.png");
groundMat.set_diffuse(groundTex);
groundMat.set_specular(groundTex);
m.set_material(groundMat);
rVal.meshes.add(m);
return rVal;
}
public static Model createUnitCube(){
Model rVal = new Model();
rVal.meshes = new ArrayList();
Mesh m = new Mesh();
// System.out.println(actualWidth + " " + actualHeight);
// System.out.println((actualWidth - 1) * (actualHeight - 1));
FloatBuffer vertices = BufferUtils.createFloatBuffer(8 * 3);
FloatBuffer normals = BufferUtils.createFloatBuffer(8 * 3);
IntBuffer faces = BufferUtils.createIntBuffer(6 * 2 * 3);
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(8 * 2);
//vertices
//0,0,0
vertices.put(0);
vertices.put(0);
vertices.put(0);
//1,0,0
vertices.put(1);
vertices.put(0);
vertices.put(0);
//0,1,0
vertices.put(0);
vertices.put(1);
vertices.put(0);
//1,1,0
vertices.put(1);
vertices.put(1);
vertices.put(0);
//0,0,1
vertices.put(0);
vertices.put(0);
vertices.put(1);
//1,0,1
vertices.put(1);
vertices.put(0);
vertices.put(1);
//0,1,1
vertices.put(0);
vertices.put(1);
vertices.put(1);
//1,1,1
vertices.put(1);
vertices.put(1);
vertices.put(1);
//normals
//-1,-1,-1
normals.put(-1);
normals.put(-1);
normals.put(-1);
// 1,-1,-1
normals.put( 1);
normals.put(-1);
normals.put(-1);
//-1, 1,-1
normals.put(-1);
normals.put( 1);
normals.put(-1);
// 1, 1,-1
normals.put( 1);
normals.put( 1);
normals.put(-1);
//-1,-1, 1
normals.put(-1);
normals.put(-1);
normals.put( 1);
// 1,-1, 1
normals.put( 1);
normals.put(-1);
normals.put( 1);
//-1, 1, 1
normals.put(-1);
normals.put( 1);
normals.put( 1);
// 1, 1, 1
normals.put( 1);
normals.put( 1);
normals.put( 1);
//faces
//0,1,2
faces.put(0);
faces.put(1);
faces.put(2);
//1,2,3
faces.put(1);
faces.put(2);
faces.put(3);
//1,3,5
faces.put(1);
faces.put(3);
faces.put(5);
//3,5,7
faces.put(3);
faces.put(5);
faces.put(7);
//0,1,4
faces.put(0);
faces.put(1);
faces.put(4);
//1,4,5
faces.put(1);
faces.put(4);
faces.put(5);
//0,2,4
faces.put(0);
faces.put(2);
faces.put(4);
//2,4,6
faces.put(2);
faces.put(4);
faces.put(6);
//2,3,6
faces.put(2);
faces.put(3);
faces.put(6);
//3,6,7
faces.put(3);
faces.put(6);
faces.put(7);
//4,5,6
faces.put(4);
faces.put(5);
faces.put(6);
//5,6,7
faces.put(5);
faces.put(6);
faces.put(7);
//texture
for(int i = 0; i < 8 * 2; i++){
texture_coords.put(0);
}
vertices.flip();
normals.flip();
faces.flip();
texture_coords.flip();
m.vertexArrayObject = glGenVertexArrays();
glBindVertexArray(m.vertexArrayObject);
//buffer vertices
m.buffer_vertices(vertices);
//buffer normals
m.buffer_normals(normals);
//buffer faces
m.buffer_faces(faces);
//buffer texture coords
m.buffer_texture_coords(texture_coords);
m.shader = ShaderProgram.smart_assemble_shader(false,true);
glBindVertexArray(0);
m.parent = rVal;
Material groundMat = new Material();
Texture groundTex = new Texture("Textures/Ground/Dirt1.png");
groundMat.set_diffuse(groundTex);
groundMat.set_specular(groundTex);
m.set_material(groundMat);
rVal.meshes.add(m);
return rVal;
}
}

View File

@ -122,6 +122,16 @@ public class RenderUtils {
} }
public static void recaptureScreen(){
//Makes the window that was just created the current OS-level window context
glfwMakeContextCurrent(Globals.window);
//Maximize it
glfwMaximizeWindow(Globals.window);
//Hide the cursor and capture it
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}

View File

@ -75,153 +75,7 @@ public class Utilities {
return rVal; return rVal;
} }
public static Model create_terrain_model(float[][] heightfield, int stride){
Model rVal = new Model();
rVal.meshes = new ArrayList();
Mesh m = new Mesh();
int width = heightfield.length;
int height = heightfield[0].length;
int actualWidth = width / stride;
int actualHeight = height / stride;
// System.out.println(actualWidth + " " + actualHeight);
//
// System.out.println((actualWidth - 1) * (actualHeight - 1));
FloatBuffer vertices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 3);
FloatBuffer normals = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 3);
IntBuffer faces = BufferUtils.createIntBuffer((actualWidth - 1) * (actualHeight - 1) * 2 * 3);
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 2);
for(int x = 0; x < width; x = x + stride){
for(int y = 0; y < height; y = y + stride){
//deal with vertex
vertices.put(x);
vertices.put(heightfield[x][y]);
vertices.put(y);
//deal with normal
if(x / stride < actualWidth - 1){
if(y / stride < actualHeight - 1){
float hL;
if(x > 0){
hL = heightfield[x-1][y];
} else {
hL = heightfield[x][y];
}
float hR = heightfield[x+1][y];
float hD = heightfield[x][y+1];
float hU;
if(y > 0){
hU = heightfield[x][y-1];
} else {
hU = heightfield[x][y];
}
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
} else {
float hL;
if(x > 0){
hL = heightfield[x-1][y];
} else {
hL = heightfield[x][y];
}
float hR = heightfield[x+1][y];
float hD = heightfield[x][y];
float hU = heightfield[x][y-1];
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
}
} else {
if(y / stride < actualHeight - 1){
float hL = heightfield[x-1][y];
float hR = heightfield[x][y];
float hD = heightfield[x][y+1];
float hU;
if(y > 0){
hU = heightfield[x][y-1];
} else {
hU = heightfield[x][y];
}
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
} else {
float hL = heightfield[x-1][y];
float hR = heightfield[x][y];
float hD = heightfield[x][y];
float hU = heightfield[x][y-1];
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
Normal.normalize();
normals.put(Normal.x);
normals.put(Normal.y);
normals.put(Normal.z);
}
}
//deal with texture coordinates
if(x / stride % 2 == 0){
if(y / stride % 2 == 0){
texture_coords.put(0);
texture_coords.put(0);
} else {
texture_coords.put(0);
texture_coords.put(1);
}
} else {
if(y / stride % 2 == 0){
texture_coords.put(1);
texture_coords.put(0);
} else {
texture_coords.put(1);
texture_coords.put(1);
}
}
//deal with faces
if(x / stride < actualWidth - 1 && y / stride < actualHeight - 1){
faces.put((x / stride + 0) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 1));
}
}
}
vertices.flip();
normals.flip();
faces.flip();
texture_coords.flip();
m.vertexArrayObject = glGenVertexArrays();
glBindVertexArray(m.vertexArrayObject);
//buffer vertices
m.buffer_vertices(vertices);
//buffer normals
m.buffer_normals(normals);
//buffer faces
m.buffer_faces(faces);
//buffer texture coords
m.buffer_texture_coords(texture_coords);
m.shader = ShaderProgram.smart_assemble_shader(false,true);
glBindVertexArray(0);
m.parent = rVal;
Material groundMat = new Material();
Texture groundTex = new Texture("Textures/Ground/Dirt1.png");
groundMat.set_diffuse(groundTex);
groundMat.set_specular(groundTex);
m.set_material(groundMat);
rVal.meshes.add(m);
return rVal;
}
public static void save_test_texture_map_to_location(String s){ public static void save_test_texture_map_to_location(String s){
TextureMap t = new TextureMap(); TextureMap t = new TextureMap();

File diff suppressed because one or more lines are too long