[DEV] tutorial 14 'basic terrain' implementation

This commit is contained in:
Edouard DUPIN 2020-04-20 01:19:21 +02:00
parent 9b423bd52a
commit 36dd2f7612
16 changed files with 141804 additions and 170 deletions

139339
res/bunny.obj Normal file

File diff suppressed because it is too large Load Diff

333
res/exampleOBJ.obj Normal file
View File

@ -0,0 +1,333 @@
# Blender v2.67 (sub 0) OBJ File: ''
# www.blender.org
o Cube
v -0.277688 1.160465 3.914409
v -0.277688 1.160465 -3.914412
v -0.277688 6.599417 3.914409
v -0.277688 6.599417 -3.914410
v 0.277689 6.749417 -4.064408
v 0.277687 6.749417 4.064413
v -0.277689 6.749417 4.064409
v -0.277688 6.749417 -4.064410
v 0.277688 1.010465 4.064410
v -0.277689 1.010465 4.064410
v 0.277689 1.010465 -4.064410
v -0.277688 1.010465 -4.064412
v 0.073231 1.270795 -3.755601
v 0.073231 1.270795 -3.755601
v 0.073231 1.270795 -3.755601
v 0.073231 1.270795 3.755601
v 0.073231 1.270795 3.755601
v 0.073231 1.270795 3.755601
v 0.073231 6.489087 -3.755599
v 0.073231 6.489087 -3.755599
v 0.073231 6.489087 -3.755599
v 0.073231 6.489087 3.755603
v 0.073231 6.489087 3.755603
v 0.073231 6.489087 3.755603
v -0.277688 1.160465 3.914409
v -0.277688 1.160465 3.914409
v -0.277688 1.160465 3.914409
v -0.277688 1.160465 -3.914412
v -0.277688 1.160465 -3.914412
v -0.277688 1.160465 -3.914412
v -0.277688 6.599417 3.914409
v -0.277688 6.599417 3.914409
v -0.277688 6.599417 3.914409
v -0.277688 6.599417 -3.914410
v -0.277688 6.599417 -3.914410
v -0.277688 6.599417 -3.914410
v 0.277689 6.749417 -4.064408
v 0.277689 6.749417 -4.064408
v 0.277689 6.749417 -4.064408
v 0.277689 6.749417 -4.064408
v 0.277687 6.749417 4.064413
v 0.277687 6.749417 4.064413
v 0.277687 6.749417 4.064413
v 0.277687 6.749417 4.064413
v -0.277688 6.749417 -4.064410
v -0.277688 6.749417 -4.064410
v -0.277688 6.749417 -4.064410
v -0.277688 6.749417 -4.064410
v -0.277689 6.749417 4.064409
v -0.277689 6.749417 4.064409
v -0.277689 6.749417 4.064409
v -0.277689 6.749417 4.064409
v 0.277688 1.010465 4.064410
v 0.277688 1.010465 4.064410
v 0.277688 1.010465 4.064410
v 0.277688 1.010465 4.064410
v -0.277689 1.010465 4.064410
v -0.277689 1.010465 4.064410
v -0.277689 1.010465 4.064410
v -0.277689 1.010465 4.064410
v 0.277689 1.010465 -4.064410
v 0.277689 1.010465 -4.064410
v 0.277689 1.010465 -4.064410
v 0.277689 1.010465 -4.064410
v -0.277688 1.010465 -4.064412
v -0.277688 1.010465 -4.064412
v -0.277688 1.010465 -4.064412
v -0.277688 1.010465 -4.064412
v 0.073231 1.270795 -3.755601
v 0.073231 1.270795 3.755601
v 0.073231 6.489087 -3.755599
v 0.073231 6.489087 3.755603
v -0.224736 -0.263644 3.371318
v -0.224736 -0.263644 2.987625
v 0.158956 -0.263644 2.987625
v 0.158956 -0.263644 3.371318
v -0.224736 1.124989 3.371318
v -0.224736 1.124989 2.987625
v 0.158956 1.124989 2.987625
v 0.158956 1.124989 3.371318
v -0.224736 -0.263644 -2.882437
v -0.224736 -0.263644 -3.266129
v 0.158956 -0.263644 -3.266129
v 0.158956 -0.263644 -2.882437
v -0.224736 1.124989 -2.882437
v -0.224736 1.124989 -3.266129
v 0.158956 1.124989 -3.266129
v 0.158956 1.124989 -2.882437
v -0.224736 1.124989 3.371318
v -0.224736 1.124989 3.371318
v -0.224736 1.124989 2.987625
v -0.224736 1.124989 2.987625
v -0.224736 -0.263644 2.987625
v -0.224736 -0.263644 2.987625
v -0.224736 -0.263644 3.371318
v -0.224736 -0.263644 3.371318
v 0.158956 1.124989 2.987625
v 0.158956 1.124989 2.987625
v 0.158956 -0.263644 2.987625
v 0.158956 -0.263644 2.987625
v 0.158956 1.124989 3.371318
v 0.158956 1.124989 3.371318
v 0.158956 -0.263644 3.371318
v 0.158956 -0.263644 3.371318
v -0.224736 1.124989 -2.882437
v -0.224736 1.124989 -2.882437
v -0.224736 1.124989 -3.266129
v -0.224736 1.124989 -3.266129
v -0.224736 -0.263644 -3.266129
v -0.224736 -0.263644 -3.266129
v -0.224736 -0.263644 -2.882437
v -0.224736 -0.263644 -2.882437
v 0.158956 1.124989 -3.266129
v 0.158956 1.124989 -3.266129
v 0.158956 -0.263644 -3.266129
v 0.158956 -0.263644 -3.266129
v 0.158956 1.124989 -2.882437
v 0.158956 1.124989 -2.882437
v 0.158956 -0.263644 -2.882437
v 0.158956 -0.263644 -2.882437
vt 0.072904 0.888916
vt 0.073177 0.731651
vt 0.892156 0.890337
vt 0.033572 0.648137
vt 0.966498 0.648137
vt 0.966498 0.992902
vt 0.885403 0.739675
vt 0.891024 0.901804
vt 0.046432 0.931085
vt 0.954577 0.995841
vt 0.021651 0.995841
vt 0.021651 0.651076
vt 0.012114 0.940261
vt 0.012114 0.874080
vt 0.945039 0.874080
vt 0.933118 0.757066
vt 0.933118 0.823248
vt 0.000193 0.823248
vt 0.831574 0.730632
vt 0.836172 0.882838
vt 0.038673 0.754583
vt -0.004575 0.653460
vt 0.928462 0.653460
vt 0.928462 0.998267
vt 0.904279 0.752987
vt 0.905988 0.884039
vt 0.223290 0.892944
vt 0.954688 0.997752
vt 0.021651 0.997752
vt 0.021651 0.652946
vt 0.009730 0.904588
vt 0.009730 0.838399
vt 0.942766 0.838399
vt 0.966608 0.850139
vt 0.966608 0.916329
vt 0.033572 0.916329
vt 0.892429 0.733072
vt 0.033572 0.992902
vt 0.040812 0.768955
vt 0.954577 0.651076
vt 0.945039 0.940261
vt 0.000193 0.757066
vt 0.043270 0.906790
vt -0.004575 0.998267
vt 0.221580 0.761891
vt 0.954688 0.652946
vt 0.942766 0.904589
vt 0.033572 0.850139
vt 0.959132 0.877638
vt 0.040502 0.877634
vt 0.976736 0.852300
vt 0.035266 0.995853
vt 0.035266 0.669132
vt 0.945133 0.995853
vt 0.076385 0.678435
vt 0.893378 0.678436
vt 0.893378 0.972183
vt 0.061741 0.675675
vt 0.955591 0.675674
vt 0.992341 0.956351
vt 0.613511 0.926087
vt 0.133853 0.904669
vt 0.133853 0.879178
vt 0.114185 0.737657
vt 0.599415 0.715982
vt 0.114183 0.763444
vt 0.940474 0.647273
vt 0.940473 0.992016
vt 0.042978 0.647273
vt 0.122126 0.901989
vt 0.328573 0.892696
vt 0.448853 0.912960
vt 0.898088 0.990689
vt 0.898087 0.663958
vt 0.904347 0.999699
vt 0.654947 0.984052
vt 0.654947 0.670585
vt 0.775916 0.654947
vt 0.911185 0.967892
vt 0.073547 0.967892
vt 0.073547 0.641170
vt 0.181226 0.766192
vt 0.830560 0.811308
vt 0.162456 0.777387
vt 0.629811 0.853269
vt 0.101284 0.829667
vt 0.937723 0.801280
vt 0.019080 0.989094
vt 0.345797 0.989095
vt 0.012820 0.998105
vt 0.916374 0.997716
vt 0.002199 0.986899
vt 0.008333 0.645963
vt 0.897485 0.670585
vt 0.897485 0.984052
vt 0.776517 0.999690
vt 0.988340 0.970203
vt 0.032136 0.970203
vt 0.032134 0.643481
vt 1.001168 0.004077
vt 1.001168 0.638868
vt 0.001884 0.638868
vt 0.022901 0.852300
vt 0.945133 0.669132
vt 0.076385 0.972182
vt 0.024993 0.956351
vt 0.892948 0.878905
vt 0.882101 0.763708
vt 0.042978 0.992016
vt 0.122129 0.912960
vt 0.904347 0.654947
vt 0.775916 0.999690
vt 0.911185 0.641170
vt 0.847603 0.824993
vt 0.101284 0.801578
vt 0.352057 0.998106
vt 0.997678 0.657668
vt 0.776517 0.654947
vt 0.988339 0.643481
vt 0.001884 0.004077
vn -1.000000 0.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 1.000000 -0.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn -0.999969 0.000000 0.000000
vn 0.786431 -0.617634 0.000000
vn 0.022523 -0.751610 -0.659200
vn 0.097201 -0.703757 -0.703726
vn 0.044496 -0.738304 -0.672964
vn 0.097201 -0.703757 0.703757
vn 0.022523 -0.751610 0.659200
vn 0.044496 -0.738304 0.672964
vn -0.016755 -0.737358 -0.675253
vn -0.040101 -0.776879 -0.628346
vn -0.026887 -0.754875 -0.655293
vn 0.833796 0.000000 0.552049
vn -0.040101 -0.776879 0.628346
vn -0.016755 -0.737388 0.675253
vn -0.026887 -0.754875 0.655293
vn 0.786431 0.617634 0.000000
vn 0.833796 0.000000 -0.552049
vn 0.000000 -0.999969 0.000000
vn 0.000000 0.999969 0.000000
vn 0.000000 -0.764550 -0.644520
vn 0.000000 -0.764550 0.644520
vn 0.000000 -0.707083 -0.707083
vn 0.000000 -0.707083 0.707083
s off
f 77/2/1 78/4/8 73/3/15
f 91/4/2 79/5/2 75/6/2
f 97/7/3 80/8/3 76/9/3
f 101/10/4 89/11/4 95/12/4
f 96/13/5 94/14/5 100/15/5
f 102/16/6 98/17/6 92/18/6
f 85/19/1 86/20/1 81/21/1
f 107/22/2 87/23/2 83/24/2
f 113/25/3 88/26/3 84/27/3
f 117/28/4 105/29/4 111/30/4
f 112/31/5 110/32/5 116/33/5
f 118/34/6 114/35/6 108/36/6
f 78/2/1 74/37/1 73/3/1
f 93/38/2 91/4/2 75/6/2
f 99/39/3 97/7/3 76/9/3
f 103/40/4 101/10/4 95/12/4
f 104/41/5 96/13/5 100/15/5
f 90/42/6 102/16/6 92/18/6
f 86/20/1 82/43/1 81/21/1
f 109/44/2 107/22/2 83/24/2
f 115/45/3 113/25/3 84/27/3
f 119/46/4 117/28/4 111/30/4
f 120/47/5 112/31/5 116/33/5
f 106/48/6 118/34/6 108/36/6
f 35/49/1 32/50/7 45/51/1
f 25/52/1 3/53/7 28/54/1
f 5/55/6 47/56/6 51/57/6
f 24/58/8 21/59/8 39/60/8
f 19/61/9 34/62/10 8/63/11
f 31/64/12 22/65/13 7/66/14
f 54/67/4 42/68/4 57/69/4
f 1/70/15 16/71/16 9/72/17
f 33/73/1 26/74/1 52/75/7
f 20/76/18 15/77/18 62/78/18
f 40/79/2 64/80/2 65/81/2
f 30/82/1 36/83/1 68/84/7
f 13/85/19 2/86/20 11/87/21
f 27/88/1 29/89/1 59/90/1
f 14/91/22 17/92/22 53/93/22
f 18/94/23 23/95/23 44/96/23
f 63/97/24 55/98/5 60/99/5
f 69/100/3 71/101/3 72/102/3
f 32/50/7 49/103/1 45/51/1
f 3/53/7 4/104/1 28/54/1
f 6/105/25 5/55/6 51/57/6
f 43/106/8 24/58/8 39/60/8
f 37/107/26 19/61/9 8/63/11
f 22/65/13 41/108/27 7/66/14
f 42/68/4 50/109/4 57/69/4
f 10/110/28 1/70/15 9/72/17
f 26/74/1 58/111/1 52/75/7
f 38/112/18 20/76/18 62/78/18
f 46/113/2 40/79/2 65/81/2
f 36/83/1 48/114/1 68/84/7
f 2/86/20 12/115/29 11/87/21
f 29/89/1 66/116/1 59/90/1
f 61/117/22 14/91/22 53/93/22
f 56/118/23 18/94/23 44/96/23
f 67/119/5 63/97/24 60/99/5
f 70/120/3 69/100/3 72/102/3

