This commit is contained in:
thatscringebro
2023-02-16 09:26:40 -05:00
parent cffe9490f0
commit 9dfd911bff
200 changed files with 28477 additions and 86 deletions

57
CPP/blockinfo.cpp Executable file
View File

@@ -0,0 +1,57 @@
#include "../H/blockinfo.h"
#include <iostream>
BlockInfo::BlockInfo(BlockType type, const std::string& name) : m_type(type), m_name(name), m_durability(1)
{
}
BlockInfo::BlockInfo()
{
}
BlockInfo::~BlockInfo()
{
}
BlockType BlockInfo::GetType() const
{
return m_type;
}
void BlockInfo::SetDurability(int durability)
{
m_durability = durability;
}
int BlockInfo::GetDurability() const
{
return m_durability;
}
void BlockInfo::SetUVWH(float u, float v, float w, float h){
m_u = u;
m_v = v;
m_w = w;
m_h = h;
}
float BlockInfo::GetU(){
return m_u;
}
float BlockInfo::GetV(){
return m_v;
}
float BlockInfo::GetW(){
return m_w;
}
float BlockInfo::GetH(){
return m_h;
}
void BlockInfo::Show() const
{
std::cout << "Type: " << m_type << std::endl;
std::cout << "Nom: " << m_name << std::endl;
std::cout << "Durabilite: " << m_durability << std::endl;
}

156
CPP/chunk.cpp Executable file
View File

@@ -0,0 +1,156 @@
#include "../H/chunk.h"
#include <climits>
Chunk::Chunk(): m_blocks(Array3d<BlockType>(CHUNK_SIZE_X, CHUNK_SIZE_Y, CHUNK_SIZE_Z)), m_isDirty(true){}
Chunk::Chunk(float x, float z) : m_blocks(Array3d<BlockType>(CHUNK_SIZE_X +1, CHUNK_SIZE_Y, CHUNK_SIZE_Z +1)), m_isDirty(true), m_posx(x), m_posz(z)
{
Perlin perlin(16, 6, 1, 95);
m_blocks.Reset(BTYPE_AIR);
for(int x = 0; x < CHUNK_SIZE_X; ++x)
{
for(int z = 0; z < CHUNK_SIZE_Z; ++z)
{
float val = perlin.Get((float)(m_posx + x) / 2000.f, (float)(m_posz + z) / 2000.f);
if (val < 0)
val *= -1;
val *= CHUNK_SIZE_Y;
val *= 0.4;
for (int i = 0; i < val; i++)
{
SetBlock(x , i, z, (rand()%(BTYPE_LAST - 1)+1));
}
}
}
}
Chunk::~Chunk()
{
}
void Chunk::RemoveBlock(int x, int y, int z)
{
m_blocks.Set(x, y, z, BTYPE_AIR);
m_isDirty = true;
}
void Chunk::SetBlock(int x, int y, int z, BlockType type)
{
m_blocks.Set(x, y, z, type);
m_isDirty = true;
}
BlockType Chunk::GetBlock(int x, int y, int z)
{
return m_blocks.Get(x, y, z);
}
void Chunk::Update(BlockInfo bi[BTYPE_LAST]){
bool front;
bool back;
bool top;
bool bottom;
bool left;
bool right;
// Update mesh
if (m_isDirty)
{
int maxVertexCount = (CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z) * (6 * 4);
VertexBuffer::VertexData * vd = new VertexBuffer::VertexData[maxVertexCount];
int count = 0;
for (int x = 0; x < CHUNK_SIZE_X; ++x)
{
for (int z = 0; z < CHUNK_SIZE_Z; ++z)
{
for (int y = 0; y < CHUNK_SIZE_Y; ++y)
{
if (count > USHRT_MAX)
break;
BlockType bt = GetBlock(x ,y ,z);
if ( bt != BTYPE_AIR )
{
AddBlockToMesh(vd, count, bt, x, y, z, bi);
}
}
}
}
if (count > USHRT_MAX)
{
count = USHRT_MAX;
std::cout << "[ Chunk :: Update ] Chunk data truncaned, too much vertices to have a 16 bit index" << std::endl;
}
m_vertexBuffer.SetMeshData(vd, count);
delete[] vd;
}
m_isDirty = false ;
}
void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, BlockInfo bi[BTYPE_LAST])
{
BlockInfo biCourant = bi[bt];
float u = biCourant.GetU();
float v = biCourant.GetV();
float w = biCourant.GetW();
float h = biCourant.GetH();
//front
if(GetBlock(x,y,z+1) == BTYPE_AIR){
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y - .5f, m_posz + z + .5f, 1.f, 1.f, 1.f, u, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y - .5f, m_posz + z + .5f, 1.f, 1.f, 1.f, u + w, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y + .5f, m_posz + z + .5f, 1.f, 1.f, 1.f, u + w, v + h);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y + .5f, m_posz + z + .5f, 1.f, 1.f, 1.f, u, v + h);
}
//back
if(GetBlock(x,y,z-1) == BTYPE_AIR){
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y - .5f, m_posz + z - .5f, 1.f, 1.f, 1.f, u, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y + .5f, m_posz + z - .5f, 1.f, 1.f, 1.f, u + w, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y + .5f, m_posz + z - .5f, 1.f, 1.f, 1.f, u + w, v + h);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y - .5f, m_posz + z - .5f, 1.f, 1.f, 1.f, u, v + h);
}
//top
if(GetBlock(x,y+1,z) == BTYPE_AIR){
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y + .5f, m_posz + z - .5f, 0.8f, 0.8f, 0.8f, u, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y + .5f, m_posz + z + .5f, 0.8f, 0.8f, 0.8f, u + w, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y + .5f, m_posz + z + .5f, 0.8f, 0.8f, 0.8f, u + w, v + h);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y + .5f, m_posz + z - .5f, 0.8f, 0.8f, 0.8f, u, v + h);
}
//bottom
if(GetBlock(x,y-1,z) == BTYPE_AIR){
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y - .5f, m_posz + z - .5f, 0.8f, 0.8f, 0.8f, u, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y - .5f, m_posz + z - .5f, 0.8f, 0.8f, 0.8f, u + w, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y - .5f, m_posz + z + .5f, 0.8f, 0.8f, 0.8f, u + w, v + h);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y - .5f, m_posz + z + .5f, 0.8f, 0.8f, 0.8f, u, v + h);
}
//left
if(GetBlock(x-1,y,z) == BTYPE_AIR){
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y - .5f, m_posz + z + .5f, 0.9f, 0.9f, 0.9f, u, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y + .5f, m_posz + z + .5f, 0.9f, 0.9f, 0.9f, u + w, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y + .5f, m_posz + z - .5f, 0.9f, 0.9f, 0.9f, u + w, v + h);
vd[count++] = VertexBuffer::VertexData(m_posx + x - .5f, y - .5f, m_posz + z - .5f, 0.9f, 0.9f, 0.9f, u, v + h);
}
//Right
if(GetBlock(x+1,y,z) == BTYPE_AIR){
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y + .5f, m_posz + z - .5f, 0.9f, 0.9f, 0.9f, u, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y + .5f, m_posz + z + .5f, 0.9f, 0.9f, 0.9f, u + w, v);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y - .5f, m_posz + z + .5f, 0.9f, 0.9f, 0.9f, u + w, v + h);
vd[count++] = VertexBuffer::VertexData(m_posx + x + .5f, y - .5f, m_posz + z - .5f, 0.9f, 0.9f, 0.9f, u, v + h);
}
}
void Chunk::Render() const{
m_vertexBuffer.Render();
}
bool Chunk::IsDirty() const{
return m_isDirty;
}

732
CPP/engine.cpp Executable file
View File

