Trying to improve chunk display.

This commit is contained in:
Quentin BAZIN 2013-05-28 06:58:06 +02:00
parent e3c632faa3
commit ff1498245c
9 changed files with 114 additions and 93 deletions

View File

@ -7,7 +7,7 @@ CXX := g++
#---------------------------------------------------------------------------------
# Options for code generation
#---------------------------------------------------------------------------------
CFLAGS := -g -Wall -O3
CFLAGS := -g -Wall -Wno-unused-result -O3
CXXFLAGS:= $(CFLAGS) --std=c++0x
LDFLAGS := -g -Wl

22
Notes
View File

@ -1,22 +0,0 @@
Cubes:
0: Nothing
1: Stone
2: Dirt
3: Dirt with grass
4: Grass
Faces:
0: y + 1 |
1: x + 1 |
2: x - 1 |
3: y - 1 |
4: z + 1 | Top
5: z - 1 | Bottom
SurroundingChunks:
0: FL
1: FR
2: BL
3: BR
4: Bottom
5: Top

6
TODO
View File

@ -1,4 +1,8 @@
- Caves
- Caves: Almost done.
- Improve performances:
* Improve update chunk display function with player direction
* Try with 16*16*256 chunks
* Make KubKraft framerate independant
- Text display
- Pause menu
- Main menu

View File

@ -27,15 +27,15 @@
#define APP_LABEL "KubKraft"
#define DIST_NEAR 0.1
#define DIST_FAR (12 << 3)
#define DIST_FAR (12 * (CHUNK_WIDTH + CHUNK_HEIGHT) / 2)
#define CHUNK_WIDTH 8
#define CHUNK_DEPTH 8
#define CHUNK_HEIGHT 8
#define CHUNK_WIDTH 16
#define CHUNK_DEPTH 16
#define CHUNK_HEIGHT 16
#define MAP_POS(x, y, z) ((x) + ((y) * Game::mapWidth) + ((z) * Game::mapWidth * Game::mapDepth))
#define _MAP_POS(x, y, z) ((x) + ((y) * m_width) + ((z) * m_width * m_depth))
#define CHUNK_POS(x, y, z) ((x) + ((y) * (m_width >> 3)) + ((z) * (m_width >> 3) * (m_depth >> 3)))
#define CHUNK_POS(x, y, z) ((x) + ((y) * (m_width / CHUNK_WIDTH)) + ((z) * (m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH)))
#define CUBE_POS(x, y, z) (((x) - m_x) + (((y) - m_y) * CHUNK_WIDTH) + (((z) - m_z) * CHUNK_WIDTH * CHUNK_HEIGHT))
#define PLAYER_HEIGHT 1.8

View File