BIN
res/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

BIN
res/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

1649
res/tree.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
res/tree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -19,8 +19,9 @@ import renderEngine.DisplayManagerDraw;
import renderEngine.Loader;
import renderEngine.MasterRenderer;
import renderEngine.OBJLoader;
import renderEngine.Renderer;
import renderEngine.EntityRenderer;
import shaders.StaticShader;
import terrains.Terrain;
import textures.ModelTexture;
/**
@ -46,25 +47,24 @@ public class MainGameLoop {
RawModel model = OBJLoader.loadObjModel("cube", loader);
TexturedModel cubeModel = new TexturedModel(model, new ModelTexture(loader.loadTexture("tree_sample")));
ModelTexture texture = cubeModel.getTexture();
RawModel model = OBJLoader.loadObjModel("tree", loader);
TexturedModel staticModel = new TexturedModel(model, new ModelTexture(loader.loadTexture("tree")));
ModelTexture texture = staticModel.getTexture();
texture.setShineDamper(10);
texture.setReflectivity(1);
Light light = new Light(new Vector3f(0,0,-20), new Vector3f(1,1,1));
Light light = new Light(new Vector3f(3000,2000,2000), new Vector3f(1,1,1));
Terrain terrain = new Terrain(0,-1,loader, new ModelTexture(loader.loadTexture("grass")));
Terrain terrain2 = new Terrain(-1,-1,loader, new ModelTexture(loader.loadTexture("grass")));
Camera camera = new Camera();
List<Entity> allCubes = new ArrayList<Entity>();
List<Entity> entities = new ArrayList<Entity>();
Random random = new Random();
for (int iii=0; iii<2000; iii++) {
float x = random.nextFloat() * 300 - 150;
float y = random.nextFloat() * 300 - 150;
float z = random.nextFloat() * -300;
allCubes.add(new Entity(cubeModel, new Vector3f(x,y,z),
new Vector3f(random.nextFloat()*3.14f,random.nextFloat()*3.14f,0), 1));
entities.add(new Entity(staticModel, new Vector3f(random.nextFloat()*800 - 400,0,random.nextFloat() * -600),new Vector3f(0,0,0),3));
}
MasterRenderer renderer = new MasterRenderer();
@ -75,9 +75,11 @@ public class MainGameLoop {
//entity.increaseRotation(0, 0, 0.01f);
//entity.increaseRotation(0.01f, 0.02f, 0.0f);
camera.move();
for (Entity cube : allCubes) {
renderer.processEntity(cube);
for (Entity entity : entities) {
renderer.processEntity(entity);
}
renderer.processTerrain(terrain);
renderer.processTerrain(terrain2);
renderer.render(light, camera);
}
});

View File

@ -5,10 +5,10 @@ import javax.vecmath.Vector3f;
import renderEngine.DisplayManager;
public class Camera {
private Vector3f position = new Vector3f(0,0,0);
private float pitch;
private float yaw;
private float roll;
private Vector3f position = new Vector3f(0,5,0);
private float pitch = 0;// = (float) Math.toRadians(10);
private float yaw = 0;
private float roll = 0;
public Camera() {

View File

@ -0,0 +1,80 @@
package renderEngine;
import java.util.List;
import java.util.Map;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector2f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.windows.DISPLAY_DEVICE;
import entities.Entity;
import models.RawModel;
import models.TexturedModel;
import shaders.StaticShader;
import textures.ModelTexture;
import toolbox.Maths;
/**
* Handles the rendering of a model to the screen.
*
* @author Karl
*
*/
public class EntityRenderer {
private StaticShader shader;
public EntityRenderer(StaticShader shader, Matrix4f projectionMatrix) {
this.shader = shader;
shader.start();
shader.loadProjectionMatrix(projectionMatrix);
shader.stop();
}
public void render(Map<TexturedModel, List<Entity>> entities) {
for (TexturedModel model:entities.keySet()) {
prepareTexturedModel(model);
List<Entity> batch = entities.get(model);
for (Entity entity:batch) {
prepareInstance(entity);
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
}
unbindTexturedModel();
}
}
private void prepareTexturedModel(TexturedModel model) {
RawModel rawModel = model.getRawModel();
GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
ModelTexture texture = model.getTexture();
shader.loadShineVariable(texture.getShineDamper(), texture.getReflectivity());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getTexturedID());
}
private void unbindTexturedModel() {
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
private void prepareInstance(Entity entity) {
Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotation(), entity.getScale());
shader.loadTransformationMatrix(transformationMatrix);
}
}