@@ -0,0 +1,732 @@
#include "../H/engine.h"
#include "../H/transformation.h"
#include <algorithm>
#include <cmath>
#include <iostream>
#include <fstream>
Engine::Engine() : m_p1(Vector3f(VIEW_DISTANCE,20,VIEW_DISTANCE)), m_textureAtlas(BTYPE_LAST), m_chunks(Array2d<Chunk*>(VIEW_DISTANCE * 2 / CHUNK_SIZE_X, VIEW_DISTANCE * 2 / CHUNK_SIZE_Z)), m_currentBlock(Vector4f(0,0,0,0)), m_currentMob(Vector3f(0,0,0),0,0)
{
}
Engine::~Engine()
{
SaveGame();
}
void Engine::LoadGame(std::ifstream SaveFile){
std::cout << "LOADING THE GAME" << std::endl;
if (SaveFile.is_open())
{
std::string Block;
while (std::getline(SaveFile, Block))
{
int notdigit = 0;
std::string x,y,z,t;
for (int i = 0; i < Block.length(); i++)
{
if (isdigit(Block[i]))
{
if (notdigit < 2)
x += Block[i];
else if (notdigit < 3)
y += Block[i];
else if (notdigit < 4)
z += Block[i];
else if (notdigit < 5)
t += Block[i];
}
else
notdigit++;
}
Vector4f Bloc(stoi(x), stoi(y), stoi(z), stoi(t));
m_ModifiedBlocks.push_front(Bloc);
SetBlockAt(stoi(x), stoi(y), stoi(z), stoi(t));
}
std::cout << "GAME LOADED" << std::endl;
SaveFile.close();
}
else
std::cout << "Problem opening the save file :(" << std::endl;
}
void Engine::SaveGame(){
std::cout << "SAVING THE GAME" << std::endl;
std::ofstream SaveFile("SaveFile");
if(SaveFile.is_open()){
for (size_t i = 0; i < m_ModifiedBlocks.size() + 1; i++)
{
if (m_ModifiedBlocks.front().x >= 0 && m_ModifiedBlocks.front().y >= 0 && m_ModifiedBlocks.front().z >= 0){
SaveFile << "{" << m_ModifiedBlocks.front().x << ";" << m_ModifiedBlocks.front().y << ";" << m_ModifiedBlocks.front().z << ";" << m_ModifiedBlocks.front().t << "}" << std::endl;
}
m_ModifiedBlocks.pop_front();
}
SaveFile.close();
std::cout << "GAME SAVED" << std::endl;
}
else
std::cout << "Problem writing to the save file :(" << std::endl;
}
void Engine::Init()
{
//glEnable(GL_CULL_FACE);
// Initialize GLEW
GLenum glewErr = glewInit();
if ( glewErr != GLEW_OK )
{
std :: cerr << " ERREUR GLEW : " << glewGetErrorString(glewErr) << std :: endl ;
abort();
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)Width() / (float)Height(), 0.0001f, 1000.0f);
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LINE_SMOOTH);
// Light
GLfloat light0Pos[4] = { 0.0f, CHUNK_SIZE_Y, 0.0f, 1.0f };
GLfloat light0Amb[4] = { 0.9f, 0.9f, 0.9f, 1.0f };
GLfloat light0Diff[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light0Spec[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, light0Amb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diff);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0Spec);
CenterMouse();
HideCursor();
}
void Engine::DeInit()
{
}
void Engine::LoadResource()
{
LoadTexture(m_textureCrosshair, TEXTURE_PATH "cross.bmp");
LoadTexture(m_textureFont, TEXTURE_PATH "font.bmp");
LoadTexture(m_textureMob, TEXTURE_PATH "mob.png");
TextureAtlas::TextureIndex texDarkIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "dark.png");
TextureAtlas::TextureIndex texDarkerIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "darker.png");
TextureAtlas::TextureIndex texLightIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "light.png");
TextureAtlas::TextureIndex texLighterIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "lighter.png");
float u,v,w,h;
m_textureAtlas.TextureIndexToCoord(texDarkerIndex, u,v,w,h);
m_bi[BTYPE_DARKER].SetUVWH(u, v, w, h);
m_textureAtlas.TextureIndexToCoord(texDarkIndex, u,v,w,h);
m_bi[BTYPE_DARK].SetUVWH(u, v, w, h);
m_textureAtlas.TextureIndexToCoord(texLighterIndex, u,v,w,h);
m_bi[BTYPE_LIGHTER].SetUVWH(u, v, w, h);
m_textureAtlas.TextureIndexToCoord(texLightIndex, u,v,w,h);
m_bi[BTYPE_LIGHT].SetUVWH(u, v, w, h);
if(!m_textureAtlas.Generate(1024, false))
{
std::cout << "Unable to generate texture atlas ..." << std::endl;
abort();
}
std::cout << "Loading and compiling shaders ..." << std::endl;
if (!m_shader01.Load(SHADER_PATH "shader01.vert", SHADER_PATH "shader01.frag", true))
{
std::cout << " Failed to load shader " << std::endl;
exit(1);
}
for (int x = 0; x < (VIEW_DISTANCE * 2 / CHUNK_SIZE_X); x++)
{
for (int z = 0; z < (VIEW_DISTANCE * 2 / CHUNK_SIZE_Z); z++)
{
m_chunks.Set(x, z, new Chunk(x * CHUNK_SIZE_X, z * CHUNK_SIZE_Z));
}
}
m_chunks.Set(15, 15, new Chunk(15 * CHUNK_SIZE_X, 15 * CHUNK_SIZE_Z));
LoadGame(std::ifstream("SaveFile"));
}
void Engine::UnloadResource()
{
}
void Engine::Render(float elapsedTime)
{
static float gameTime = elapsedTime;
gameTime += elapsedTime;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Transformations initiales
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Transformation player_move;
bool OnGround = false;
Vector3f pos = m_p1.Position();
Vector3f delta = m_p1.SimulateMove(m_keyW, m_keyS, m_keyA, m_keyD, m_shift, elapsedTime);
delta.y = -0.1;
float jumpvalue = 0;
BlockType bt1, bt2, bt3;
bt1 = BlockAt(pos.x, pos.y - 1.7f, pos.z, BTYPE_DARK);
if (bt1 != BTYPE_AIR)
OnGround = true;
bt2 = BlockAt(pos.x, pos.y + delta.y, pos.z, BTYPE_DARK);
if (bt2 != BTYPE_AIR)
m_jumpsize = 1.6;
m_jumpsize += m_p1.SimulateJump(m_space, m_InJump, jumpvalue, OnGround, m_jumpsize);
//Collisions for x:
bt1 = BlockAt(pos.x + delta.x, pos.y, pos.z, BTYPE_AIR);
bt2 = BlockAt(pos.x + delta.x, pos.y - 0.9f, pos.z, BTYPE_AIR);
bt3 = BlockAt(pos.x + delta.x, pos.y - 1.6f, pos.z, BTYPE_AIR);
if(bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR)
delta.x = 0;
// Collisions for y
bt1 = BlockAt(pos.x, pos.y - 1.7f, pos.z, BTYPE_DARK);
if(bt1 != BTYPE_AIR){
delta.y = 0;
}
//Colisions for z
bt1 = BlockAt(pos.x, pos.y, pos.z + delta.z, BTYPE_AIR);
bt2 = BlockAt(pos.x, pos.y - 0.9f, pos.z + delta.z, BTYPE_AIR);
bt3 = BlockAt(pos.x, pos.y - 1.6f, pos.z + delta.z, BTYPE_AIR);
if(bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR)
delta.z = 0;
pos.y += jumpvalue;
pos += delta;
m_p1.SetPosition(pos);
m_p1.ApplyTransformation(player_move);
player_move.Use();
m_textureAtlas.Bind();
//translation
player_move.ApplyTranslation(0.5f,0.5f,0.5f);
//use the above
player_move.Use();
m_shader01.Use();
for (int x = 0; x < (VIEW_DISTANCE * 2 / CHUNK_SIZE_X); x++)
{
for (int z = 0; z < (VIEW_DISTANCE * 2 / CHUNK_SIZE_Z); z++)
{
if (m_chunks.Get(x,z)->IsDirty())
m_chunks.Get(x,z)->Update(m_bi);
m_chunks.Get(x,z)->Render();
}
}
Shader::Disable();
m_textureMob.Bind();
for (int i = 0; i < m_mobs.size(); i++)
{
if (m_mobs[i].Health() <= 0)
m_mobs.erase(m_mobs.begin() + i);
Vector3f posMob = m_mobs[i].Position();
if ((posMob.x <= pos.x + 0.1 && posMob.x >= pos.x - 0.1) && (posMob.y <= pos.y + 0.1 && posMob.y >= pos.y - 0.1) && (posMob.z <= pos.z + 0.1 && posMob.z >= pos.z - 0.1))
{
m_mobs[i].Damage(m_p1);
m_mobs[i].SetPosition(Vector3f(posMob.x - 5, posMob.y + 5, posMob.z - 5));
}
m_mobs[i].Move(m_p1);
m_mobs[i].RenderMob();
}
m_points = m_mobs.size() * 100;
if(m_wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
DrawHud(elapsedTime);
if(m_wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (m_p1.Health() <= 0)
{
SaveGame();
Stop();
}
}
void Engine::KeyPressEvent(unsigned char key)
{
switch(key)
{
case 36: // ESC
SaveGame();
Stop();
break;
case 94: // F10
SetFullscreen(!IsFullscreen());
break;
case 38: // Shift
m_shift = true;
m_run = true;
break;
case 22: // W
m_keyW = true;
m_walk = true;
break;
case 0: // A
m_keyA = true;
m_walk = true;
break;
case 18: // S
m_keyS = true;
m_walk = true;
break;
case 3: // D
m_keyD = true;
m_walk = true;
break;
case 57: // spacebar
m_space = true;
break;
case 60: //tab
if (m_selectedbloc <= BTYPE_LIGHTER)
m_selectedbloc++;
else
m_selectedbloc = BTYPE_DARK;
break;
default:
std::cout << "Unhandled key: " << (int)key << std::endl;
}
}
void Engine::KeyReleaseEvent(unsigned char key)
{
switch(key)
{
case 38: // Shift
m_shift = false;
m_run = false;
break;
case 22: // W
m_keyW = false;
if (!m_keyW && !m_keyS && !m_keyD && !m_keyA)
m_walk = false;
break;
case 0: // A
m_keyA = false;
if (!m_keyW && !m_keyS && !m_keyD && !m_keyA)
m_walk = false;
break;
case 18: // S
m_keyS = false;
if (!m_keyW && !m_keyS && !m_keyD && !m_keyA)
m_walk = false;
break;
case 3: // D
m_keyD = false;
if (!m_keyW && !m_keyS && !m_keyD && !m_keyA)
m_walk = false;
break;
case 57: // spacebar
m_space = false;
break;
case 24: // Y
m_wireframe = !m_wireframe;
if(m_wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
}
}
void Engine::MouseMoveEvent(int x, int y)
{
// Centrer la souris seulement si elle n'est pas d<>j<EFBFBD> centr<74>e
// Il est n<>cessaire de faire la v<>rification pour <20>viter de tomber
// dans une boucle infinie o<> l'appel <20> CenterMouse g<>n<EFBFBD>re un
// MouseMoveEvent, qui rapelle CenterMouse qui rapelle un autre
// MouseMoveEvent, etc
if(x == (Width() / 2) && y == (Height() / 2))
return;
MakeRelativeToCenter(x, y);
//m_p1.TurnLeftRight(y);
//m_p1.TurnTopBottom(x);
m_p1.TurnCamera(x, y);
CenterMouse();
}
void Engine::MousePressEvent(const MOUSE_BUTTON& button, int x, int y)
{
switch (button)
{
case 1:
if(!m_currentMob.isNull())
HitMob();
else
DestroyBlocGenerateMob();
break;
case 4:
CreateBloc();
break;
default:
std::cout << "Unhandled mouse action" << std::endl;
break;
}
}
void Engine::MouseReleaseEvent(const MOUSE_BUTTON& button, int x, int y)
{
}
bool Engine::LoadTexture(Texture& texture, const std::string& filename, bool stopOnError)
{
texture.Load(filename);
if(!texture.IsValid())
{
std::cerr << "Unable to load texture (" << filename << ")" << std::endl;
if(stopOnError)
Stop();
return false;
}
return true;
}
int Engine::GetFps(float elapsedTime){
return 1 / elapsedTime;
}
void Engine::DrawHud(float elapsedTime)
{
// Set the blend func, all that is black will be transparent
glDisable(GL_LIGHTING);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBlendFunc(GL_SRC_ALPHA , GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, Width (), 0, Height (), -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Font
m_textureFont.Bind();
std::ostringstream ss;
for (int i = 0; i < m_mobs.size(); i++)
{
ss << "Mob#" << i << " health: " << m_mobs[i].Health();
PrintText(10, Height () - 40 - (i * 10), ss.str());
ss.str("");
}
ss << "Score:" << m_points;
PrintText(Width() / 2, Height () - 25, ss.str());
ss.str("");
ss << "Health:" << m_p1.Health();
PrintText(Width() / 2, Height () - 35, ss.str());
ss.str("");
ss << "Fps: " << GetFps(elapsedTime);
PrintText(10, Height () - 25, ss.str());
ss.str("");
ss << "Selected bloc type: " << m_selectedbloc;
PrintText(10, 20, ss.str());
ss.str("");
ss << "Position: " << m_p1.Position();
PrintText (10, 10, ss.str());
// Crosshair
m_textureCrosshair.Bind();
static const int crossSize = 32;
glLoadIdentity();
glTranslated(Width () / 2 - crossSize / 2, Height () / 2 - crossSize / 2, 0);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(0, 0);
glTexCoord2f(1, 0);
glVertex2i(crossSize, 0);
glTexCoord2f(1, 1);
glVertex2i(crossSize, crossSize);
glTexCoord2f(0, 1);
glVertex2i(0, crossSize);
glEnd();
glEnable(GL_LIGHTING);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void Engine::PrintText(unsigned int x, unsigned int y, const std::string& t)
{
glLoadIdentity();
glTranslated(x, y, 0);
for(unsigned int i = 0; i<t.length(); ++i)
{
float left = (float)((t[i] - 32) % 16) / 16.0f;
float top = (float)((t[i] - 32) / 16) / 16.0f;
top += 0.5f;
glBegin(GL_QUADS);
glTexCoord2f(left, 1.0f - top - 0.0625f);
glVertex2f(0, 0);
glTexCoord2f(left + 0.0625f, 1.0f - top - 0.0625f);
glVertex2f(12, 0);
glTexCoord2f(left + 0.0625f, 1.0f - top);
glVertex2f(12, 12);
glTexCoord2f(left, 1.0f - top);
glVertex2f(0, 12);
glEnd();
glTranslated(8, 0, 0);
}
}
Chunk* Engine::ChunkAt(float x, float y, float z) const
{
int cx = (int)x / CHUNK_SIZE_X;
int cz = (int)z / CHUNK_SIZE_Z;
if (cx > VIEW_DISTANCE * 2 / CHUNK_SIZE_X || cz > VIEW_DISTANCE * 2 / CHUNK_SIZE_Z || cx < 0 || cz < 0)
{
std::cout << "WRONG CHUNK POSITION" << std::endl;
return nullptr;
}
return m_chunks.Get(cx, cz);
}
Chunk* Engine::ChunkAt(const Vector3<float>& pos) const
{
return ChunkAt(pos.x, pos.y, pos.z);
}
BlockType Engine::BlockAt(float x, float y, float z, BlockType defaultBlockType) const
{
Chunk* c = ChunkAt(x, y, z);
if(!c)
return defaultBlockType;
int bx = (int)x % CHUNK_SIZE_X;
int by = (int)y % CHUNK_SIZE_Y;
int bz = (int)z % CHUNK_SIZE_Z;
return c->GetBlock(bx, by, bz);
}
void Engine::SetBlockAt(float x, float y, float z, BlockType BlockToSet) const{
Chunk* c = ChunkAt(x, y, z);
int bx = (int)x % CHUNK_SIZE_X;
int by = (int)y % CHUNK_SIZE_Y;
int bz = (int)z % CHUNK_SIZE_Z;
c->SetBlock(bx, by, bz, BlockToSet);
}
bool Engine::IsWalking(){
if (m_keyA || m_keyD || m_keyS || m_keyW)
return true;
else
return false;
}
static bool EqualWithEpsilon(const float& v1, const float& v2, float epsilon = float(0.0001))
{
return (fabs(v2 - v1) < epsilon);
}
static bool InRangeWithEpsilon(const float& v, const float& vinf, const float& vsup, float epsilon = float(0.0001))
{
return (v >= vinf - epsilon && v <= vsup + epsilon);
}
void Engine::GetBlocAtCursor()
{
int x = Width() / 2;
int y = Height() / 2;
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
posX += .5f;
posY += .5f;
posZ += .5f;
// Le cast vers int marche juste pour les valeurs entiere, utiliser une fonction de la libc si besoin
// de valeurs negatives
int px = (int)(posX);
int py = (int)(posY);
int pz = (int)(posZ);
bool found = false;
if((m_p1.Position() - Vector3f((float)posX, (float)posY, (float)posZ)).Length() < MAX_SELECTION_DISTANCE)
{
// Apres avoir determine la position du bloc en utilisant la partie entiere du hit
// point retourne par opengl, on doit verifier de chaque cote du bloc trouve pour trouver
// le vrai bloc. Le vrai bloc peut etre different a cause d'erreurs de precision de nos
// nombres flottants (si z = 14.999 par exemple, et qu'il n'y a pas de blocs a la position
// 14 (apres arrondi vers l'entier) on doit trouver et retourner le bloc en position 15 s'il existe
// A cause des erreurs de precisions, ils arrive que le cote d'un bloc qui doit pourtant etre a la
// position 15 par exemple nous retourne plutot la position 15.0001
for(int x = px - 1; !found && x <= px + 1; ++x)
{
for(int y = py - 1; !found && x >= 0 && y <= py + 1; ++y)
{
for(int z = pz - 1; !found && y >= 0 && z <= pz + 1; ++z)
{
if(z >= 0)
{
Mob mob = MobAt((float)x,(float)y, (float)z);
if (!mob.isNull())
m_currentMob = mob;
BlockType bt = BlockAt((float)x,(float)y, (float)z, BTYPE_AIR);
if(bt == BTYPE_AIR)
continue;
// Skip water blocs
//if(bloc->Type == BT_WATER)
// continue;
m_currentBlock.x = x;
m_currentBlock.y = y;
m_currentBlock.z = z;
m_currentBlock.t = bt;
if(InRangeWithEpsilon((float)posX, (float)x, (float)x + 1.f, 0.05f) && InRangeWithEpsilon((float)posY, (float)y, (float)y + 1.f, 0.05f) && InRangeWithEpsilon((float)posZ, (float)z, (float)z + 1.f, 0.05f))
{
found = true;
}
}
}
}
}
}
if(!found)
{
m_currentBlock.x = -1;
}
else
{
// Find on which face of the bloc we got an hit
m_currentFaceNormal.Zero();
const float epsilon = 0.09f;
// Front et back:
if(EqualWithEpsilon((float)posZ, (float)m_currentBlock.z, epsilon))
m_currentFaceNormal.z = -1;
else if(EqualWithEpsilon((float)posZ, (float)m_currentBlock.z + 1.f, epsilon))
m_currentFaceNormal.z = 1;
else if(EqualWithEpsilon((float)posX, (float)m_currentBlock.x, epsilon))
m_currentFaceNormal.x = -1;
else if(EqualWithEpsilon((float)posX, (float)m_currentBlock.x + 1.f, epsilon))
m_currentFaceNormal.x = 1;
else if(EqualWithEpsilon((float)posY, (float)m_currentBlock.y, epsilon))
m_currentFaceNormal.y = -1;
else if(EqualWithEpsilon((float)posY, (float)m_currentBlock.y + 1.f, epsilon))
m_currentFaceNormal.y = 1;
}
}
void Engine::CreateBloc(){
GetBlocAtCursor();
Vector4f Bloc(m_currentBlock.x + m_currentFaceNormal.x, m_currentBlock.y + m_currentFaceNormal.y, m_currentBlock.z + m_currentFaceNormal.z, m_selectedbloc);
m_ModifiedBlocks.push_front(Bloc);
SetBlockAt(m_currentBlock.x + m_currentFaceNormal.x, m_currentBlock.y + m_currentFaceNormal.y, m_currentBlock.z + m_currentFaceNormal.z, m_selectedbloc);
}
void Engine::DestroyBloc(){
GetBlocAtCursor();
Vector4f Bloc(m_currentBlock.x, m_currentBlock.y, m_currentBlock.z, BTYPE_AIR);
m_ModifiedBlocks.push_front(Bloc);
SetBlockAt(m_currentBlock.x, m_currentBlock.y, m_currentBlock.z, BTYPE_AIR);
}
void Engine::DestroyBlocGenerateMob(){
GetBlocAtCursor();
Vector4f Bloc(m_currentBlock.x, m_currentBlock.y, m_currentBlock.z, BTYPE_AIR);
m_ModifiedBlocks.push_front(Bloc);
SetBlockAt(m_currentBlock.x, m_currentBlock.y, m_currentBlock.z, BTYPE_AIR);
Vector3f v(m_currentBlock.x, m_currentBlock.y, m_currentBlock.z);
int dmg;
if(m_currentBlock.t == BTYPE_AIR)
dmg = 1000;
else
dmg = m_currentBlock.t;
Mob NewMob(v, dmg, dmg);
m_mobs.push_back(NewMob);
}
void Engine::HitMob(){
GetBlocAtCursor();
for (int i = 0; i < m_mobs.size(); i++)
{
if(m_mobs[i].isEqual(m_currentMob))
{
m_p1.Damage(m_mobs[i]);
}
}
}
Mob Engine::MobAt(int x, int y, int z){
for (int i = 0; i < m_mobs.size(); i++)
{
Vector3f posMob = m_mobs[i].Position();
if((posMob.x <= x + 0.5f && posMob.x >= x - 0.5f) && (posMob.y <= y + 0.5f && posMob.y >= y - 0.5f) && (posMob.z <= z + 0.5f && posMob.z >= z - 0.5f))
{
return m_mobs[i];
}
}
return Mob(Vector3f(0,0,0), 0, 0);
}

17
CPP/main.cpp Executable file
View File

@@ -0,0 +1,17 @@
#include <iostream>
#include "../H/engine.h"
#include "../H/sounds.h"
void ManageSounds(Engine engine){
std::cout << "walking" << std::endl;
}
int main()
{
Engine engine;
Sounds sounds;
std::thread t(&Sounds::ManageSounds, &sounds, &engine);
engine.SetMaxFps(60);
engine.Start("TheLandofWildBlocs", 800, 600, true);
return 0;
}

133
CPP/mob.cpp Executable file
View File

@@ -0,0 +1,133 @@
#include "../H/player.h"
Mob::Mob(){}
Mob::Mob(const Vector3f & position, float Damage, int Armour) : m_pos(position), m_damage(Damage), m_armour(Armour)
{
m_health = 100.f * Armour;
}
void Mob::SetPosition (Vector3f delta){
m_pos.x = delta.x;
m_pos.y = delta.y;
m_pos.z = delta.z;
}
void Mob::Move(Player p1){
double speed = 0.1;
Vector3f p1pos = p1.Position();
if (p1pos.x >= m_pos.x){
m_pos.x += speed;
}
if (p1pos.x < m_pos.x){
m_pos.x -= speed;
}
if (p1pos.y >= m_pos.y){
m_pos.y += speed;
}
if (p1pos.y < m_pos.y){
m_pos.y -= speed;
}
if (p1pos.z >= m_pos.z){
m_pos.z += speed;
}
if (p1pos.z < m_pos.z){
m_pos.z -= speed;
}
}
Vector3f Mob::Position(){
return m_pos;
}
void Mob::Damage(Player& p1){
p1.setHealth(p1.Health() - m_damage);
}
float Mob::GetDamage(){
return m_damage;
}
float Mob::Health(){
return m_health;
}
void Mob::setHealth(float health){
m_health = health;
}
void Mob::RenderMob()
{
//around1
glBegin(GL_TRIANGLES);
glNormal3f(0, 1, 0);
glTexCoord2f(0, 0);
glVertex3f(m_pos.x, m_pos.y + .5f, m_pos.z);
glTexCoord2f(1, 0);
glVertex3f(m_pos.x + .5f, m_pos.y - .5f, m_pos.z - .5f);
glTexCoord2f(1, 1);
glVertex3f(m_pos.x - .5f, m_pos.y - .5f, m_pos.z + .5f);
glEnd();
//around2
glBegin(GL_TRIANGLES);
glNormal3f(0, 1, 0);
glTexCoord2f(0, 0);
glVertex3f(m_pos.x, m_pos.y + .5f, m_pos.z);
glTexCoord2f(1, 0);
glVertex3f(m_pos.x - .5f, m_pos.y - .5f, m_pos.z + .5f);
glTexCoord2f(1, 1);
glVertex3f(m_pos.x + .5f, m_pos.y - .5f, m_pos.z + .5f);
glEnd();
//around3
glBegin(GL_TRIANGLES);
glNormal3f(0, 1, 0);
glTexCoord2f(0, 0);
glVertex3f(m_pos.x, m_pos.y + .5f, m_pos.z);
glTexCoord2f(1, 0);
glVertex3f(m_pos.x + .5f, m_pos.y - .5f, m_pos.z + .5f);
glTexCoord2f(1, 1);
glVertex3f(m_pos.x + .5f, m_pos.y - .5f, m_pos.z - .5f);
glEnd();
//bottom
glBegin(GL_TRIANGLES);
glNormal3f(0, -1, 0);
glTexCoord2f(0, 0);
glVertex3f(m_pos.x + .5f, m_pos.y - .5f, m_pos.z - .5f);
glTexCoord2f(1, 0);
glVertex3f(m_pos.x - .5f, m_pos.y - .5f, m_pos.z + .5f);
glTexCoord2f(1, 1);
glVertex3f(m_pos.x + .5f, m_pos.y - .5f, m_pos.z + .5f);
glEnd();
}
bool Mob::isNull(){
if (m_pos.x == 0 && m_pos.y == 0 && m_pos.z == 0 && m_damage == 0 && m_armour == 0)
return true;
return false;
}
int Mob::GetArmour(){
return m_armour;
}
bool Mob::isEqual(Mob mob){
Vector3f v = mob.Position();
if (m_pos.x == v.x && m_pos.y == v.y && m_pos.z == v.z && m_damage == mob.GetDamage() && m_armour == mob.GetArmour())
return true;
return false;
}

172
CPP/openglcontext.cpp Executable file
View File

@@ -0,0 +1,172 @@
#include "../H/openglcontext.h"
#include "../H/define.h"
OpenglContext::OpenglContext() : m_maxFps(999999), m_fullscreen(false), m_title(""), m_lastFrameTime(0)
{
}
OpenglContext::~OpenglContext()
{
}
bool OpenglContext::Start(const std::string& title, int width, int height, bool fullscreen)
{
m_title = title;
m_fullscreen = fullscreen;
InitWindow(width, height);
Init();
LoadResource();
sf::Clock clock;
while (m_app.isOpen())
{
clock.restart();
sf::Event Event;
while (m_app.pollEvent(Event))
{
switch(Event.type)
{
case sf::Event::Closed:
m_app.close();
break;
case sf::Event::Resized:
glViewport(0, 0, Event.size.width, Event.size.height);
break;
case sf::Event::KeyPressed:
KeyPressEvent(Event.key.code);
break;
case sf::Event::KeyReleased:
KeyReleaseEvent(Event.key.code);
break;
case sf::Event::MouseMoved:
MouseMoveEvent(Event.mouseMove.x, Event.mouseMove.y);
break;
case sf::Event::MouseButtonPressed:
MousePressEvent(ConvertMouseButton(Event.mouseButton.button), Event.mouseButton.x, Event.mouseButton.y);
break;
case sf::Event::MouseButtonReleased:
MouseReleaseEvent(ConvertMouseButton(Event.mouseButton.button), Event.mouseButton.x, Event.mouseButton.y);
break;
case sf::Event::MouseWheelMoved:
if(Event.mouseWheel.delta > 0)
MousePressEvent(MOUSE_BUTTON_WHEEL_UP, Event.mouseButton.x, Event.mouseButton.y);
else
MousePressEvent(MOUSE_BUTTON_WHEEL_DOWN, Event.mouseButton.x, Event.mouseButton.y);
break;
}
}
m_app.setActive();
Render(m_lastFrameTime);
m_app.display();
m_lastFrameTime = clock.getElapsedTime().asSeconds();
// Handle ourself frame rate limit, sf::Window::setFramerateLimit doesn't seems to work
float waitTime = (1.f / m_maxFps) - m_lastFrameTime;
if(waitTime > 0)
{
sf::sleep(sf::seconds(waitTime));
m_lastFrameTime = clock.getElapsedTime().asSeconds();
}
}
UnloadResource();
DeInit();
return true;
}
bool OpenglContext::Stop()
{
m_app.close();
return true;
}
void OpenglContext::CenterMouse()
{
sf::Mouse::setPosition(sf::Vector2i(Width() / 2, Height() / 2), m_app);
}
int OpenglContext::Width() const
{
return m_app.getSize().x;
}
int OpenglContext::Height() const
{
return m_app.getSize().y;
}
void OpenglContext::SetMaxFps(int maxFps)
{
m_maxFps = maxFps;
m_app.setFramerateLimit(maxFps);
}
int OpenglContext::GetMaxFps() const
{
return m_maxFps;
}
void OpenglContext::SetFullscreen(bool fullscreen)
{
if(m_fullscreen == fullscreen)
return;
m_fullscreen = !m_fullscreen;
DeInit();
InitWindow(Width(), Height());
Init();
}
bool OpenglContext::IsFullscreen() const
{
return m_fullscreen;
}
void OpenglContext::MakeRelativeToCenter(int& x, int& y) const
{
x = x - (Width() / 2);
y = y - (Height() / 2);
}
void OpenglContext::ShowCursor()
{
m_app.setMouseCursorVisible(true);
}
void OpenglContext::HideCursor()
{
m_app.setMouseCursorVisible(false);
}
void OpenglContext::ShowCrossCursor() const
{
}
void OpenglContext::InitWindow(int width, int height)
{
m_app.create((m_fullscreen ? sf::VideoMode::getFullscreenModes()[0] : sf::VideoMode(width, height, 32)), m_title.c_str(), m_fullscreen ? sf::Style::Fullscreen : (sf::Style::Resize|sf::Style::Close), sf::ContextSettings(32, 8, 0));
}
OpenglContext::MOUSE_BUTTON OpenglContext::ConvertMouseButton(sf::Mouse::Button button) const
{
switch(button)
{
case sf::Mouse::Left:
return MOUSE_BUTTON_LEFT;
case sf::Mouse::Middle:
return MOUSE_BUTTON_MIDDLE;
case sf::Mouse::Right:
return MOUSE_BUTTON_RIGHT;
default:
return MOUSE_BUTTON_NONE;
}
}

262
CPP/perlin.cpp Executable file
View File

@@ -0,0 +1,262 @@
/* coherent noise function over 1, 2 or 3 dimensions */
/* (copyright Ken Perlin) */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../H/perlin.h"
#define B SAMPLE_SIZE
#define BM (SAMPLE_SIZE-1)
#define N 0x1000
#define NP 12 /* 2^N */
#define NM 0xfff
#define s_curve(t) ( t * t * (3.0f - 2.0f * t) )
#define lerp(t, a, b) ( a + t * (b - a) )
#define setup(i,b0,b1,r0,r1)\
t = vec[i] + N;\
b0 = ((int)t) & BM;\
b1 = (b0+1) & BM;\
r0 = t - (int)t;\
r1 = r0 - 1.0f;
float Perlin::noise1(float arg)
{
int bx0, bx1;
float rx0, rx1, sx, t, u, v, vec[1];
vec[0] = arg;
if (mStart)
{
srand(mSeed);
mStart = false;
init();
}
setup(0, bx0,bx1, rx0,rx1);
sx = s_curve(rx0);
u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ];
return lerp(sx, u, v);
}
float Perlin::noise2(float vec[2])
{
int bx0, bx1, by0, by1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
int i, j;
if (mStart)
{
srand(mSeed);
mStart = false;
init();
}
setup(0,bx0,bx1,rx0,rx1);
setup(1,by0,by1,ry0,ry1);
i = p[bx0];
j = p[bx1];
b00 = p[i + by0];
b10 = p[j + by0];
b01 = p[i + by1];
b11 = p[j + by1];
sx = s_curve(rx0);
sy = s_curve(ry0);
#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
q = g2[b00];
u = at2(rx0,ry0);
q = g2[b10];
v = at2(rx1,ry0);
a = lerp(sx, u, v);
q = g2[b01];
u = at2(rx0,ry1);
q = g2[b11];
v = at2(rx1,ry1);
b = lerp(sx, u, v);
return lerp(sy, a, b);
}
float Perlin::noise3(float vec[3])
{
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
int i, j;
if (mStart)
{
srand(mSeed);
mStart = false;
init();
}
setup(0, bx0,bx1, rx0,rx1);
setup(1, by0,by1, ry0,ry1);
setup(2, bz0,bz1, rz0,rz1);
i = p[ bx0 ];
j = p[ bx1 ];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
t = s_curve(rx0);
sy = s_curve(ry0);
sz = s_curve(rz0);
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
a = lerp(t, u, v);
q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
b = lerp(t, u, v);
c = lerp(sy, a, b);
q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
a = lerp(t, u, v);
q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
b = lerp(t, u, v);
d = lerp(sy, a, b);
return lerp(sz, c, d);
}
void Perlin::normalize2(float v[2])
{
float s;
s = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
s = 1.0f/s;
v[0] = v[0] * s;
v[1] = v[1] * s;
}
void Perlin::normalize3(float v[3])
{
float s;
s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
s = 1.0f/s;
v[0] = v[0] * s;
v[1] = v[1] * s;
v[2] = v[2] * s;
}
void Perlin::init(void)
{
int i, j, k;
for (i = 0 ; i < B ; i++)
{
p[i] = i;
g1[i] = (float)((rand() % (B + B)) - B) / B;
for (j = 0 ; j < 2 ; j++)
g2[i][j] = (float)((rand() % (B + B)) - B) / B;
normalize2(g2[i]);
for (j = 0 ; j < 3 ; j++)
g3[i][j] = (float)((rand() % (B + B)) - B) / B;
normalize3(g3[i]);
}
while (--i)
{
k = p[i];
p[i] = p[j = rand() % B];
p[j] = k;
}
for (i = 0 ; i < B + 2 ; i++)
{
p[B + i] = p[i];
g1[B + i] = g1[i];
for (j = 0 ; j < 2 ; j++)
g2[B + i][j] = g2[i][j];
for (j = 0 ; j < 3 ; j++)
g3[B + i][j] = g3[i][j];
}
}
float Perlin::perlin_noise_2D(float vec[2])
{
int terms = mOctaves;
//float freq = mFrequency;
float result = 0.0f;
float amp = mAmplitude;
vec[0]*=mFrequency;
vec[1]*=mFrequency;
for( int i=0; i<terms; i++ )
{
result += noise2(vec)*amp;
vec[0] *= 2.0f;
vec[1] *= 2.0f;
amp*=0.5f;
}
return result;
}
float Perlin::perlin_noise_3D(float vec[3])
{
int terms = mOctaves;
//float freq = mFrequency;
float result = 0.0f;
float amp = mAmplitude;
vec[0]*=mFrequency;
vec[1]*=mFrequency;
vec[2]*=mFrequency;
for( int i=0; i<terms; i++ )
{
result += noise3(vec)*amp;
vec[0] *= 2.0f;
vec[1] *= 2.0f;
vec[2] *= 2.0f;
amp*=0.5f;
}
return result;
}
Perlin::Perlin(int octaves,float freq,float amp,int seed)
{
mOctaves = octaves;
mFrequency = freq;
mAmplitude = amp;
mSeed = seed;
mStart = true;
}

90
CPP/player.cpp Executable file
View File

@@ -0,0 +1,90 @@
#include "../H/player.h"
Player::Player(const Vector3f & position, float rotx, float roty) : m_rotx(rotx), m_roty(roty), m_pos(position){
m_health = 100.f;
std::cout << "Constructor" << std::endl;
}
Vector3f Player::Position(){
return m_pos;
}
void Player::TurnCamera(float x, float y){
x *= 0.01;
y *= 0.01;
if(m_rotx + y >= -70 && m_rotx + y <= 70)
m_rotx += y;
m_roty += x;
}
void Player::SetPosition (Vector3f delta){
m_pos.x = delta.x;
m_pos.y = delta.y;
m_pos.z = delta.z;
}
Vector3f Player::SimulateMove ( bool front , bool back , bool left , bool right , bool run, float elapsedTime ){
Vector3f delta(0, 0, 0);
double speed = 0.1;
if(run)
speed = 0.2;
if (front){
float yrotrad = (m_roty / 180 * 3.141592654f);
delta.x += float(sin(yrotrad)) * speed;
delta.z -= float(cos(yrotrad)) * speed;
}
if (back){
float yrotrad = (m_roty / 180 * 3.141592654f);
delta.x -= float(sin(yrotrad)) * speed;
delta.z += float(cos(yrotrad)) * speed;
}
if (left){
float yrotrad = (m_roty / 180 * 3.141592654f);
delta.x -= float(cos(yrotrad)) * speed;
delta.z -= float(sin(yrotrad)) * speed;
}
if(right){
float yrotrad = (m_roty / 180 * 3.141592654f);
delta.x += float(cos(yrotrad)) * speed;
delta.z += float(sin(yrotrad)) * speed;
}
return delta;
}
float Player::SimulateJump(bool jump, bool& InJump, float& deltay, bool OnGround, float& jumpsize){
if(jump){
if (OnGround)
{
InJump = true;
}
}
if(InJump){
deltay += 0.2;
if (jumpsize > 1.5)
{
InJump = false;
return -1.5;
}
return 0.1;
}
return 0;
}
void Player::ApplyTransformation ( Transformation & transformation ) const{
transformation.ApplyRotation(-m_rotx, 1.f, 0, 0);
transformation.ApplyRotation(-m_roty, 0, 1.f, 0);
transformation.ApplyTranslation(-m_pos);
}
void Player::Damage(Mob& mob){
mob.setHealth(mob.Health() - m_damage);
}
float Player::Health(){
return m_health;
}
void Player::setHealth(float health){
m_health = health;
}

155
CPP/shader.cpp Executable file
View File

@@ -0,0 +1,155 @@
#include "../H/shader.h"
#include "../H/define.h"
#include "../H/tool.h"
#include <iostream>
#include <cassert>
#ifndef WINDOWS
bool Shader::Load(const std::string& vertFile, const std::string& fragFile, bool verbose)
{
std::string fragmentShader;
std::string vertexShader;
if(!Tool::LoadTextFile(vertFile, vertexShader))
{
if(verbose)
std::cout << "Failed to load " << vertFile << std::endl;
return false;
}
if(!Tool::LoadTextFile(fragFile, fragmentShader))
{
if(verbose)
std::cout << "Failed to load " << fragFile << std::endl;
return false;
}
const char * my_fragment_shader_source = fragmentShader.c_str();
const char * my_vertex_shader_source = vertexShader.c_str();
//std::cout << fragmentShader << std::endl;
//std::cout << vertexShader << std::endl;
m_program = glCreateProgram();
CHECK_GL_ERROR();
assert(glIsProgram(m_program));
m_vertexShader = glCreateShader(GL_VERTEX_SHADER_ARB);
CHECK_GL_ERROR();
assert(glIsShader(m_vertexShader));
m_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER_ARB);
CHECK_GL_ERROR();
assert(glIsShader(m_fragmentShader));
// Load Shader Sources
glShaderSource(m_vertexShader, 1, (const GLchar**)&my_vertex_shader_source, NULL);
CHECK_GL_ERROR();
glShaderSource(m_fragmentShader, 1, (const GLchar**)&my_fragment_shader_source, NULL);
CHECK_GL_ERROR();
// Compile The Shaders
if(verbose)
std::cout << "Compiling vertex shader (" << vertFile << ")..." << std::endl;
glCompileShader(m_vertexShader);
if(!CheckShaderError(m_vertexShader, verbose))
return false;
if(verbose)
std::cout << "Compiling fragment shader (" << fragFile << ")..." << std::endl;
glCompileShader(m_fragmentShader);
if(!CheckShaderError(m_fragmentShader, verbose))
return false;
// Attach The Shader Objects To The Program Object
glAttachShader(m_program, m_vertexShader);
CHECK_GL_ERROR();
glAttachShader(m_program, m_fragmentShader);
CHECK_GL_ERROR();
// Link The Program Object
glLinkProgram(m_program);
//if(!CheckProgramError(m_program, verbose))
// return false;
CheckProgramError(m_program, true, verbose);
CHECK_GL_ERROR();
return true;
}
void Shader::Use() const
{
glUseProgram(m_program);
}
GLint Shader::BindIntUniform(const std::string& name) const
{
return glGetUniformLocation(m_program, name.c_str());
}
void Shader::UpdateIntUniform(GLint name, GLint value) const
{
glUniform1i(name, value);
}
void Shader::UpdateFloatUniform(GLint name, GLfloat value) const
{
glUniform1f(name, value);
}
void Shader::Disable()
{
glUseProgram(0);
}
bool Shader::CheckShaderError(GLenum shader, bool verbose)
{
GLint compileOk;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileOk);
if(verbose && !compileOk)
{
int maxLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
char* infoLog = new char[maxLength];
glGetShaderInfoLog(shader, maxLength, &maxLength, infoLog);
std::cout << infoLog << std::endl;
delete [] infoLog;
return false;
}
return compileOk;
}
bool Shader::CheckProgramError(GLenum program, bool showWarning, bool verbose)
{
GLint compileOk;
glGetProgramiv(program, GL_LINK_STATUS, &compileOk);
CHECK_GL_ERROR();
if(verbose && (showWarning || !compileOk))
{
int maxLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
CHECK_GL_ERROR();
char* infoLog = new char[maxLength + 1];
glGetProgramInfoLog(program, maxLength, &maxLength, infoLog);
CHECK_GL_ERROR();
infoLog[maxLength] = 0;
std::cout << infoLog << std::endl;
delete [] infoLog;
}
return compileOk;
}
#endif

51
CPP/sounds.cpp Executable file
View File

@@ -0,0 +1,51 @@
#include "../H/sounds.h"
Sounds::Sounds(){
m_BackgroundMusic.openFromFile("media/music/TheRiseoftheMechbeings.ogg");
m_BackgroundMusic.setLoop(true);
m_BackgroundMusic.play();
}
Sounds::~Sounds(){
m_BackgroundMusic.stop();
}
void Sounds::ManageSounds(Engine* en){
std::cout << "Sounds" << std::endl;
while(en->IsWalking()){
std::cout << "Is walking" << std::endl;
Move(en);
usleep(100);
}
}
sf::SoundBuffer Sounds::SelectSound(sf::SoundBuffer buffer, char& sound){
switch (sound)
{
case 0:
std::cout << "LEFT" << std::endl;
buffer.loadFromFile("media/sounds/Footstep_Tile_Left.wav");
sleep(1);
nextFootStep = 1;
break;
case 1:
std::cout << "RIGHT" << std::endl;
buffer.loadFromFile("media/sounds/Footstep_Tile_Right_2.wav");
sleep(1);
nextFootStep = 0;
break;
default:
break;
}
return buffer;
}
void Sounds::Move(Engine* en){
if (m_sound1.getStatus() != m_sound1.Playing){
m_sound1.setBuffer(SelectSound(m_buffer, nextFootStep));
if(en->m_walk){
if (en->m_run)
m_sound1.setPitch(1.2f);
m_sound1.play();
}
}
}

64
CPP/texture.cpp Executable file
View File

@@ -0,0 +1,64 @@
#include "../H/texture.h"
#include <cassert>
Texture::Texture(const std::string& filename) : m_isValid(false)
{
if(filename != "")
Load(filename);
}
Texture::~Texture()
{
if(IsValid())
glDeleteTextures(1, &m_textureId);
}
bool Texture::Load(const std::string& filename)
{
// Initialize Devil only once:
static bool alreadyInitialized = false;
if(!alreadyInitialized)
{
ilInit();
alreadyInitialized = true;
}
// Use Devil library to load image data in memory
ILuint texid;
ilGenImages(1, &texid);
ilBindImage(texid);
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
ilEnable(IL_ORIGIN_SET);
if (!ilLoadImage((const ILstring)filename.c_str()))
return false;
if (!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))
return false;
// Create mipmapped opengl texture from image data
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
ilDeleteImages(1, &texid);
m_isValid = true;
return true;
}
bool Texture::IsValid() const
{
return m_isValid;
}
void Texture::Bind() const
{
assert(IsValid());
glBindTexture(GL_TEXTURE_2D, m_textureId);
}

198
CPP/textureatlas.cpp Executable file
View File

@@ -0,0 +1,198 @@
#include "../H/textureatlas.h"
#include <cmath>
// TODO
#include <iostream>
#include <sstream>
#include <cassert>
#include "../H/tool.h"
TextureAtlas::TextureAtlas(unsigned int nbTexture) : m_isValid(false), m_currentTextureIndex(0)
{
if(nbTexture < 4)
nbTexture = 4;
// Arrondir sur la puissance de 2 superieure
m_nbTexturePerSide = (int)sqrt((float)nbTexture);
if(m_nbTexturePerSide * m_nbTexturePerSide < nbTexture)
m_nbTexturePerSide++;
while(!IsPowerOfTwo(m_nbTexturePerSide))
m_nbTexturePerSide++;
}
TextureAtlas::~TextureAtlas()
{
if(IsValid())
glDeleteTextures(1, &m_textureId);
}
TextureAtlas::TextureIndex TextureAtlas::AddTexture(const std::string& fname)
{
TextureList::iterator it = m_textureList.find(fname);
if(it != m_textureList.end())
return it->second.texIdx;
TextureIndex id = m_currentTextureIndex++;
m_textureList.insert(std::make_pair(fname, TextureInfo((ILuint)-1, id)));
return id;
}
bool TextureAtlas::Generate(int textureSize, bool mipmap)
{
// TODO mipmap pas encore 100% parfait...
assert(!mipmap);
if(!IsPowerOfTwo(textureSize))
return false;
// Initialize Devil only once:
static bool alreadyInitialized = false;
if(!alreadyInitialized)
{
ilInit();
iluInit();
alreadyInitialized = true;
}
for(TextureList::iterator it = m_textureList.begin(); it != m_textureList.end(); ++it)
{
ILuint texid = it->second.texId;
if(texid == (ILuint)-1)
{
std::cout << "Loading " << it->first << " (id=" << it->second.texIdx << ")..." << std::endl;
ilGenImages(1, &texid);
ilBindImage(texid);
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
ilEnable(IL_ORIGIN_SET);
if (!ilLoadImage((const ILstring)it->first.c_str()))
return false;
if (!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))
return false;
iluScale(textureSize, textureSize, 1);
it->second.texId = texid;
}
}
//std::cout << ilGetInteger(IL_IMAGE_BPP) << std::endl;
//std::cout << ilGetInteger(IL_IMAGE_FORMAT) << std::endl;
//std::cout << ilGetInteger(IL_IMAGE_DEPTH) << std::endl;
//std::cout << ilGetInteger(IL_IMAGE_TYPE) << std::endl;
//std::cout << ilGetInteger(IL_IMAGE_WIDTH) << std::endl;
//std::cout << ilGetInteger(IL_IMAGE_HEIGHT) << std::endl;
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
if(mipmap)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
int level = textureSize;
int oglLevel = 0;
int mipmapSize = textureSize * m_nbTexturePerSide;
while(mipmapSize != 0)
{
ILuint atlasTex;
ilGenImages(1, &atlasTex);
ilBindImage(atlasTex);
ilTexImage(mipmapSize, mipmapSize, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, 0);
ilClearColour(1, 0, 0, 1);
ilClearImage();
for(TextureList::iterator it = m_textureList.begin(); it != m_textureList.end(); ++it)
{
ILuint tmpImg;
ilGenImages(1, &tmpImg);
ilBindImage(tmpImg);
ilCopyImage(it->second.texId);
iluImageParameter(ILU_FILTER, ILU_NEAREST);
//iluImageParameter(ILU_FILTER, ILU_BILINEAR);
if(level != textureSize)
iluScale(level, level, 1);
char* data = new char[level * level * 4];
ilCopyPixels(0, 0, 0, level, level, 1, IL_RGBA, IL_UNSIGNED_BYTE, data);
int imgIdx = it->second.texIdx;
int x = imgIdx % m_nbTexturePerSide;
int y = m_nbTexturePerSide - 1 - imgIdx / m_nbTexturePerSide;
ilBindImage(atlasTex);
ilSetPixels(x * level, y * level, 0, level, level, 1, IL_RGBA, IL_UNSIGNED_BYTE, data);
//ilOverlayImage(tmpImg, x * level, y * level, 0);
delete [] data;
ilDeleteImages(1, &tmpImg);
}
// TODO
//if(level == textureSize)
//{
//ilEnable(IL_FILE_OVERWRITE);
//ilSaveImage("textureatlas.png");
//}
//std::cout << oglLevel << ":" << level << ":" << mipmapSize << std::endl;
glTexImage2D(GL_TEXTURE_2D, oglLevel++, GL_RGBA, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData());
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
CHECK_GL_ERROR();
ilDeleteImages(1, &atlasTex);
if(!mipmap)
break;
level /= 2;
mipmapSize /= 2;
}
m_isValid = true;
return true;
}
bool TextureAtlas::IsValid() const
{
return m_isValid;
}
void TextureAtlas::Bind() const
{
assert(IsValid());
glBindTexture(GL_TEXTURE_2D, m_textureId);
}
void TextureAtlas::TextureIndexToCoord(TextureIndex idx, float& u, float& v, float& w, float& h) const
{
w = 1.f / (float)m_nbTexturePerSide;
h = 1.f / (float)m_nbTexturePerSide;
u = (float)((unsigned int)idx % m_nbTexturePerSide) * w;
v = (float)(m_nbTexturePerSide - 1 - (unsigned int)idx / m_nbTexturePerSide) * h;
}