@ -40,6 +40,10 @@ class Player {
float y() const { return m_y; }
float z() const { return m_eyeheight; }
vect3D speed() const { return m_speed; }
float angleH() const { return m_angleH; }
bool isJumping() const { return m_isJumping; }
void setJumpSpeed(float jumpSpeed) { m_speed.z = jumpSpeed; }
@ -58,6 +62,8 @@ class Player {
float m_angleH;
float m_angleV;
float m_direction;
bool m_isJumping;
vect3D m_speed;

View File

@ -42,12 +42,12 @@ using namespace std;
Player *Game::player;
Map *Game::map;
unsigned int Game::mapWidth = 64 << 3;
unsigned int Game::mapDepth = 64 << 3;
unsigned int Game::mapHeight = 16 << 3;
unsigned int Game::mapWidth = 16 * CHUNK_WIDTH;
unsigned int Game::mapDepth = 16 * CHUNK_DEPTH;
unsigned int Game::mapHeight = 8 * CHUNK_HEIGHT;
Game::Game() {
player = new Player(0, 0, 12 << 3, 90);
player = new Player(0, 0, 6 * CHUNK_HEIGHT, 90);
map = new Map(mapWidth, mapDepth, mapHeight);
}
@ -66,6 +66,9 @@ void Game::exec() {
uint32_t lastTime = SDL_GetTicks();
int nbFrames = 0;
//uint32_t timeDelta = 1000/30;
//uint32_t timeAccumulator = 0;
while(m_cont) {
uint32_t currentTime = SDL_GetTicks();
nbFrames++;
@ -77,10 +80,25 @@ void Game::exec() {
manageEvents();
/*uint32_t timeSimulated = 0;
uint32_t startTime = SDL_GetTicks();
while(timeAccumulator >= timeDelta) {
//stepGameState(timeDelta);
//for(uint32_t i = 0 ; i < timeDelta ; i++);
timeAccumulator -= timeDelta;
timeSimulated += timeDelta;
}
//stepAnimation(timeSimulated);
//for(uint32_t i = 0 ; i < timeSimulated ; i++);
*/
if(!m_paused) {
animate();
draw();
}
//timeAccumulator += SDL_GetTicks() - startTime;
}
unlockMouse();
@ -189,9 +207,14 @@ void Game::animate() {
player->move(distance, direction);
}
// Update player jump state
player->jump();
// Update player
player->update();
// Put camera
player->watch();
}
void Game::draw() {
@ -199,9 +222,6 @@ void Game::draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Put camera
player->watch();
// Display the map
map->render();

View File

@ -55,7 +55,7 @@ void initOpenGL() {
glEnable(GL_ALPHA_TEST);
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, DIST_FAR - (4 << 3));
glFogf(GL_FOG_START, DIST_FAR - (4 * (CHUNK_WIDTH + CHUNK_HEIGHT) / 2));
glFogf(GL_FOG_END, DIST_FAR);
glHint(GL_FOG_HINT, GL_DONT_CARE);
GLfloat fog_c[] = {0.5f, 0.5f, 0.5f, 1.0f};
@ -73,7 +73,7 @@ void initOpenGL() {
glLoadIdentity();
// Visible area definition
gluPerspective(WIN_FOV, (GLdouble)WIN_WIDTH / (GLdouble)WIN_HEIGHT, DIST_NEAR, DIST_FAR - (2 << 3));
gluPerspective(WIN_FOV, (GLdouble)WIN_WIDTH / (GLdouble)WIN_HEIGHT, DIST_NEAR, DIST_FAR - (2 * (CHUNK_WIDTH + CHUNK_HEIGHT) / 2));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

View File

@ -65,8 +65,8 @@ Map::Map(u16 width, u16 depth, u16 height) {
}
}
for (int yy = 0; yy < m_depth >> 3; yy++) {
for (int xx = 0; xx < m_width >> 3; xx++) {
for (int yy = 0; yy < m_depth / CHUNK_DEPTH; yy++) {
for (int xx = 0; xx < m_width / CHUNK_WIDTH; xx++) {
for (int yC = 0; yC < CHUNK_DEPTH; yC++) {
for (int xC = 0; xC < CHUNK_WIDTH; xC++) {
int x = xx * CHUNK_WIDTH + xC;
@ -81,14 +81,14 @@ Map::Map(u16 width, u16 depth, u16 height) {
if(cavePerlin > -2 && cavePerlin < 1) {
int dirtHeight = (1.0 - rand()%10 / 100 - 0.20) * heightValue;
if(zz < dirtHeight) m_map[_MAP_POS(xC + (xx << 3), yC + (yy << 3), zz)] = 1;
else if(zz > dirtHeight && zz < dirtHeight + 3) m_map[_MAP_POS(xC + (xx << 3), yC + (yy << 3), zz)] = rand()%2 + 1;
else m_map[_MAP_POS(xC + (xx << 3), yC + (yy << 3), zz)] = 2;
if(zz < 16 && cavePerlin > 0.01 && cavePerlin < 0.02) m_map[_MAP_POS(xC + (xx << 3), yC + (yy << 3), zz)] = 10;
if(zz < dirtHeight) m_map[_MAP_POS(xC + (xx * CHUNK_WIDTH), yC + (yy * CHUNK_DEPTH), zz)] = 1;
else if(zz > dirtHeight && zz < dirtHeight + 3) m_map[_MAP_POS(xC + (xx * CHUNK_WIDTH), yC + (yy * CHUNK_DEPTH), zz)] = rand()%2 + 1;
else m_map[_MAP_POS(xC + (xx * CHUNK_WIDTH), yC + (yy * CHUNK_DEPTH), zz)] = 2;
if(zz < 16 && cavePerlin > 0.01 && cavePerlin < 0.02) m_map[_MAP_POS(xC + (xx * CHUNK_WIDTH), yC + (yy * CHUNK_DEPTH), zz)] = 10;
}
if(zz == 0) {
m_map[_MAP_POS(xC + (xx << 3), yC + (yy << 3), zz)] = 5;
m_map[_MAP_POS(xC + (xx * CHUNK_WIDTH), yC + (yy * CHUNK_DEPTH), zz)] = 5;
}
}
}
@ -96,33 +96,33 @@ Map::Map(u16 width, u16 depth, u16 height) {
}
}
m_chunks = new Chunk*[(m_width >> 3) * (m_height >> 3) * (m_depth >> 3)];
m_chunks = new Chunk*[(m_width / CHUNK_WIDTH) * (m_height / CHUNK_HEIGHT) * (m_depth / CHUNK_DEPTH)];
for(u16 z = 0 ; z < m_height >> 3 ; z++) {
for(u16 y = 0 ; y < m_depth >> 3 ; y++) {
for(u16 x = 0 ; x < m_width >> 3 ; x++) {
m_chunks[CHUNK_POS(x, y, z)] = new Chunk(x << 3, y << 3, z << 3);
for(u16 z = 0 ; z < m_height / CHUNK_HEIGHT ; z++) {
for(u16 y = 0 ; y < m_depth / CHUNK_DEPTH ; y++) {
for(u16 x = 0 ; x < m_width / CHUNK_WIDTH ; x++) {
m_chunks[CHUNK_POS(x, y, z)] = new Chunk(x * CHUNK_WIDTH, y * CHUNK_DEPTH, z * CHUNK_HEIGHT);
}
}
}
for(u16 z = 0 ; z < m_height >> 3 ; z++) {
for(u16 y = 0 ; y < m_depth >> 3 ; y++) {
for(u16 x = 0 ; x < m_width >> 3 ; x++) {
int chunkIndex = x + (y * (m_width >> 3)) + (z * (m_width >> 3) * (m_depth >> 3));
for(u16 z = 0 ; z < m_height / CHUNK_HEIGHT ; z++) {
for(u16 y = 0 ; y < m_depth / CHUNK_DEPTH ; y++) {
for(u16 x = 0 ; x < m_width / CHUNK_WIDTH ; x++) {
int chunkIndex = x + (y * (m_width / CHUNK_WIDTH)) + (z * (m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH));
if(x - 1 >= 0) m_chunks[chunkIndex]->setSurroundingChunk(0, m_chunks[chunkIndex - 1]);
if(x + 1 < m_width >> 3) m_chunks[chunkIndex]->setSurroundingChunk(1, m_chunks[chunkIndex + 1]);
if(y - 1 >= 0) m_chunks[chunkIndex]->setSurroundingChunk(2, m_chunks[chunkIndex - (m_width >> 3)]);
if(y + 1 < m_depth >> 3) m_chunks[chunkIndex]->setSurroundingChunk(3, m_chunks[chunkIndex + (m_width >> 3)]);
if(z + 1 < m_height >> 3) m_chunks[chunkIndex]->setSurroundingChunk(4, m_chunks[chunkIndex + ((m_width >> 3) * (m_depth >> 3))]);
if(z - 1 >= 0) m_chunks[chunkIndex]->setSurroundingChunk(5, m_chunks[chunkIndex - ((m_width >> 3) * (m_depth >> 3))]);
if(x + 1 < m_width / CHUNK_WIDTH) m_chunks[chunkIndex]->setSurroundingChunk(1, m_chunks[chunkIndex + 1]);
if(y - 1 >= 0) m_chunks[chunkIndex]->setSurroundingChunk(2, m_chunks[chunkIndex - (m_width / CHUNK_WIDTH)]);
if(y + 1 < m_depth / CHUNK_DEPTH) m_chunks[chunkIndex]->setSurroundingChunk(3, m_chunks[chunkIndex + (m_width / CHUNK_WIDTH)]);
if(z + 1 < m_height / CHUNK_HEIGHT) m_chunks[chunkIndex]->setSurroundingChunk(4, m_chunks[chunkIndex + ((m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH))]);
if(z - 1 >= 0) m_chunks[chunkIndex]->setSurroundingChunk(5, m_chunks[chunkIndex - ((m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH))]);
}
}
}
int cubeCount = 0;
for(int i = 0 ; i < ((m_width >> 3) * (m_depth >> 3) * (m_height >> 3)); i++) {
for(int i = 0 ; i < ((m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH) * (m_height / CHUNK_HEIGHT)); i++) {
for(s32 z = m_chunks[i]->z() ; z < m_chunks[i]->z() + CHUNK_HEIGHT ; z++) {
for(s32 y = m_chunks[i]->y() ; y < m_chunks[i]->y() + CHUNK_DEPTH ; y++) {
for(s32 x = m_chunks[i]->x() ; x < m_chunks[i]->x() + CHUNK_WIDTH ; x++) {
@ -135,9 +135,9 @@ Map::Map(u16 width, u16 depth, u16 height) {
uint32_t time = SDL_GetTicks();
for(int i = 0 ; i < ((m_width >> 3) * (m_depth >> 3) * (m_height >> 3)); i++) {
for(int i = 0 ; i < ((m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH) * (m_height / CHUNK_HEIGHT)); i++) {
m_chunks[i]->refreshVBO();
cout << "Chunks loaded: " << i+1 << "/" << ((m_width >> 3) * (m_depth >> 3) * (m_height >> 3)) << endl;
cout << "Chunks loaded: " << i+1 << "/" << ((m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH) * (m_height / CHUNK_HEIGHT)) << endl;
}
cout << "Chunks loading time: " << (SDL_GetTicks() - time) << " ms for " << cubeCount << " cubes" << endl;
@ -153,7 +153,7 @@ Map::Map(u16 width, u16 depth, u16 height) {
for(long int z = m_chunkDisplay[2] ; z < m_chunkDisplay[5] ; z++) {
for(long int y = m_chunkDisplay[1] ; y < m_chunkDisplay[4] ; y++) {
for(long int x = m_chunkDisplay[0] ; x < m_chunkDisplay[3] ; x++) {
if(x < 0 || y < 0 || z < 0 || x >= (m_width >> 3) || y >= (m_depth >> 3) || z >= (m_height >> 3)) continue;
if(x < 0 || y < 0 || z < 0 || x >= (m_width / CHUNK_WIDTH) || y >= (m_depth / CHUNK_DEPTH) || z >= (m_height / CHUNK_HEIGHT)) continue;
pos = CHUNK_POS(x, y, z);
vect3D center;
@ -177,7 +177,7 @@ Map::Map(u16 width, u16 depth, u16 height) {
Map::~Map() {
free(m_map);
for(int i = 0 ; i < ((m_width >> 3) * (m_depth >> 3) * (m_height >> 3)); i++) {
for(int i = 0 ; i < ((m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH) * (m_height / CHUNK_HEIGHT)); i++) {
if(m_chunks[i] != NULL) delete m_chunks[i];
}
@ -190,13 +190,13 @@ Map::~Map() {
void Map::updateChunkDisplay() {
// Get visible chunk surface
m_chunkDisplay[0] = ((long)(Game::player->x() - DIST_FAR) >> 3);
m_chunkDisplay[1] = ((long)(Game::player->y() - DIST_FAR) >> 3);
m_chunkDisplay[2] = ((long)(Game::player->z() - DIST_FAR) >> 3);
m_chunkDisplay[0] = ((long)(Game::player->x() - DIST_FAR) / CHUNK_WIDTH);
m_chunkDisplay[1] = ((long)(Game::player->y() - DIST_FAR) / CHUNK_DEPTH);
m_chunkDisplay[2] = ((long)(Game::player->z() - DIST_FAR) / CHUNK_HEIGHT);
m_chunkDisplay[3] = ((long)(Game::player->x() + DIST_FAR) >> 3);
m_chunkDisplay[4] = ((long)(Game::player->y() + DIST_FAR) >> 3);
m_chunkDisplay[5] = ((long)(Game::player->z() + DIST_FAR) >> 3);
m_chunkDisplay[3] = ((long)(Game::player->x() + DIST_FAR) / CHUNK_WIDTH);
m_chunkDisplay[4] = ((long)(Game::player->y() + DIST_FAR) / CHUNK_DEPTH);
m_chunkDisplay[5] = ((long)(Game::player->z() + DIST_FAR) / CHUNK_HEIGHT);
}
float frustum[6][4];
@ -302,6 +302,7 @@ int cubeInFrustum(float x, float y, float z, float size) {
}
void Map::render() {
// Display a black square under the world
glColor3ub(0, 0, 0);
glBegin(GL_QUADS);
glVertex3f(0, 0, -0.01);
@ -311,17 +312,20 @@ void Map::render() {
glEnd();
glColor3ub(255, 255, 255);
// Select texture
glBindTexture(GL_TEXTURE_2D, m_texture);
// Turn on filters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//uint32_t time = SDL_GetTicks();
extractFrustum();
// Update chunk display array
updateChunkDisplay();
uint32_t time = SDL_GetTicks();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
@ -329,13 +333,27 @@ void Map::render() {
float distance = DIST_FAR;
currentChunk = NULL;
bool changed = false;
unsigned long long int pos;
for(long int z = m_chunkDisplay[2] ; z < m_chunkDisplay[5] ; z++) {
for(long int y = m_chunkDisplay[1] ; y < m_chunkDisplay[4] ; y++) {
for(long int x = m_chunkDisplay[0] ; x < m_chunkDisplay[3] ; x++) {
if(x < 0 || y < 0 || z < 0 || x >= (m_width >> 3) || y >= (m_depth >> 3) || z >= (m_height >> 3)) continue;
long long int xMax, yMax, zMax, xMin, yMin, zMin;
xMax = (m_chunkDisplay[0] + (m_chunkDisplay[1] - m_chunkDisplay[0]) / 2); xMin = xMax;
yMax = (m_chunkDisplay[2] + (m_chunkDisplay[3] - m_chunkDisplay[2]) / 2) * (m_width / CHUNK_WIDTH); yMin = yMax;
zMax = (m_chunkDisplay[4] + (m_chunkDisplay[5] - m_chunkDisplay[4]) / 2) * (m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH); zMin = zMax;
for(long long int z = m_chunkDisplay[2] ; z < m_chunkDisplay[5] ; z++) {
for(long long int y = m_chunkDisplay[1] ; y < m_chunkDisplay[4] ; y++) {
for(long long int x = m_chunkDisplay[0] ; x < m_chunkDisplay[3] ; x++) {
if(x < 0 || y < 0 || z < 0 || x >= (m_width / CHUNK_WIDTH) || y >= (m_depth / CHUNK_DEPTH) || z >= (m_height / CHUNK_HEIGHT)) continue;
pos = CHUNK_POS(x, y, z);
if(cubeInFrustum(m_chunks[pos]->x(), m_chunks[pos]->y(), m_chunks[pos]->z(), 8)) {
if(m_chunks[pos]->x() > xMax) { xMax = m_chunks[pos]->x(); changed = true; }
if(m_chunks[pos]->y() > yMax) { yMax = m_chunks[pos]->y(); changed = true; }
if(m_chunks[pos]->z() > zMax) { zMax = m_chunks[pos]->z(); changed = true; }
if(m_chunks[pos]->x() < xMin) { xMin = m_chunks[pos]->x(); changed = true; }
if(m_chunks[pos]->y() < yMin) { yMin = m_chunks[pos]->y(); changed = true; }
if(m_chunks[pos]->z() < zMin) { zMin = m_chunks[pos]->z(); changed = true; }
if(changed && cubeInFrustum(m_chunks[pos]->x(), m_chunks[pos]->y(), m_chunks[pos]->z(), (CHUNK_WIDTH + CHUNK_DEPTH) / 2)) {
m_chunks[pos]->render();
}
@ -359,11 +377,11 @@ void Map::render() {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
time = SDL_GetTicks() - time;
cout << "Render time: " << time << " ms" << endl;
testCubes();
//time = SDL_GetTicks() - time;
//cout << "Render time: " << time << " ms" << endl;
glBindTexture(GL_TEXTURE_2D, 0);
if ((currentChunk != NULL) && (selectedCube->x() != -1) && (selectedCube->selectedFace() >= 0) && (selectedCube->selectedFace() < 6)) {
@ -399,11 +417,11 @@ void Map::render() {
}
Chunk* Map::getChunk(int x, int y, int z) {
if ((x < 0) || (x >= m_width >> 3) || (y < 0) || (y >= m_depth >> 3) || (z < 0) || (z >= m_height >> 3)) {
if ((x < 0) || (x >= m_width / CHUNK_WIDTH) || (y < 0) || (y >= m_depth / CHUNK_DEPTH) || (z < 0) || (z >= m_height / CHUNK_HEIGHT)) {
return NULL;
}
int coords = x + (y * (m_width >> 3)) + (z * (m_width >> 3) * (m_depth >> 3));
int coords = x + (y * (m_width / CHUNK_WIDTH)) + (z * (m_width / CHUNK_WIDTH) * (m_depth / CHUNK_DEPTH));
return m_chunks[coords];
}
@ -519,9 +537,9 @@ void Map::testCubes() {
0, 1, -1, 0, -1, -1
};
c = getChunk((currentChunk->x() >> 3) + coords[(i-7)*3],
(currentChunk->y() >> 3) + coords[(i-7)*3 + 1],
(currentChunk->z() >> 3) + coords[(i-7)*3 + 2]);
c = getChunk((currentChunk->x() / CHUNK_WIDTH) + coords[(i-7)*3],
(currentChunk->y() / CHUNK_DEPTH) + coords[(i-7)*3 + 1],
(currentChunk->z() / CHUNK_HEIGHT) + coords[(i-7)*3 + 2]);
if(c == NULL) continue;

View File

@ -55,13 +55,8 @@ bool passable(s16 caseX, s16 caseY, s16 caseZ) {
int pos = MAP_POS(caseX, caseY, caseZ);
if(pos > 0 && pos < Game::map->width() * Game::map->depth() * Game::map->height()) {
int cubeid = Game::map->map()[pos];
if(passableCubes[cubeid]) {
return true;
} else {
return false;
}
} else {
return false;
}
if(passableCubes[cubeid]) return true;
else return false;
} else return false;
}