View File

@ -5,26 +5,61 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector2f;
import org.lwjgl.opengl.GL11;
import entities.Camera;
import entities.Entity;
import entities.Light;
import models.TexturedModel;
import shaders.StaticShader;
import shaders.TerrainShader;
import terrains.Terrain;
public class MasterRenderer {
private static final float FOV = 70;
private static final float NEAR_PLANE = 0.1f;
private static final float FAR_PLANE = 10000;
private Matrix4f projectionMatrix;
private StaticShader shader = new StaticShader();
private Renderer renderer = new Renderer(shader);
private EntityRenderer renderer;
private TerrainRenderer terrainRenderer;
private TerrainShader terrainShader = new TerrainShader();
private Map<TexturedModel, List<Entity>> entities = new HashMap<TexturedModel, List<Entity>>();
private List<Terrain> terrains = new ArrayList<Terrain>();
public MasterRenderer() {
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_BACK);
createProjectionMatrix();
renderer = new EntityRenderer(shader, projectionMatrix);
terrainRenderer = new TerrainRenderer(terrainShader, projectionMatrix);
}
public void render(Light sun, Camera camera) {
renderer.prepare();
prepare();
shader.start();
shader.loadLight(sun);
shader.loadViewMatrix(camera);
renderer.render(entities);
shader.stop();
entities.clear();
terrainShader.start();
terrainShader.loadLight(sun);
terrainShader.loadViewMatrix(camera);
terrainRenderer.render(terrains);
terrainShader.stop();
terrains.clear();
}
public void processTerrain(Terrain terrain) {
terrains.add(terrain);
}
public void processEntity(Entity entity) {
@ -38,8 +73,74 @@ public class MasterRenderer {
entities.put(entityModel, newBatch);
}
}
public void prepare() {
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClearColor(1, 0, 0, 1);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
}
public void cleanUp () {
shader.cleanUp();
terrainShader.cleanUp();
}
private void createProjectionMatrix() {
//float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
Vector2f windowsSize = DisplayManager.getSize();
float aspectRatio = windowsSize.x / windowsSize.y;
// float y_scale = (float) ((1f/Math.atan(Math.toRadians(FOV/2f))) * aspectRatio);
// float x_scale = y_scale / aspectRatio;
// float frustrum_length = FAR_PLANE - NEAR_PLANE;
//
// projectionMatrix = new Matrix4f();
// projectionMatrix.m00 = x_scale;
// projectionMatrix.m11 = y_scale;
// projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustrum_length);
// projectionMatrix.m23 = -1;;
// projectionMatrix.m32 = -((2*FAR_PLANE * NEAR_PLANE) / frustrum_length);
// projectionMatrix.m33 = 0;
projectionMatrix = matPerspective(FOV, aspectRatio, NEAR_PLANE, FAR_PLANE);
}
Matrix4f matFrustum(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar) {
Matrix4f tmp = new Matrix4f();
// 0 1 2 3
// 4 5 6 7
// 8 9 10 11
// 12 13 14 15
tmp.m00 = (2.0f * zNear) / (xmax - xmin);
tmp.m11 = (2.0f * zNear) / (ymax - ymin);
tmp.m22 = -(zFar + zNear) / (zFar - zNear);
tmp.m02 = (xmax + xmin) / (xmax - xmin);
tmp.m12 = (ymax + ymin) / (ymax - ymin);
tmp.m32 = -1.0f;
tmp.m23 = -(2.0f * zFar * zNear) / (zFar - zNear);
return tmp;
}
Matrix4f matPerspective(float fovx, float aspect, float zNear, float zFar) {
//TK_DEBUG("drax perspective: fovx=" << fovx << "->" << aspect << " " << zNear << "->" << zFar);
float xmax = zNear * (float)Math.atan(fovx/2.0);
float xmin = -xmax;
float ymin = xmin / aspect;
float ymax = xmax / aspect;
//TK_DEBUG("drax perspective: " << xmin << "->" << xmax << " & " << ymin << "->" << ymax << " " << zNear << "->" << zFar);
return matFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
Matrix4f matOrtho(float left, float right, float bottom, float top, float nearVal, float farVal) {
Matrix4f tmp = new Matrix4f();
tmp.m00 = 2.0f / (right - left);
tmp.m11 = 2.0f / (top - bottom);
tmp.m22 = -2.0f / (farVal - nearVal);
tmp.m03 = -1*(right + left) / (right - left);
tmp.m13 = -1*(top + bottom) / (top - bottom);
tmp.m23 = -1*(farVal + nearVal) / (farVal - nearVal);
tmp.m33 = 1;
return tmp;
}
}

