Hello everyone!
Im trying to make smooth lighting on my 3d terrain. But result is bad (watch screenshots). I
m calculating verticles from the heightmap and normals from the verticles.
How can I fix this? I just want to make a sun
my code:
public class NGINE4 {
int w = 1280;
int h = 720;
double map[][];
int Size = 500;
Texture floorTex;
Texture grassTex;
List<Triangle> triangles= new ArrayList<Triangle>();
OBJLoader objl = new OBJLoader();
Obj grass = new Obj();
public static void main(String[] args) throws Exception {
NGINE4 ng = new NGINE4();
ng.start();
}
void initContext() throws Exception {
Camera.create();
Camera.moveSpeed = 0.1f;
Display.setDisplayMode(new DisplayMode(w, h));
Display.setFullscreen(false);
Display.create();
glViewport(0, 0, w, h);
Mouse.setGrabbed(true);
floorTex = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/FloorTex.jpg"));
grassTex = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/GrassTex.jpg"));
Random rand = new Random();
NoiseHeightMap nsh = new NoiseHeightMap(Size+1, rand.nextInt(10000000));
map = nsh.getHeightmap();
grass = objl.loadModel(new File("res/Grass_01.obj"));
}
double myRandom(double min, double max) {
Random r = new Random();
return (r.nextInt((int) ((max - min) * 10 + 1)) + min * 10) / 10.0;
}
public Vector3f Cross(Vector3f v1, Vector3f v2)
{
Vector3f result = new Vector3f(0,0,0);
result.x = (v1.y * v2.z) - (v1.z * v2.y);
result.y = (v1.z * v2.x) - (v1.x * v2.z);
result.z = (v1.x * v2.y) - (v1.y * v2.x);
return result;
}
public Vector3f Normalize(Vector3f v1)
{
float length = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z;
length = (float) Math.sqrt(length);
v1.x /= length; v1.x /= length; v1.x /= length;
return v1;
}
void renderLoop() {
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//glEnable(GL_DEPTH_TEST);
glTexParameterf(GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
float lightAmbient[] = {0.5f, 0.5f, 0.5f, 1.0f}; // Ambient Light Values
float lightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; // Diffuse Light Values
float lightPosition[] = {0.0f, 15.0f, 2.0f, 1.0f}; // Light Position
ByteBuffer temp = ByteBuffer.allocateDirect(16);
temp.order(ByteOrder.nativeOrder());
glLight(GL_LIGHT1, GL_AMBIENT, (FloatBuffer) temp.asFloatBuffer().put(lightAmbient).flip()); // Setup The Ambient Light
glLight(GL_LIGHT1, GL_DIFFUSE, (FloatBuffer) temp.asFloatBuffer().put(lightDiffuse).flip()); // Setup The Diffuse Light
glLight(GL_LIGHT1, GL_POSITION, (FloatBuffer) temp.asFloatBuffer().put(lightPosition).flip()); // Position The Light
glEnable(GL_LIGHT1);
long time = 0;
int frames = 0;
int heightmapExaggeration = 20;
// Random rand = new Random();
for (int x = 0; x < Size; x++) {
for (int y = 0; y < Size; y++) {
Vector3f v0 = new Vector3f(x * 0.25f,(float) (map[x][y] * heightmapExaggeration),y * 0.25f);
Vector3f v1 = new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f);
Vector3f v2 = new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f);
Vector3f normal = Normalize(Cross(new Vector3f(v2.x-v0.x,v2.y-v0.y,v2.z-v0.z), new Vector3f(v1.x-v0.x,v1.y-v0.y,v1.z-v0.z)));
Triangle t = new Triangle(
new Vector3f(x * 0.25f,(float) (map[x][y] * heightmapExaggeration),y * 0.25f),
new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f),
new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f),
normal, normal, normal,
new Vector2f(0,1),
new Vector2f(1,1),
new Vector2f(0,0),
1,1,1,
1,1,1,
1,1,1);
triangles.add(t);
Vector3f sv0 = new Vector3f(x * 0.25f,(float) (map[x][y] * heightmapExaggeration),y * 0.25f);
Vector3f sv1 = new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f);
Vector3f sv2 = new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f);
Vector3f snormal = Normalize(Cross(new Vector3f(sv2.x-sv0.x,sv2.y-sv0.y,sv2.z-sv0.z), new Vector3f(sv1.x-sv0.x,sv1.y-sv0.y,sv1.z-sv0.z)));
Triangle d = new Triangle(
new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y + 1] * heightmapExaggeration),(y + 1) * 0.25f),
new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f),
new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f),
snormal, snormal, snormal,
new Vector2f(1,0),
new Vector2f(1,1),
new Vector2f(0,0),
1,1,1,
1,1,1,
1,1,1);
triangles.add(d);
}
}
int vertex_size = 3; // X, Y, Z,
int color_size = 3; // R, G, B,
int texture_size = 2; // U, V
FloatBuffer vBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
FloatBuffer cBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
FloatBuffer tBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
FloatBuffer nBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
for (int x = 0; x < triangles.size()-10; x++) {
Triangle c = triangles.get(x);
cBuffer.put(c.v0r).put(c.v0g).put(c.v0b);
cBuffer.put(c.v1r).put(c.v1g).put(c.v1b);
cBuffer.put(c.v2r).put(c.v2g).put(c.v2b);
vBuffer.put(c.v0.x).put(c.v0.y).put(c.v0.z);
vBuffer.put(c.v1.x).put(c.v1.y).put(c.v1.z);
vBuffer.put(c.v2.x).put(c.v2.y).put(c.v2.z);
tBuffer.put(new float[] { c.t0.x, c.t0.y, }); // Texture Coordinate
tBuffer.put(new float[] { c.t1.x, c.t1.y, }); // Texture Coordinate
tBuffer.put(new float[] { c.t2.x, c.t2.y, }); // Texture Coordinate
nBuffer.put(c.n0.x).put(c.n0.y).put(c.n0.z);
nBuffer.put(c.n1.x).put(c.n1.y).put(c.n1.z);
nBuffer.put(c.n2.x).put(c.n2.y).put(c.n2.z);
}
cBuffer.flip();
vBuffer.flip();
tBuffer.flip();
nBuffer.flip();
int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
int vbo_color_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glBufferData(GL_ARRAY_BUFFER, cBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
int vbo_tex_coord_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coord_handle);
glBufferData(GL_ARRAY_BUFFER, tBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
int vbo_normal_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_normal_handle);
glBufferData(GL_ARRAY_BUFFER, nBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);
glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glColorPointer(color_size, GL_FLOAT, 0, 0l);
glBindTexture(GL_TEXTURE_2D, floorTex.getTextureID());
glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coord_handle);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(texture_size, GL_FLOAT, 0, 0l);
glBindBuffer(GL_ARRAY_BUFFER, vbo_normal_handle);
glNormalPointer(GL_FLOAT, 0, 0l);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
while (!Display.isCloseRequested()) {
preRender();
render();
Display.update();
Display.sync(60 /* desired fps */);
frames++;
if ((System.currentTimeMillis() - time) >= 1000) {
/*Ray r = getPickingRay();
Vector3f j = new Vector3f(-1,1,0);
Vector3f d = new Vector3f(1,1,0);
Vector3f t = new Vector3f(-1,-11,0);*/
Display.setTitle(" FPS: " + (int) ((frames * 1000) / (System.currentTimeMillis() - time))/*+ " " + RayTriangleIntersectionTest(r.Position, r.Direction,j,d,t)*/);
time = System.currentTimeMillis();
frames = 0;
}
}
glDeleteBuffers(vbo_vertex_handle);
glDeleteBuffers(vbo_color_handle);
glDeleteBuffers(vbo_tex_coord_handle);
glDeleteBuffers(vbo_normal_handle);
floorTex.release();
grassTex.release();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY_POINTER);
glDisableClientState(GL_NORMAL_ARRAY);
Display.destroy();
}
void preRender() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45.0f, ((float) w / (float) h), 0.1f, 100.0f); // fix na błąd z kamerą
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void render() {
Camera.acceptInput(0.3f);
Camera.apply();
glDrawArrays(GL_TRIANGLES, 0, ((Size * Size) * 2)*3 );
}
public FloatBuffer floatBuffer(float a, float b, float c, float d) {
float[] data = new float[]{a,b,c,d};
FloatBuffer fb = BufferUtils.createFloatBuffer(data.length);
fb.put(data);
fb.flip();
return fb;
}
public void start() throws Exception {
initContext();
renderLoop();
}
}