67
CPP/tool.cpp Executable file
View File

@@ -0,0 +1,67 @@
#include "../H/tool.h"
#include "../H/define.h"
#include <cassert>
#include <iostream>
#include <fstream>
bool Tool::LoadTextFile(const std::string& filename, std::string& buffer)
{
std::ifstream f(filename.c_str(), std::ios::binary);
if(!f.is_open())
return false;
f.seekg(0, std::ios::end);
unsigned int len = f.tellg();
f.seekg(0, std::ios::beg);
char* tmp = new char[len + 1];
f.read(tmp, len);
f.close();
tmp[len] = 0;
buffer = tmp;
delete [] tmp;
return true;
}
void Tool::CheckGLError(const char* file, int line)
{
GLuint err = glGetError();
if (err != GL_NO_ERROR)
{
std::cerr << "Opengl error before " << file << "[" << line << "]:" << std::hex << err << "(";
switch(err)
{
case GL_INVALID_ENUM:
std::cerr << "GL_INVALID_ENUM";
break;
case GL_INVALID_VALUE:
std::cerr << "GL_INVALID_VALUE";
break;
case GL_INVALID_OPERATION:
std::cerr << "GL_INVALID_OPERATION";
break;
case GL_STACK_OVERFLOW:
std::cerr << "GL_STACK_OVERFLOW";
break;
case GL_STACK_UNDERFLOW:
std::cerr << "GL_STACK_UNDERFLOW";
break;
case GL_OUT_OF_MEMORY:
std::cerr << "GL_OUT_OF_MEMORY";
break;
case GL_TABLE_TOO_LARGE:
std::cerr << "GL_TABLE_TOO_LARGE";
break;
default:
std::cerr << "unknown";
}
std::cerr << ")" << std::endl;
std::cerr << "ATTENTION: this error might come from anywhere in the code since the previous call to CHECK_GL_ERROR" << std::endl;
exit(1);
}
}