View File

@ -1,150 +0,0 @@
package renderEngine;
import java.util.List;
import java.util.Map;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector2f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.windows.DISPLAY_DEVICE;
import entities.Entity;
import models.RawModel;
import models.TexturedModel;
import shaders.StaticShader;
import textures.ModelTexture;
import toolbox.Maths;
/**
* Handles the rendering of a model to the screen.
*
* @author Karl
*
*/
public class Renderer {
private static final float FOV = 70;
private static final float NEAR_PLANE = 0.1f;
private static final float FAR_PLANE = 10000;
private Matrix4f projectionMatrix;
private StaticShader shader;
public Renderer(StaticShader shader) {
this.shader = shader;
createProjectionMatrix();
shader.start();
shader.loadProjectionMatrix(projectionMatrix);
shader.stop();
}
public void prepare() {
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_BACK);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClearColor(1, 0, 0, 1);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
}
public void render(Map<TexturedModel, List<Entity>> entities) {
for (TexturedModel model:entities.keySet()) {
prepareTexturedModel(model);
List<Entity> batch = entities.get(model);
for (Entity entity:batch) {
prepareInstance(entity);
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
}
unbindTexturedModel();
}
}
private void prepareTexturedModel(TexturedModel model) {
RawModel rawModel = model.getRawModel();
GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
ModelTexture texture = model.getTexture();
shader.loadShineVariable(texture.getShineDamper(), texture.getReflectivity());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getTexturedID());
}
private void unbindTexturedModel() {
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
private void prepareInstance(Entity entity) {
Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotation(), entity.getScale());
shader.loadTransformationMatrix(transformationMatrix);
}
private void createProjectionMatrix() {
//float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
Vector2f windowsSize = DisplayManager.getSize();
float aspectRatio = windowsSize.x / windowsSize.y;
// float y_scale = (float) ((1f/Math.atan(Math.toRadians(FOV/2f))) * aspectRatio);
// float x_scale = y_scale / aspectRatio;
// float frustrum_length = FAR_PLANE - NEAR_PLANE;
//
// projectionMatrix = new Matrix4f();
// projectionMatrix.m00 = x_scale;
// projectionMatrix.m11 = y_scale;
// projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustrum_length);
// projectionMatrix.m23 = -1;;
// projectionMatrix.m32 = -((2*FAR_PLANE * NEAR_PLANE) / frustrum_length);
// projectionMatrix.m33 = 0;
projectionMatrix = matPerspective(FOV, aspectRatio, NEAR_PLANE, FAR_PLANE);
}
Matrix4f matFrustum(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar) {
Matrix4f tmp = new Matrix4f();
// 0 1 2 3
// 4 5 6 7
// 8 9 10 11
// 12 13 14 15
tmp.m00 = (2.0f * zNear) / (xmax - xmin);
tmp.m11 = (2.0f * zNear) / (ymax - ymin);
tmp.m22 = -(zFar + zNear) / (zFar - zNear);
tmp.m02 = (xmax + xmin) / (xmax - xmin);
tmp.m12 = (ymax + ymin) / (ymax - ymin);
tmp.m32 = -1.0f;
tmp.m23 = -(2.0f * zFar * zNear) / (zFar - zNear);
return tmp;
}
Matrix4f matPerspective(float fovx, float aspect, float zNear, float zFar) {
//TK_DEBUG("drax perspective: fovx=" << fovx << "->" << aspect << " " << zNear << "->" << zFar);
float xmax = zNear * (float)Math.atan(fovx/2.0);
float xmin = -xmax;
float ymin = xmin / aspect;
float ymax = xmax / aspect;
//TK_DEBUG("drax perspective: " << xmin << "->" << xmax << " & " << ymin << "->" << ymax << " " << zNear << "->" << zFar);
return matFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
Matrix4f matOrtho(float left, float right, float bottom, float top, float nearVal, float farVal) {
Matrix4f tmp = new Matrix4f();
tmp.m00 = 2.0f / (right - left);
tmp.m11 = 2.0f / (top - bottom);
tmp.m22 = -2.0f / (farVal - nearVal);
tmp.m03 = -1*(right + left) / (right - left);
tmp.m13 = -1*(top + bottom) / (top - bottom);
tmp.m23 = -1*(farVal + nearVal) / (farVal - nearVal);
tmp.m33 = 1;
return tmp;
}
}

