Init
This commit is contained in:
57
CPP/blockinfo.cpp
Executable file
57
CPP/blockinfo.cpp
Executable 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
156
CPP/chunk.cpp
Executable 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
732
CPP/engine.cpp
Executable 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
17
CPP/main.cpp
Executable 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
133
CPP/mob.cpp
Executable 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
172
CPP/openglcontext.cpp
Executable 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
262
CPP/perlin.cpp
Executable 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
90
CPP/player.cpp
Executable 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
155
CPP/shader.cpp
Executable 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
51
CPP/sounds.cpp
Executable 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
64
CPP/texture.cpp
Executable 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
198
CPP/textureatlas.cpp
Executable 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
67
CPP/tool.cpp
Executable 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
63
CPP/transformation.cpp
Executable 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
84
CPP/vertexbuffer.cpp
Executable 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user