63
CPP/transformation.cpp Executable file
View File

@@ -0,0 +1,63 @@
#include "../H/transformation.h"
Transformation::Transformation()
{
m_stack.push(Matrix4f::IDENTITY);
}
void Transformation::SetIdentity()
{
m_stack.top().SetIdentity();
}
void Transformation::Push()
{
m_stack.push(m_stack.top());
}
void Transformation::Pop()
{
m_stack.pop();
}
void Transformation::ApplyTranslation(float x, float y, float z)
{
m_stack.top().ApplyTranslation(x, y, z);
}
void Transformation::ApplyTranslation(const Vector3f& v)
{
ApplyTranslation(v.x, v.y, v.z);
}
void Transformation::ApplyRotation(float angle, float x, float y, float z)
{
m_stack.top().ApplyRotation(angle, x, y, z);
}
void Transformation::ApplyRotation(float angle, const Vector3f& v)
{
ApplyRotation(angle, v.x, v.y, v.z);
}
void Transformation::ApplyScale(float x, float y, float z)
{
m_stack.top().ApplyScale(x, y, z);
}
void Transformation::ApplyScale(const Vector3f& v)
{
ApplyScale(v.x, v.y, v.z);
}
void Transformation::Use() const
{
glLoadMatrixf(m_stack.top().GetInternalValues());
}
const Matrix4f& Transformation::GetMatrix() const
{
return m_stack.top();
}