View File

@ -0,0 +1,65 @@
package renderEngine;
import java.util.List;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import models.RawModel;
import shaders.TerrainShader;
import terrains.Terrain;
import textures.ModelTexture;
import toolbox.Maths;
public class TerrainRenderer {
private TerrainShader shader;
public TerrainRenderer(TerrainShader shader, Matrix4f projectionMatrix) {
this.shader = shader;
shader.start();
shader.loadProjectionMatrix(projectionMatrix);
shader.stop();
}
public void render(List<Terrain> terrains) {
for (Terrain terrain : terrains) {
prepareTerrain(terrain);
loadModelMatrix(terrain);
GL11.glDrawElements(GL11.GL_TRIANGLES, terrain.getModel().getVertexCount(),
GL11.GL_UNSIGNED_INT, 0);
unbindTexturedModel();
}
}
private void prepareTerrain(Terrain terrain) {
RawModel rawModel = terrain.getModel();
GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
ModelTexture texture = terrain.getTexture();
shader.loadShineVariable(texture.getShineDamper(), texture.getReflectivity());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getTexturedID());
}
private void unbindTexturedModel() {
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
private void loadModelMatrix(Terrain terrain) {
Matrix4f transformationMatrix = Maths.createTransformationMatrix(
new Vector3f(terrain.getX(), 0, terrain.getZ()), new Vector3f(0, 0, 0), 1);
shader.loadTransformationMatrix(transformationMatrix);
}
}

