diff --git a/Makefile b/Makefile index 134c98b5..4470d48c 100755 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/Notes b/Notes index 4b12655b..e69de29b 100755 --- a/Notes +++ b/Notes @@ -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 diff --git a/TODO b/TODO index 52f49c65..630d828a 100755 --- a/TODO +++ b/TODO @@ -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 diff --git a/include/config.h b/include/config.h index 33d30a3c..82c75007 100644 --- a/include/config.h +++ b/include/config.h @@ -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 diff --git a/include/player.h b/include/player.h index 8c415eca..542eaa89 100644 --- a/include/player.h +++ b/include/player.h @@ -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; diff --git a/source/game.cpp b/source/game.cpp index c58616a2..65a710b9 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -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(); diff --git a/source/init.cpp b/source/init.cpp index 56ccbeee..1bf393ac 100644 --- a/source/init.cpp +++ b/source/init.cpp @@ -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(); diff --git a/source/map.cpp b/source/map.cpp index 2ab18a98..cbbe492e 100644 --- a/source/map.cpp +++ b/source/map.cpp @@ -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; diff --git a/source/mapManager.cpp b/source/mapManager.cpp index 318b52e7..70414d2e 100644 --- a/source/mapManager.cpp +++ b/source/mapManager.cpp @@ -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; }