84
CPP/vertexbuffer.cpp Executable file
View File

@@ -0,0 +1,84 @@
#include "../H/vertexbuffer.h"
#include <cassert>
#include <climits>
VertexBuffer::VertexBuffer() : m_isValid(false)
{
}
VertexBuffer::~VertexBuffer()
{
if(m_isValid)
{
glDeleteBuffers(1, &m_vertexVboId);
glDeleteBuffers(1, &m_indexVboId);
}
}
bool VertexBuffer::IsValid() const
{
return m_isValid;
}
void VertexBuffer::SetMeshData(VertexData* vd, int vertexCount)
{
assert(vertexCount <= USHRT_MAX);
if(vertexCount == 0)
return;
if(!m_isValid)
{
glGenBuffers(1, &m_vertexVboId);
glGenBuffers(1, &m_indexVboId);
}
m_vertexCount = vertexCount;
glBindBuffer(GL_ARRAY_BUFFER, m_vertexVboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, vd, GL_STATIC_DRAW);
// Pour le moment, generer le index array pour inclure tout les vertex, sans
// optimisation pour reduire le nombre de vertex envoyes a la carte
// Idealement cet array devrait etre utiliser pour reutiliser les vertex et ainsi
// sauver du temps en envoyant moins de donnees a la carte (il devrait etre construit
// en meme temps que le buffer vd est rempli..)
uint16_t* idx = new uint16_t[vertexCount];
for(int i = 0; i < vertexCount; ++i)
idx[i] = i;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexVboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint16_t) * vertexCount, idx, GL_STATIC_DRAW);
delete [] idx;
m_isValid = true;
}
void VertexBuffer::Render() const
{
if(IsValid())
{
glClientActiveTexture(GL_TEXTURE0);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexVboId);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), (char*)0);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, sizeof(VertexData), (char*)12);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexData), (char*)24);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexVboId);
glDrawElements(GL_QUADS, m_vertexCount, GL_UNSIGNED_SHORT, (char*)0);
// TODO
//glDrawRangeElements(GL_TRIANGLES, 0, 3, 3, GL_UNSIGNED_SHORT, (char*)0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
int VertexBuffer::Count() const
{
return m_vertexCount;
}