View File

@ -0,0 +1,60 @@
package shaders;
import javax.vecmath.Matrix4f;
import entities.Camera;
import entities.Light;
import toolbox.Maths;
public class TerrainShader extends ShaderProgram {
private static final String VERTEX_FILE = "src/shaders/terrainVertexShader.txt";
private static final String FRAGMENT_FILE = "src/shaders/terrainFragmentShader.txt";
private int location_transformationMatrix;
private int location_projectionMatrix;
private int location_viewMatrix;
private int location_lightPosition;
private int location_lightColour;
private int location_reflectivity;
private int location_shineDamper;
public TerrainShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
super.bindAttribute(1, "textureCoords");
super.bindAttribute(2, "normal");
}
@Override
protected void getAllUniformLocations() {
location_transformationMatrix = super.getUniformLocation("transformationMatrix");
location_projectionMatrix = super.getUniformLocation("projectionMatrix");
location_viewMatrix = super.getUniformLocation("viewMatrix");
location_lightPosition = super.getUniformLocation("lightPosition");
location_lightColour = super.getUniformLocation("lightColour");
location_reflectivity = super.getUniformLocation("reflectivity");
location_shineDamper = super.getUniformLocation("shineDamper");
}
public void loadShineVariable(float shineDamper, float reflectivity) {
super.loadFloat(location_reflectivity, reflectivity);
super.loadFloat(location_shineDamper, shineDamper);
}
public void loadTransformationMatrix(Matrix4f matrix) {
super.loadMatrix(location_transformationMatrix, matrix);
}
public void loadLight(Light light) {
super.loadVector(location_lightPosition, light.getPosition());
super.loadVector(location_lightColour, light.getColour());
}
public void loadProjectionMatrix(Matrix4f projection) {
super.loadMatrix(location_projectionMatrix, projection);
}
public void loadViewMatrix(Camera camera) {
super.loadMatrix(location_viewMatrix, Maths.createViewMatrix(camera));
}
}

