1775 lines
63 KiB
Java
1775 lines
63 KiB
Java
package electrosphere.renderer;
|
|
|
|
import electrosphere.engine.assetmanager.AssetDataStrings;
|
|
import electrosphere.entity.CameraEntityUtils;
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.IntBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import electrosphere.main.Globals;
|
|
import org.joml.Matrix4f;
|
|
import org.joml.Vector3f;
|
|
import org.lwjgl.BufferUtils;
|
|
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
|
|
import static org.lwjgl.glfw.GLFW.glfwMaximizeWindow;
|
|
import org.lwjgl.opengl.GL11;
|
|
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
|
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
|
|
import static org.lwjgl.opengl.GL11.GL_LESS;
|
|
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
|
|
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
|
|
import org.lwjgl.opengl.GL15;
|
|
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
|
|
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
|
|
import static org.lwjgl.opengl.GL15.glBindBuffer;
|
|
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
|
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
|
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
|
import static org.lwjgl.opengl.GL20.glUniform3fv;
|
|
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
|
import static org.lwjgl.opengl.GL20.glUseProgram;
|
|
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
|
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
|
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
|
|
|
/**
|
|
*
|
|
* @author amaterasu
|
|
*/
|
|
public class RenderUtils {
|
|
|
|
|
|
|
|
static int createScreenTextureVAO(){
|
|
int rVal = glGenVertexArrays();
|
|
glBindVertexArray(rVal);
|
|
//vertices
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12);
|
|
VertexArrayBufferData.put(-1.0f);
|
|
VertexArrayBufferData.put( 1.0f);
|
|
|
|
VertexArrayBufferData.put(-1.0f);
|
|
VertexArrayBufferData.put(-1.0f);
|
|
|
|
VertexArrayBufferData.put( 1.0f);
|
|
VertexArrayBufferData.put(-1.0f);
|
|
|
|
VertexArrayBufferData.put(-1.0f);
|
|
VertexArrayBufferData.put( 1.0f);
|
|
|
|
VertexArrayBufferData.put( 1.0f);
|
|
VertexArrayBufferData.put(-1.0f);
|
|
|
|
VertexArrayBufferData.put( 1.0f);
|
|
VertexArrayBufferData.put( 1.0f);
|
|
VertexArrayBufferData.flip();
|
|
int vertexBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, VertexArrayBufferData, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(0);
|
|
|
|
|
|
|
|
|
|
|
|
//texture coords
|
|
FloatBuffer TextureArrayBufferData = BufferUtils.createFloatBuffer(12);
|
|
TextureArrayBufferData.put(0.0f);
|
|
TextureArrayBufferData.put(1.0f);
|
|
|
|
TextureArrayBufferData.put(0.0f);
|
|
TextureArrayBufferData.put(0.0f);
|
|
|
|
TextureArrayBufferData.put(1.0f);
|
|
TextureArrayBufferData.put(0.0f);
|
|
|
|
TextureArrayBufferData.put(0.0f);
|
|
TextureArrayBufferData.put(1.0f);
|
|
|
|
TextureArrayBufferData.put(1.0f);
|
|
TextureArrayBufferData.put(0.0f);
|
|
|
|
TextureArrayBufferData.put(1.0f);
|
|
TextureArrayBufferData.put(1.0f);
|
|
TextureArrayBufferData.flip();
|
|
int textureCoordBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, textureCoordBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, TextureArrayBufferData, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(1);
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
//apply mouse controls state
|
|
if(Globals.controlHandler.isMouseVisible()){
|
|
Globals.controlHandler.showMouse();
|
|
} else {
|
|
Globals.controlHandler.hideMouse();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Model createSkyboxModel(Material optionalMaterial){
|
|
Model skyboxModel = new Model();
|
|
skyboxModel.meshes = new ArrayList<Mesh>();
|
|
|
|
skyboxModel.modelMatrix = new Matrix4f();
|
|
|
|
|
|
|
|
boolean apply_lighting = false;
|
|
boolean has_bones = false;
|
|
|
|
Mesh skyboxmesh = new Mesh(){
|
|
@Override
|
|
public void complexDraw(boolean setShader, boolean bufferStandardUniforms, boolean bufferNonStandardUniforms, boolean useMaterial, boolean useShadowMap, boolean setBones, boolean useLight){
|
|
if(setShader){
|
|
GL11.glDepthFunc(GL_LEQUAL);
|
|
glUseProgram(shader.shaderProgram);
|
|
}
|
|
|
|
if(useMaterial){
|
|
if(material == null){
|
|
Globals.materialDefault.apply_material(0,1);
|
|
Iterator<Vector3f> colorIterator = Globals.skyboxColors.iterator();
|
|
int counter = 0;
|
|
float[] temp = new float[3];
|
|
while(colorIterator.hasNext()){
|
|
Vector3f colorCurrent = colorIterator.next();
|
|
temp[0] = colorCurrent.x / 255.0f;
|
|
temp[1] = colorCurrent.y / 255.0f;
|
|
temp[2] = colorCurrent.z / 255.0f;
|
|
// System.out.println("colors[" + counter + "] " + temp[0] + " " + temp[1] + " " + temp[2]);
|
|
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "colors[" + counter + "]"), temp);
|
|
counter++;
|
|
}
|
|
}
|
|
}
|
|
|
|
glBindVertexArray(vertexArrayObject);
|
|
|
|
|
|
|
|
if(bufferStandardUniforms){
|
|
//buffer model/view/proj matrices
|
|
glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
|
glUniformMatrix4fv(shader.shaderVertexViewLoc, false, new Matrix4f(Globals.viewMatrix).scale(100).get(new float[16]));
|
|
glUniformMatrix4fv(shader.shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16]));
|
|
glUniform3fv(shader.shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3)));
|
|
}
|
|
|
|
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
|
glBindVertexArray(0);
|
|
|
|
if(setShader){
|
|
GL11.glDepthFunc(GL_LESS);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
skyboxmesh.mesh = null;
|
|
|
|
//
|
|
// VAO
|
|
//
|
|
skyboxmesh.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(skyboxmesh.vertexArrayObject);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float[] vertexcoords = {
|
|
100.0f, 100.0f, 100.0f,
|
|
100.0f, 100.0f,-100.0f,
|
|
100.0f,-100.0f, 100.0f,
|
|
100.0f,-100.0f,-100.0f,
|
|
-100.0f, 100.0f, 100.0f,
|
|
-100.0f, 100.0f,-100.0f,
|
|
-100.0f,-100.0f, 100.0f,
|
|
-100.0f,-100.0f,-100.0f,
|
|
|
|
};
|
|
|
|
//
|
|
//Buffer data to GPU
|
|
//
|
|
|
|
try {
|
|
skyboxmesh.vertexCount = vertexcoords.length / 3;
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount * 3);
|
|
float[] temp = new float[3];
|
|
for (int i = 0; i < skyboxmesh.vertexCount; i++) {
|
|
temp[0] = vertexcoords[i * 3 + 0];
|
|
temp[1] = vertexcoords[i * 3 + 1];
|
|
temp[2] = vertexcoords[i * 3 + 2];
|
|
VertexArrayBufferData.put(temp);
|
|
}
|
|
VertexArrayBufferData.flip();
|
|
skyboxmesh.buffer_vertices(VertexArrayBufferData, 3);
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
|
|
int[] facedata = {
|
|
0,1,4,
|
|
1,4,5,
|
|
1,3,5,
|
|
3,5,7,
|
|
4,5,7,
|
|
4,6,7,
|
|
|
|
0,2,4,
|
|
2,4,6,
|
|
0,1,2,
|
|
1,2,3,
|
|
|
|
2,3,6,
|
|
3,6,7,
|
|
|
|
};
|
|
|
|
//
|
|
// FACES
|
|
//
|
|
skyboxmesh.faceCount = facedata.length / 3;
|
|
skyboxmesh.elementCount = facedata.length;
|
|
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(skyboxmesh.elementCount);
|
|
for(int i = 0; i < skyboxmesh.faceCount; i++){
|
|
int[] temp = new int[3];
|
|
temp[0] = facedata[i * 3 + 0];
|
|
temp[1] = facedata[i * 3 + 1];
|
|
temp[2] = facedata[i * 3 + 2];
|
|
elementArrayBufferData.put(temp);
|
|
}
|
|
elementArrayBufferData.flip();
|
|
skyboxmesh.buffer_faces(elementArrayBufferData);
|
|
|
|
|
|
|
|
|
|
if(optionalMaterial != null){
|
|
//
|
|
// NORMALS
|
|
//
|
|
try {
|
|
skyboxmesh.normalCount = vertexcoords.length / 3;
|
|
FloatBuffer NormalArrayBufferData;
|
|
if(skyboxmesh.normalCount > 0){
|
|
NormalArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.normalCount * 3);
|
|
float[] temp = new float[3];
|
|
for (int i = 0; i < skyboxmesh.normalCount; i++) {
|
|
temp[0] = vertexcoords[i * 3 + 0];
|
|
temp[1] = vertexcoords[i * 3 + 1];
|
|
temp[2] = vertexcoords[i * 3 + 2];
|
|
NormalArrayBufferData.put(temp);
|
|
}
|
|
NormalArrayBufferData.flip();
|
|
skyboxmesh.buffer_normals(NormalArrayBufferData, 3);
|
|
}
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
//
|
|
// TEXTURE COORDINATES
|
|
//
|
|
/*try {
|
|
skyboxmesh.textureCoordCount = mesh.mTextureCoords(0).capacity();
|
|
FloatBuffer TextureArrayBufferData;
|
|
if(skyboxmesh.textureCoordCount > 0){
|
|
TextureArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.textureCoordCount * 2);
|
|
float[] temp = new float[2];
|
|
for (int i = 0; i < skyboxmesh.textureCoordCount; i++) {
|
|
AIVector3D normal = texturecoords.get(i);
|
|
temp[0] = normal.x();
|
|
temp[1] = normal.y();
|
|
// temp[2] = normal.z();
|
|
TextureArrayBufferData.put(temp);
|
|
}
|
|
TextureArrayBufferData.flip();
|
|
skyboxmesh.buffer_texture_coords(TextureArrayBufferData);
|
|
}
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
|
|
skyboxmesh.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
|
|
|
|
skybox_model.materials.add(optionalMaterial);
|
|
*/
|
|
} else {
|
|
skyboxmesh.shader = ShaderProgram.loadSpecificShader("/Shaders/skybox/VertexShaderNoTexture.vs", "/Shaders/skybox/FragmentShaderNoTexture.fs");
|
|
try {
|
|
FloatBuffer ColorArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount);
|
|
for (int i = 0; i < skyboxmesh.vertexCount; i++) {
|
|
ColorArrayBufferData.put(i);
|
|
}
|
|
ColorArrayBufferData.flip();
|
|
int idBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, idBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, ColorArrayBufferData, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(1, 1, GL11.GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(1);
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
skyboxmesh.hasBones = false;
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
skyboxmesh.nodeID = "skybox";
|
|
|
|
skyboxmesh.parent = skyboxModel;
|
|
|
|
|
|
skyboxModel.meshes.add(skyboxmesh);
|
|
|
|
|
|
return skyboxModel;
|
|
}
|
|
|
|
|
|
public static Model createParticleModel(){
|
|
Model particleModel = new Model();
|
|
particleModel.meshes = new ArrayList<Mesh>();
|
|
particleModel.modelMatrix = new Matrix4f();
|
|
|
|
|
|
Mesh particleMesh = new Mesh();
|
|
|
|
|
|
particleMesh.mesh = null;
|
|
|
|
//
|
|
// VAO
|
|
//
|
|
particleMesh.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(particleMesh.vertexArrayObject);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float[] vertexcoords = {
|
|
-1.0f, 1.0f, 0.0f,
|
|
1.0f, 1.0f, 0.0f,
|
|
-1.0f, -1.0f, 0.0f,
|
|
1.0f, -1.0f, 0.0f,
|
|
|
|
};
|
|
|
|
//
|
|
//Buffer data to GPU
|
|
//
|
|
|
|
try {
|
|
particleMesh.vertexCount = vertexcoords.length / 3;
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(particleMesh.vertexCount * 3);
|
|
float[] temp = new float[3];
|
|
for (int i = 0; i < particleMesh.vertexCount; i++) {
|
|
temp[0] = vertexcoords[i * 3 + 0];
|
|
temp[1] = vertexcoords[i * 3 + 1];
|
|
temp[2] = vertexcoords[i * 3 + 2];
|
|
VertexArrayBufferData.put(temp);
|
|
}
|
|
VertexArrayBufferData.flip();
|
|
particleMesh.buffer_vertices(VertexArrayBufferData, 3);
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
|
|
int[] facedata = {
|
|
0,1,2,
|
|
1,2,3,
|
|
};
|
|
|
|
//
|
|
// FACES
|
|
//
|
|
particleMesh.faceCount = facedata.length / 3;
|
|
particleMesh.elementCount = facedata.length;
|
|
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(particleMesh.elementCount);
|
|
for(int i = 0; i < particleMesh.faceCount; i++){
|
|
int[] temp = new int[3];
|
|
temp[0] = facedata[i * 3 + 0];
|
|
temp[1] = facedata[i * 3 + 1];
|
|
temp[2] = facedata[i * 3 + 2];
|
|
elementArrayBufferData.put(temp);
|
|
}
|
|
elementArrayBufferData.flip();
|
|
particleMesh.buffer_faces(elementArrayBufferData);
|
|
|
|
//
|
|
// TEXTURE COORDS
|
|
//
|
|
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(8);
|
|
float[] texturedata = {
|
|
0,0,
|
|
1,0,
|
|
0,1,
|
|
1,1
|
|
};
|
|
texture_coords.put(texturedata);
|
|
texture_coords.flip();
|
|
particleMesh.buffer_texture_coords(texture_coords, 2);
|
|
|
|
|
|
|
|
|
|
particleMesh.shader = ShaderProgram.loadSpecificShader("Shaders/particleBillboard/particleBillboard.vs", "Shaders/particleBillboard/particleBillboard.fs");
|
|
particleMesh.hasBones = false;
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
particleMesh.nodeID = "particleBillboard";
|
|
|
|
particleMesh.parent = particleModel;
|
|
|
|
|
|
particleModel.meshes.add(particleMesh);
|
|
|
|
|
|
return particleModel;
|
|
}
|
|
|
|
|
|
public static Model createPlaneModel(){
|
|
Model rVal = new Model();
|
|
|
|
rVal.meshes = new ArrayList<Mesh>();
|
|
rVal.modelMatrix = new Matrix4f();
|
|
|
|
|
|
Mesh planeMesh = new Mesh();
|
|
|
|
|
|
planeMesh.mesh = null;
|
|
|
|
//
|
|
// VAO
|
|
//
|
|
planeMesh.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(planeMesh.vertexArrayObject);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float[] vertexcoords = {
|
|
-1.0f, 1.0f, 0.0f,
|
|
1.0f, 1.0f, 0.0f,
|
|
-1.0f, -1.0f, 0.0f,
|
|
1.0f, -1.0f, 0.0f,
|
|
|
|
};
|
|
|
|
//
|
|
//Buffer data to GPU
|
|
//
|
|
|
|
try {
|
|
planeMesh.vertexCount = vertexcoords.length / 3;
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(planeMesh.vertexCount * 3);
|
|
float[] temp = new float[3];
|
|
for (int i = 0; i < planeMesh.vertexCount; i++) {
|
|
temp[0] = vertexcoords[i * 3 + 0];
|
|
temp[1] = vertexcoords[i * 3 + 1];
|
|
temp[2] = vertexcoords[i * 3 + 2];
|
|
VertexArrayBufferData.put(temp);
|
|
}
|
|
VertexArrayBufferData.flip();
|
|
planeMesh.buffer_vertices(VertexArrayBufferData, 3);
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
|
|
int[] facedata = {
|
|
0,1,2,
|
|
1,2,3,
|
|
};
|
|
|
|
//
|
|
// FACES
|
|
//
|
|
planeMesh.faceCount = facedata.length / 3;
|
|
planeMesh.elementCount = facedata.length;
|
|
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(planeMesh.elementCount);
|
|
for(int i = 0; i < planeMesh.faceCount; i++){
|
|
int[] temp = new int[3];
|
|
temp[0] = facedata[i * 3 + 0];
|
|
temp[1] = facedata[i * 3 + 1];
|
|
temp[2] = facedata[i * 3 + 2];
|
|
elementArrayBufferData.put(temp);
|
|
}
|
|
elementArrayBufferData.flip();
|
|
planeMesh.buffer_faces(elementArrayBufferData);
|
|
|
|
//
|
|
// TEXTURE COORDS
|
|
//
|
|
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(8);
|
|
float[] texturedata = {
|
|
0,1,
|
|
1,1,
|
|
0,0,
|
|
1,0
|
|
};
|
|
texture_coords.put(texturedata);
|
|
texture_coords.flip();
|
|
planeMesh.buffer_texture_coords(texture_coords, 2);
|
|
|
|
|
|
|
|
|
|
planeMesh.shader = ShaderProgram.loadSpecificShader("Shaders/plane/plane.vs", "Shaders/plane/plane.fs");
|
|
planeMesh.hasBones = false;
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
planeMesh.nodeID = "plane";
|
|
|
|
planeMesh.parent = rVal;
|
|
|
|
|
|
rVal.meshes.add(planeMesh);
|
|
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
public static Model createBitmapDisplay(){
|
|
|
|
Model rVal = new Model();
|
|
rVal.meshes = new ArrayList<Mesh>();
|
|
Mesh m = new Mesh();
|
|
m.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(m.vertexArrayObject);
|
|
//vertices
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12);
|
|
VertexArrayBufferData.put( 0);
|
|
VertexArrayBufferData.put( 1);
|
|
|
|
VertexArrayBufferData.put( 0);
|
|
VertexArrayBufferData.put( 0);
|
|
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.put( 0);
|
|
|
|
VertexArrayBufferData.put( 0);
|
|
VertexArrayBufferData.put( 1);
|
|
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.put( 0);
|
|
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.flip();
|
|
|
|
|
|
IntBuffer faceArrayBufferData = BufferUtils.createIntBuffer(6);
|
|
faceArrayBufferData.put(0);
|
|
faceArrayBufferData.put(1);
|
|
faceArrayBufferData.put(2);
|
|
|
|
faceArrayBufferData.put(3);
|
|
faceArrayBufferData.put(4);
|
|
faceArrayBufferData.put(5);
|
|
faceArrayBufferData.flip();
|
|
|
|
|
|
|
|
//texture coords
|
|
FloatBuffer TextureArrayBufferData = BufferUtils.createFloatBuffer(12);
|
|
TextureArrayBufferData.put(0);
|
|
TextureArrayBufferData.put(1);
|
|
|
|
TextureArrayBufferData.put(0);
|
|
TextureArrayBufferData.put(0);
|
|
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.put(0);
|
|
|
|
TextureArrayBufferData.put(0);
|
|
TextureArrayBufferData.put(1);
|
|
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.put(0);
|
|
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.flip();
|
|
|
|
|
|
//buffer vertices
|
|
m.buffer_vertices(VertexArrayBufferData, 2);
|
|
//buffer normals
|
|
m.buffer_normals(VertexArrayBufferData, 2);
|
|
//buffer faces
|
|
m.buffer_faces(faceArrayBufferData);
|
|
//buffer texture coords
|
|
m.buffer_texture_coords(TextureArrayBufferData, 2);
|
|
|
|
|
|
m.shader = ShaderProgram.loadSpecificShader("/Shaders/font/basicbitmap/basicbitmap.vs", "/Shaders/font/basicbitmap/basicbitmap.fs");
|
|
|
|
|
|
glBindVertexArray(0);
|
|
m.parent = rVal;
|
|
m.nodeID = AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME;
|
|
|
|
Material uiMat = new Material();
|
|
Globals.assetManager.addTexturePathtoQueue("/Textures/Fonts/myfont1-harsher.png");
|
|
uiMat.set_diffuse("/Textures/Fonts/myfont1-harsher.png");
|
|
uiMat.set_specular("/Textures/Fonts/myfont1-harsher.png");
|
|
m.setMaterial(uiMat);
|
|
rVal.materials = new ArrayList<Material>();
|
|
rVal.materials.add(uiMat);
|
|
|
|
rVal.meshes.add(m);
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Model createBitmapCharacter(){
|
|
|
|
Model rVal = new Model();
|
|
rVal.meshes = new ArrayList<Mesh>();
|
|
Mesh m = new Mesh();
|
|
m.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(m.vertexArrayObject);
|
|
//vertices
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12);
|
|
VertexArrayBufferData.put(-1);
|
|
VertexArrayBufferData.put( 1);
|
|
|
|
VertexArrayBufferData.put(-1);
|
|
VertexArrayBufferData.put(-1);
|
|
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.put(-1);
|
|
|
|
VertexArrayBufferData.put(-1);
|
|
VertexArrayBufferData.put( 1);
|
|
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.put(-1);
|
|
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.put( 1);
|
|
VertexArrayBufferData.flip();
|
|
|
|
|
|
IntBuffer faceArrayBufferData = BufferUtils.createIntBuffer(6);
|
|
faceArrayBufferData.put(0);
|
|
faceArrayBufferData.put(1);
|
|
faceArrayBufferData.put(2);
|
|
|
|
faceArrayBufferData.put(3);
|
|
faceArrayBufferData.put(4);
|
|
faceArrayBufferData.put(5);
|
|
faceArrayBufferData.flip();
|
|
|
|
|
|
|
|
//texture coords
|
|
FloatBuffer TextureArrayBufferData = BufferUtils.createFloatBuffer(12);
|
|
TextureArrayBufferData.put(0);
|
|
TextureArrayBufferData.put(1);
|
|
|
|
TextureArrayBufferData.put(0);
|
|
TextureArrayBufferData.put(0);
|
|
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.put(0);
|
|
|
|
TextureArrayBufferData.put(0);
|
|
TextureArrayBufferData.put(1);
|
|
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.put(0);
|
|
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.put(1);
|
|
TextureArrayBufferData.flip();
|
|
|
|
|
|
//buffer vertices
|
|
m.buffer_vertices(VertexArrayBufferData, 2);
|
|
//buffer normals
|
|
m.buffer_normals(VertexArrayBufferData, 2);
|
|
//buffer faces
|
|
m.buffer_faces(faceArrayBufferData);
|
|
//buffer texture coords
|
|
m.buffer_texture_coords(TextureArrayBufferData, 2);
|
|
|
|
|
|
m.shader = ShaderProgram.loadSpecificShader("/Shaders/font/bitmapchar/bitmapchar.vs", "/Shaders/font/bitmapchar/bitmapchar.fs");
|
|
|
|
|
|
glBindVertexArray(0);
|
|
m.parent = rVal;
|
|
m.nodeID = AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME;
|
|
|
|
Material uiMat = new Material();
|
|
Globals.assetManager.addTexturePathtoQueue("/Textures/Fonts/myfont1-harsher.png");
|
|
uiMat.set_diffuse("/Textures/Fonts/myfont1-harsher.png");
|
|
uiMat.set_specular("/Textures/Fonts/myfont1-harsher.png");
|
|
m.setMaterial(uiMat);
|
|
rVal.materials = new ArrayList<Material>();
|
|
rVal.materials.add(uiMat);
|
|
|
|
rVal.meshes.add(m);
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Model createTerrainModelPrecomputedShader(float[][] heightfield, float[][] texturemap, ShaderProgram program, int stride){
|
|
Model rVal = new Model();
|
|
rVal.meshes = new ArrayList<Mesh>();
|
|
Mesh m = new Mesh();
|
|
int width = heightfield.length;
|
|
int height = heightfield[0].length;
|
|
|
|
int actualWidth = (int)Math.ceil(1.0f * width / (1.0f * stride));
|
|
int actualHeight = (int)Math.ceil(1.0f * height / (1.0f * stride));
|
|
|
|
|
|
// System.out.println(actualWidth + " " + actualHeight);
|
|
|
|
// System.out.println((actualWidth - 1) * (actualHeight - 1));
|
|
|
|
FloatBuffer vertices;
|
|
FloatBuffer normals;
|
|
IntBuffer faces;
|
|
FloatBuffer texture_coords;
|
|
FloatBuffer textureIndices;
|
|
if(stride * actualWidth > width){
|
|
int drawWidth = actualWidth + 1;
|
|
int drawHeight = actualHeight + 1;
|
|
vertices = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 12);
|
|
normals = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 12);
|
|
faces = BufferUtils.createIntBuffer((drawWidth - 1) * (drawHeight - 1) * 2 * 3);
|
|
texture_coords = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 8);
|
|
textureIndices = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 16);
|
|
} else {
|
|
vertices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 12);
|
|
normals = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 12);
|
|
faces = BufferUtils.createIntBuffer((actualWidth - 1) * (actualHeight - 1) * 2 * 3);
|
|
texture_coords = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 8);
|
|
textureIndices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 16);
|
|
}
|
|
|
|
int incrementer = 0;
|
|
int numFaces = (actualWidth - 1) * (actualHeight - 1) * 2 * 3;
|
|
for(int x = 0; x < width - 1; x = x + stride){
|
|
for(int y = 0; y < height - 1; y = y + stride){
|
|
//deal with vertex
|
|
//0,0
|
|
vertices.put(x);
|
|
vertices.put(heightfield[x][y]);
|
|
vertices.put(y);
|
|
//1,0
|
|
vertices.put(x + stride);
|
|
vertices.put(heightfield[x+stride][y]);
|
|
vertices.put(y);
|
|
//0,1
|
|
vertices.put(x);
|
|
vertices.put(heightfield[x][y+stride]);
|
|
vertices.put(y + stride);
|
|
//1,1
|
|
vertices.put(x + stride);
|
|
vertices.put(heightfield[x+stride][y+stride]);
|
|
vertices.put(y + stride);
|
|
//deal with normal
|
|
Vector3f normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x, y);
|
|
normals.put(normal.x);
|
|
normals.put(normal.y);
|
|
normals.put(normal.z);
|
|
normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x + stride, y);
|
|
normals.put(normal.x);
|
|
normals.put(normal.y);
|
|
normals.put(normal.z);
|
|
normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x, y + stride);
|
|
normals.put(normal.x);
|
|
normals.put(normal.y);
|
|
normals.put(normal.z);
|
|
normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x + stride, y + stride);
|
|
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);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(1);
|
|
// } 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);
|
|
// }
|
|
// }
|
|
texture_coords.put(0);
|
|
texture_coords.put(0);
|
|
texture_coords.put(1);
|
|
texture_coords.put(0);
|
|
texture_coords.put(0);
|
|
texture_coords.put(1);
|
|
texture_coords.put(1);
|
|
texture_coords.put(1);
|
|
|
|
if(x + stride < width - 1 && y + stride < height - 1){
|
|
// texturemap[x+stride][y+stride];
|
|
for(int i = 0; i < 4 ; i++){
|
|
// textureIndices.put(1);
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
textureIndices.put(texturemap[x][y]);
|
|
textureIndices.put(texturemap[x+stride][y]);
|
|
textureIndices.put(texturemap[x][y+stride]);
|
|
textureIndices.put(texturemap[x+stride][y+stride]);
|
|
}
|
|
} else {
|
|
for(int i = 0; i < 4 ; i++){
|
|
textureIndices.put(0);
|
|
textureIndices.put(0);
|
|
textureIndices.put(0);
|
|
textureIndices.put(0);
|
|
}
|
|
}
|
|
|
|
|
|
//deal with faces
|
|
if(1.0f * x / stride < actualWidth - 1 && 1.0f * y / stride < actualHeight - 1){
|
|
faces.put(incrementer * 4 + 0);
|
|
faces.put(incrementer * 4 + 1);
|
|
faces.put(incrementer * 4 + 2);
|
|
faces.put(incrementer * 4 + 1);
|
|
faces.put(incrementer * 4 + 2);
|
|
faces.put(incrementer * 4 + 3);
|
|
}
|
|
incrementer++;
|
|
}
|
|
}
|
|
|
|
vertices.flip();
|
|
normals.flip();
|
|
faces.flip();
|
|
texture_coords.flip();
|
|
textureIndices.flip();
|
|
|
|
m.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(m.vertexArrayObject);
|
|
//buffer vertices
|
|
m.buffer_vertices(vertices, 3);
|
|
//buffer normals
|
|
m.buffer_normals(normals, 3);
|
|
//buffer faces
|
|
m.buffer_faces(faces);
|
|
//buffer texture coords
|
|
m.buffer_texture_coords(texture_coords, 2);
|
|
//texture indices
|
|
m.bufferCustomFloatAttribArray(textureIndices, 4, 5);
|
|
m.shader = program;
|
|
glBindVertexArray(0);
|
|
m.parent = rVal;
|
|
|
|
m.hasBones = false;
|
|
|
|
Material groundMat = new Material();
|
|
Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png");
|
|
groundMat.set_diffuse("/Textures/Ground/Dirt1.png");
|
|
groundMat.set_specular("/Textures/Ground/Dirt1.png");
|
|
m.setMaterial(groundMat);
|
|
|
|
rVal.meshes.add(m);
|
|
return rVal;
|
|
}
|
|
|
|
|
|
static float MINIMIZATION_DIFF_MAX = 0.1f;
|
|
|
|
public static Model createMinimizedTerrainModelPrecomputedShader(float[][] heightfield, float[][] texturemap, ShaderProgram program, int stride){
|
|
|
|
class QuadToGenerate {
|
|
//coords are inclusive
|
|
int startX;
|
|
int endX;
|
|
int startY;
|
|
int endY;
|
|
float diff;
|
|
float min;
|
|
float max;
|
|
float texture;
|
|
boolean homogeneousTexture;
|
|
|
|
QuadToGenerate(int startX, int startY, int endX, int endY, float diff, float min, float max, boolean homogeneousTexture, float texture){
|
|
this.startX = startX;
|
|
this.startY = startY;
|
|
this.endX = endX;
|
|
this.endY = endY;
|
|
this.diff = diff;
|
|
this.min = min;
|
|
this.max = max;
|
|
this.texture = texture;
|
|
this.homogeneousTexture = homogeneousTexture;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
Model rVal = new Model();
|
|
rVal.meshes = new ArrayList<Mesh>();
|
|
Mesh m = new Mesh();
|
|
int width = heightfield.length;
|
|
int height = heightfield[0].length;
|
|
|
|
int actualWidth = (int)Math.ceil(1.0f * width / (1.0f * stride));
|
|
int actualHeight = (int)Math.ceil(1.0f * height / (1.0f * stride));
|
|
|
|
|
|
// System.out.println(actualWidth + " " + actualHeight);
|
|
|
|
// System.out.println((actualWidth - 1) * (actualHeight - 1));
|
|
|
|
FloatBuffer vertices;
|
|
FloatBuffer normals;
|
|
IntBuffer faces;
|
|
FloatBuffer texture_coords;
|
|
FloatBuffer textureIndices;
|
|
if(stride * actualWidth > width){
|
|
int drawWidth = actualWidth + 1;
|
|
int drawHeight = actualHeight + 1;
|
|
vertices = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 12);
|
|
normals = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 12);
|
|
faces = BufferUtils.createIntBuffer((drawWidth - 1) * (drawHeight - 1) * 2 * 3);
|
|
texture_coords = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 8);
|
|
textureIndices = BufferUtils.createFloatBuffer(drawWidth * drawHeight * 16);
|
|
} else {
|
|
vertices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 12);
|
|
normals = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 12);
|
|
faces = BufferUtils.createIntBuffer((actualWidth - 1) * (actualHeight - 1) * 2 * 3);
|
|
texture_coords = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 8);
|
|
textureIndices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 16);
|
|
}
|
|
|
|
|
|
//merge along y
|
|
|
|
List<QuadToGenerate> firstPhaseQuads = new LinkedList<QuadToGenerate>();
|
|
QuadToGenerate quadCurrent = null;
|
|
float minVal = 0;
|
|
float maxVal = 0;
|
|
int textureVal = -1;
|
|
for(int x = 0; x < width - 1; x = x + stride){
|
|
quadCurrent = null;
|
|
for(int y = 0; y < height - 1; y = y + stride){
|
|
if((x == 5 && y == 2)){
|
|
// System.out.println(quadCurrent);
|
|
// continue;
|
|
}
|
|
if(quadCurrent == null){
|
|
minVal = 100000000;
|
|
maxVal = 0;
|
|
textureVal = -1;
|
|
//minval
|
|
if(heightfield[x][y] < minVal){
|
|
minVal = heightfield[x][y];
|
|
}
|
|
if(heightfield[x+stride][y] < minVal){
|
|
minVal = heightfield[x+stride][y];
|
|
}
|
|
if(heightfield[x][y+stride] < minVal){
|
|
minVal = heightfield[x][y+stride];
|
|
}
|
|
if(heightfield[x+stride][y+stride] < minVal){
|
|
minVal = heightfield[x+stride][y+stride];
|
|
}
|
|
//maxval
|
|
if(heightfield[x][y] > maxVal){
|
|
maxVal = heightfield[x][y];
|
|
}
|
|
if(heightfield[x+stride][y] > maxVal){
|
|
maxVal = heightfield[x+stride][y];
|
|
}
|
|
if(heightfield[x][y+stride] > maxVal){
|
|
maxVal = heightfield[x][y+stride];
|
|
}
|
|
if(heightfield[x+stride][y+stride] > maxVal){
|
|
maxVal = heightfield[x+stride][y+stride];
|
|
}
|
|
boolean textureMatch = false;
|
|
float texture = -1;
|
|
if(x+stride < width - 1 && y+stride < height -1 &&
|
|
texturemap[x][y] == texturemap[x+stride][y] &&
|
|
texturemap[x][y] == texturemap[x][y+stride] &&
|
|
texturemap[x][y] == texturemap[x+stride][y+stride]){
|
|
|
|
textureMatch = true;
|
|
texture = texturemap[x][y];
|
|
} else {
|
|
// if(x > 8 && (x+stride < width - 1) && (y+stride < height -1)){
|
|
// System.out.println(
|
|
// (x+stride < width - 1) + " " +
|
|
// (y+stride < height -1) + " " +
|
|
// (texturemap[x][y] == texturemap[x+stride][y]) + " " +
|
|
// (texturemap[x][y] == texturemap[x][y+stride]) + " " +
|
|
// (texturemap[x][y] == texturemap[x+stride][y+stride])
|
|
// );
|
|
// }
|
|
}
|
|
if(textureMatch){
|
|
quadCurrent = new QuadToGenerate(x,y,x+stride,y+stride,maxVal - minVal,minVal,maxVal,textureMatch,texture);
|
|
} else {
|
|
firstPhaseQuads.add(new QuadToGenerate(x,y,x+stride,y+stride,maxVal - minVal,minVal,maxVal,textureMatch,texture));
|
|
// quadCurrent = null;
|
|
}
|
|
} else {
|
|
float newMin = minVal;
|
|
float newMax = maxVal;
|
|
//min
|
|
if(heightfield[x][y+stride] < newMin){
|
|
newMin = heightfield[x][y+stride];
|
|
}
|
|
if(heightfield[x+stride][y+stride] < newMin){
|
|
newMin = heightfield[x+stride][y+stride];
|
|
}
|
|
//max
|
|
if(heightfield[x][y+stride] > newMax){
|
|
newMax = heightfield[x][y+stride];
|
|
}
|
|
if(heightfield[x+stride][y+stride] > newMax){
|
|
newMax = heightfield[x+stride][y+stride];
|
|
}
|
|
if(y+stride < height - 1 && x+stride < width - 1){
|
|
if(newMax - newMin < MINIMIZATION_DIFF_MAX &&
|
|
quadCurrent.texture == texturemap[x+stride][y] &&
|
|
quadCurrent.texture == texturemap[x ][y+stride] &&
|
|
quadCurrent.texture == texturemap[x+stride][y+stride] &&
|
|
quadCurrent.homogeneousTexture
|
|
){
|
|
//add to quad
|
|
quadCurrent.endY = y + stride;
|
|
quadCurrent.diff = newMax - newMin;
|
|
quadCurrent.min = newMax;
|
|
quadCurrent.max = newMax;
|
|
} else {
|
|
//push quad
|
|
firstPhaseQuads.add(quadCurrent);
|
|
firstPhaseQuads.add(new QuadToGenerate(x,y,x+stride,y+stride,maxVal - minVal,minVal,maxVal,false,0));
|
|
quadCurrent = null;
|
|
// System.out.println("Push");
|
|
}
|
|
} else {
|
|
if(newMax - newMin < MINIMIZATION_DIFF_MAX){
|
|
//add to quad
|
|
quadCurrent.endY = y + stride;
|
|
quadCurrent.diff = newMax - newMin;
|
|
quadCurrent.min = newMax;
|
|
quadCurrent.max = newMax;
|
|
} else {
|
|
//push quad
|
|
firstPhaseQuads.add(quadCurrent);
|
|
quadCurrent = null;
|
|
// System.out.println("Push");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(quadCurrent != null){
|
|
firstPhaseQuads.add(quadCurrent);
|
|
}
|
|
}
|
|
|
|
List<QuadToGenerate> finalQuads = new LinkedList<QuadToGenerate>();
|
|
// for(QuadToGenerate current : firstPhaseQuads){
|
|
// finalQuads.add(current);
|
|
// }
|
|
|
|
// System.out.println(finalQuads.size());
|
|
|
|
//merge along x
|
|
|
|
// QuadToGenerate currentQuad = null;
|
|
List<QuadToGenerate> toSkip = new LinkedList<QuadToGenerate>();
|
|
for(QuadToGenerate currentQuad : firstPhaseQuads){
|
|
// toRemove.clear();
|
|
if(toSkip.contains(currentQuad)){
|
|
continue;
|
|
}
|
|
for(QuadToGenerate currentPotentialMatch : firstPhaseQuads){
|
|
if(currentPotentialMatch.startX <= currentQuad.startX){
|
|
continue;
|
|
}
|
|
if(currentPotentialMatch.startX > currentQuad.endX){
|
|
break;
|
|
}
|
|
if(currentPotentialMatch.startY != currentQuad.startY){
|
|
continue;
|
|
}
|
|
if(currentPotentialMatch.endY != currentQuad.endY){
|
|
continue;
|
|
}
|
|
if(
|
|
!(currentQuad.homogeneousTexture &&
|
|
currentPotentialMatch.homogeneousTexture &&
|
|
currentQuad.texture == currentPotentialMatch.texture)
|
|
){
|
|
continue;
|
|
}
|
|
if(currentQuad.min < currentPotentialMatch.min && currentQuad.max < currentPotentialMatch.max){
|
|
float min = currentQuad.min;
|
|
float max = currentPotentialMatch.max;
|
|
if(max - min < MINIMIZATION_DIFF_MAX){
|
|
currentQuad.endX = currentPotentialMatch.endX;
|
|
currentQuad.max = currentPotentialMatch.max;
|
|
toSkip.add(currentPotentialMatch);
|
|
}
|
|
} else if(currentQuad.min > currentPotentialMatch.min && currentQuad.max > currentPotentialMatch.max){
|
|
float min = currentPotentialMatch.min;
|
|
float max = currentQuad.max;
|
|
if(max - min < MINIMIZATION_DIFF_MAX){
|
|
currentQuad.endX = currentPotentialMatch.endX;
|
|
currentQuad.min = currentPotentialMatch.min;
|
|
toSkip.add(currentPotentialMatch);
|
|
}
|
|
} else {
|
|
if(currentQuad.min < currentPotentialMatch.min){
|
|
currentQuad.endX = currentPotentialMatch.endX;
|
|
} else {
|
|
currentQuad.endX = currentPotentialMatch.endX;
|
|
currentQuad.min = currentPotentialMatch.min;
|
|
currentQuad.max = currentPotentialMatch.max;
|
|
}
|
|
toSkip.add(currentPotentialMatch);
|
|
}
|
|
}
|
|
finalQuads.add(currentQuad);
|
|
}
|
|
// for(QuadToGenerate currentIteration : firstPhaseQuads){
|
|
// if(currentQuad == null){
|
|
// currentQuad = currentIteration;
|
|
// } else {
|
|
// //if should merge:
|
|
// if(
|
|
// currentQuad.homogeneousTexture &&
|
|
// currentIteration.homogeneousTexture &&
|
|
// currentQuad.texture == currentIteration.texture
|
|
// ){
|
|
// if(currentQuad.min < currentIteration.min && currentQuad.max < currentIteration.max){
|
|
// float min = currentQuad.min;
|
|
// float max = currentIteration.max;
|
|
// if(max - min < MINIMIZATION_DIFF_MAX){
|
|
// currentQuad.endX = currentIteration.endX;
|
|
// currentQuad.max = currentIteration.max;
|
|
// } else {
|
|
// finalQuads.add(currentQuad);
|
|
// currentQuad = currentIteration;
|
|
// }
|
|
// } else if(currentQuad.min > currentIteration.min && currentQuad.max > currentIteration.max){
|
|
// float min = currentIteration.min;
|
|
// float max = currentQuad.max;
|
|
// if(max - min < MINIMIZATION_DIFF_MAX){
|
|
// currentQuad.endX = currentIteration.endX;
|
|
// currentQuad.min = currentIteration.min;
|
|
// } else {
|
|
// finalQuads.add(currentQuad);
|
|
// currentQuad = currentIteration;
|
|
// }
|
|
// } else {
|
|
// if(currentQuad.min < currentIteration.min){
|
|
// currentQuad.endX = currentIteration.endX;
|
|
// } else {
|
|
// currentQuad.endX = currentIteration.endX;
|
|
// currentQuad.min = currentIteration.min;
|
|
// currentQuad.max = currentIteration.max;
|
|
// }
|
|
// }
|
|
// } else {
|
|
// finalQuads.add(currentQuad);
|
|
// currentQuad = currentIteration;
|
|
// }
|
|
// }
|
|
// }
|
|
// finalQuads.add(currentQuad);
|
|
|
|
// for(QuadToGenerate current : finalQuads){
|
|
// if(current.startX > 0 && current.startY > 0 && current.endX < 99 && current.endY < 99){
|
|
// System.out.println(current.startX + " " + current.startY + " " + current.endX + " " + current.endY);
|
|
// }
|
|
// }
|
|
|
|
// System.out.println("AAAAAAAAAAAAAAAAAA");
|
|
// System.out.println(finalQuads.size());
|
|
// System.exit(0);
|
|
|
|
int incrementer = 0;
|
|
|
|
for(QuadToGenerate current : finalQuads){
|
|
//deal with vertex
|
|
//0,0
|
|
vertices.put(current.startX);
|
|
vertices.put(heightfield[current.startX][current.startY]);
|
|
vertices.put(current.startY);
|
|
//1,0
|
|
vertices.put(current.endX);
|
|
vertices.put(heightfield[current.endX][current.startY]);
|
|
vertices.put(current.startY);
|
|
//0,1
|
|
vertices.put(current.startX);
|
|
vertices.put(heightfield[current.startX][current.endY]);
|
|
vertices.put(current.endY);
|
|
//1,1
|
|
vertices.put(current.endX);
|
|
vertices.put(heightfield[current.endX][current.endY]);
|
|
vertices.put(current.endY);
|
|
//deal with normal
|
|
Vector3f normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, current.startX, current.startY);
|
|
normals.put(normal.x);
|
|
normals.put(normal.y);
|
|
normals.put(normal.z);
|
|
normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, current.endX, current.startY);
|
|
normals.put(normal.x);
|
|
normals.put(normal.y);
|
|
normals.put(normal.z);
|
|
normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, current.startX, current.endY);
|
|
normals.put(normal.x);
|
|
normals.put(normal.y);
|
|
normals.put(normal.z);
|
|
normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, current.endX, current.endY);
|
|
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);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(1);
|
|
// } 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);
|
|
// }
|
|
// }
|
|
texture_coords.put(0);
|
|
texture_coords.put(0);
|
|
texture_coords.put(current.endX - current.startX);
|
|
texture_coords.put(0);
|
|
texture_coords.put(0);
|
|
texture_coords.put(current.endY - current.startY);
|
|
texture_coords.put(current.endX - current.startX);
|
|
texture_coords.put(current.endY - current.startY);
|
|
|
|
if(current.endX < width - 1 && current.endY < height - 1){
|
|
// texturemap[x+stride][y+stride];
|
|
for(int i = 0; i < 4 ; i++){
|
|
// textureIndices.put(1);
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
textureIndices.put(texturemap[current.startX][current.startY]);
|
|
textureIndices.put(texturemap[current.endX][current.startY]);
|
|
textureIndices.put(texturemap[current.startX][current.endY]);
|
|
textureIndices.put(texturemap[current.endX][current.endY]);
|
|
}
|
|
} else {
|
|
for(int i = 0; i < 4 ; i++){
|
|
textureIndices.put(0);
|
|
textureIndices.put(0);
|
|
textureIndices.put(0);
|
|
textureIndices.put(0);
|
|
}
|
|
}
|
|
|
|
|
|
//deal with faces
|
|
faces.put(incrementer * 4 + 0);
|
|
faces.put(incrementer * 4 + 1);
|
|
faces.put(incrementer * 4 + 2);
|
|
faces.put(incrementer * 4 + 1);
|
|
faces.put(incrementer * 4 + 2);
|
|
faces.put(incrementer * 4 + 3);
|
|
|
|
incrementer++;
|
|
}
|
|
|
|
|
|
|
|
// int numFaces = (actualWidth - 1) * (actualHeight - 1) * 2 * 3;
|
|
// for(int x = 0; x < width - 1; x = x + stride){
|
|
// for(int y = 0; y < height - 1; y = y + stride){
|
|
// //deal with vertex
|
|
// //0,0
|
|
// vertices.put(x);
|
|
// vertices.put(heightfield[x][y]);
|
|
// vertices.put(y);
|
|
// //1,0
|
|
// vertices.put(x + stride);
|
|
// vertices.put(heightfield[x+stride][y]);
|
|
// vertices.put(y);
|
|
// //0,1
|
|
// vertices.put(x);
|
|
// vertices.put(heightfield[x][y+stride]);
|
|
// vertices.put(y + stride);
|
|
// //1,1
|
|
// vertices.put(x + stride);
|
|
// vertices.put(heightfield[x+stride][y+stride]);
|
|
// vertices.put(y + stride);
|
|
// //deal with normal
|
|
// Vector3f normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x, y);
|
|
// normals.put(normal.x);
|
|
// normals.put(normal.y);
|
|
// normals.put(normal.z);
|
|
// normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x + stride, y);
|
|
// normals.put(normal.x);
|
|
// normals.put(normal.y);
|
|
// normals.put(normal.z);
|
|
// normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x, y + stride);
|
|
// normals.put(normal.x);
|
|
// normals.put(normal.y);
|
|
// normals.put(normal.z);
|
|
// normal = calculateTerrainNormal(heightfield, actualWidth, actualHeight, stride, x + stride, y + stride);
|
|
// 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);
|
|
//// texture_coords.put(1);
|
|
//// texture_coords.put(0);
|
|
//// texture_coords.put(0);
|
|
//// texture_coords.put(1);
|
|
//// texture_coords.put(1);
|
|
//// texture_coords.put(1);
|
|
//// } 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);
|
|
//// }
|
|
//// }
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(0);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(1);
|
|
// texture_coords.put(1);
|
|
//
|
|
// if(x + stride < width - 1 && y + stride < height - 1){
|
|
//// texturemap[x+stride][y+stride];
|
|
// for(int i = 0; i < 4 ; i++){
|
|
//// textureIndices.put(1);
|
|
//// textureIndices.put(0);
|
|
//// textureIndices.put(0);
|
|
//// textureIndices.put(0);
|
|
// textureIndices.put(texturemap[x][y]);
|
|
// textureIndices.put(texturemap[x+stride][y]);
|
|
// textureIndices.put(texturemap[x][y+stride]);
|
|
// textureIndices.put(texturemap[x+stride][y+stride]);
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < 4 ; i++){
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
// textureIndices.put(0);
|
|
// }
|
|
// }
|
|
//
|
|
//
|
|
// //deal with faces
|
|
// if(1.0f * x / stride < actualWidth - 1 && 1.0f * y / stride < actualHeight - 1){
|
|
// faces.put(incrementer * 4 + 0);
|
|
// faces.put(incrementer * 4 + 1);
|
|
// faces.put(incrementer * 4 + 2);
|
|
// faces.put(incrementer * 4 + 1);
|
|
// faces.put(incrementer * 4 + 2);
|
|
// faces.put(incrementer * 4 + 3);
|
|
// }
|
|
// incrementer++;
|
|
// }
|
|
// }
|
|
|
|
System.out.println(incrementer + " quads");
|
|
|
|
vertices.flip();
|
|
normals.flip();
|
|
faces.flip();
|
|
texture_coords.flip();
|
|
textureIndices.flip();
|
|
|
|
m.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(m.vertexArrayObject);
|
|
//buffer vertices
|
|
m.buffer_vertices(vertices, 3);
|
|
//buffer normals
|
|
m.buffer_normals(normals, 3);
|
|
//buffer faces
|
|
m.buffer_faces(faces);
|
|
//buffer texture coords
|
|
m.buffer_texture_coords(texture_coords, 2);
|
|
//texture indices
|
|
m.bufferCustomFloatAttribArray(textureIndices, 4, 5);
|
|
m.shader = program;
|
|
glBindVertexArray(0);
|
|
m.parent = rVal;
|
|
|
|
m.hasBones = false;
|
|
|
|
Material groundMat = new Material();
|
|
Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png");
|
|
groundMat.set_diffuse("/Textures/Ground/Dirt1.png");
|
|
groundMat.set_specular("/Textures/Ground/Dirt1.png");
|
|
m.setMaterial(groundMat);
|
|
|
|
rVal.meshes.add(m);
|
|
return rVal;
|
|
}
|
|
|
|
static Vector3f calculateTerrainNormal(float[][] heightfield, int actualWidth, int actualHeight, int stride, int x, int y){
|
|
Vector3f rVal = new Vector3f();
|
|
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];
|
|
}
|
|
rVal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
|
rVal.normalize();
|
|
} 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];
|
|
rVal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
|
rVal.normalize();
|
|
}
|
|
} 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];
|
|
}
|
|
rVal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
|
rVal.normalize();
|
|
} else {
|
|
float hL = heightfield[x-1][y];
|
|
float hR = heightfield[x][y];
|
|
float hD = heightfield[x][y];
|
|
float hU = heightfield[x][y-1];
|
|
rVal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
|
rVal.normalize();
|
|
}
|
|
}
|
|
return rVal;
|
|
}
|
|
|
|
|
|
public static Model createUnitCube(){
|
|
Model rVal = new Model();
|
|
rVal.meshes = new ArrayList<Mesh>();
|
|
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, 3);
|
|
//buffer normals
|
|
m.buffer_normals(normals, 3);
|
|
//buffer faces
|
|
m.buffer_faces(faces);
|
|
//buffer texture coords
|
|
m.buffer_texture_coords(texture_coords, 2);
|
|
m.shader = ShaderProgram.smart_assemble_shader(false,true);
|
|
glBindVertexArray(0);
|
|
m.parent = rVal;
|
|
|
|
Material groundMat = new Material();
|
|
Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png");
|
|
groundMat.set_diffuse("/Textures/Ground/Dirt1.png");
|
|
groundMat.set_specular("/Textures/Ground/Dirt1.png");
|
|
m.setMaterial(groundMat);
|
|
|
|
rVal.meshes.add(m);
|
|
return rVal;
|
|
}
|
|
|
|
|
|
|
|
}
|