View File

@ -0,0 +1,37 @@
#version 400 core
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;
out vec4 out_Color;
uniform sampler2D textureSampler;
uniform vec3 lightColour;
uniform float reflectivity;
uniform float shineDamper;
void main(void) {
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal, unitLightVector);
// the 0.2 represent the anbiant lightning ==> maybe set an uniform for this
float brightness = max(nDot1, 0.2);
vec3 diffuse = brightness * lightColour;
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float damperFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = damperFactor * reflectivity * lightColour;
out_Color = vec4(diffuse,1.0) * texture(textureSampler,pass_textureCoords) + vec4(finalSpecular, 1.0);
}

View File

@ -0,0 +1,26 @@
#version 400 core
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;
void main(void) {
vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_textureCoords = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz;
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
}

92
src/terrains/Terrain.java Normal file
View File

@ -0,0 +1,92 @@
package terrains;
import models.RawModel;
import renderEngine.Loader;
import textures.ModelTexture;
public class Terrain {
private static final float SIZE = 800;
private static final int VERTEX_COUNT = 128;
private float x;
private float z;
private RawModel model;
private ModelTexture texture;
public Terrain(int girdX, int girdZ, Loader loader, ModelTexture texture) {
this.texture = texture;
this.x = girdX * SIZE;
this.z = girdZ * SIZE;
this.model = generateTerrain(loader);
}
private RawModel generateTerrain(Loader loader){
int count = VERTEX_COUNT * VERTEX_COUNT;
float[] vertices = new float[count * 3];
float[] normals = new float[count * 3];
float[] textureCoords = new float[count*2];
int[] indices = new int[6*(VERTEX_COUNT-1)*(VERTEX_COUNT-1)];
int vertexPointer = 0;
for(int i=0;i<VERTEX_COUNT;i++){
for(int j=0;j<VERTEX_COUNT;j++){
vertices[vertexPointer*3] = (float)j/((float)VERTEX_COUNT - 1) * SIZE;
vertices[vertexPointer*3+1] = 0;
vertices[vertexPointer*3+2] = (float)i/((float)VERTEX_COUNT - 1) * SIZE;
normals[vertexPointer*3] = 0;
normals[vertexPointer*3+1] = 1;
normals[vertexPointer*3+2] = 0;
textureCoords[vertexPointer*2] = (float)j/((float)VERTEX_COUNT - 1);
textureCoords[vertexPointer*2+1] = (float)i/((float)VERTEX_COUNT - 1);
vertexPointer++;
}
}
int pointer = 0;
for(int gz=0;gz<VERTEX_COUNT-1;gz++){
for(int gx=0;gx<VERTEX_COUNT-1;gx++){
int topLeft = (gz*VERTEX_COUNT)+gx;
int topRight = topLeft + 1;
int bottomLeft = ((gz+1)*VERTEX_COUNT)+gx;
int bottomRight = bottomLeft + 1;
indices[pointer++] = topLeft;
indices[pointer++] = bottomLeft;
indices[pointer++] = topRight;
indices[pointer++] = topRight;
indices[pointer++] = bottomLeft;
indices[pointer++] = bottomRight;
}
}
return loader.loadToVAO(vertices, textureCoords, normals, indices);
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getZ() {
return z;
}
public void setZ(float z) {
this.z = z;
}
public RawModel getModel() {
return model;
}
public void setModel(RawModel model) {
this.model = model;
}
public ModelTexture getTexture() {
return texture;
}
public void setTexture(ModelTexture texture) {
this.texture = texture;
}
}