Sloth loves Chunk!

This commit is contained in:
Marc-Eric Martel 2021-10-11 11:37:58 -04:00
parent 2347a3f7e4
commit 6f3dd99ab7
27 changed files with 19795 additions and 194 deletions

View File

@ -19,7 +19,8 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="blockarray3d.h" />
<ClInclude Include="array2d.h" />
<ClInclude Include="array3d.h" />
<ClInclude Include="blockinfo.h" />
<ClInclude Include="chunk.h" />
<ClInclude Include="define.h" />
@ -27,20 +28,25 @@
<ClInclude Include="matrix4.h" />
<ClInclude Include="openglcontext.h" />
<ClInclude Include="player.h" />
<ClInclude Include="shader.h" />
<ClInclude Include="texture.h" />
<ClInclude Include="tool.h" />
<ClInclude Include="transformation.h" />
<ClInclude Include="vector3.h" />
<ClInclude Include="vertexbuffer.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="blockarray3d.cpp" />
<ClCompile Include="blockinfo.cpp" />
<ClCompile Include="chunk.cpp" />
<ClCompile Include="engine.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="openglcontext.cpp" />
<ClCompile Include="player.cpp" />
<ClCompile Include="shader.cpp" />
<ClCompile Include="texture.cpp" />
<ClCompile Include="tool.cpp" />
<ClCompile Include="transformation.cpp" />
<ClCompile Include="vertexbuffer.cpp" />
</ItemGroup>
<ItemGroup>
<Text Include="notes.txt" />
@ -97,8 +103,8 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>external\devil178\include;external\sfml23\include;$(IncludePath)</IncludePath>
<LibraryPath>external\devil178\lib;external\sfml23\lib;$(LibraryPath)</LibraryPath>
<IncludePath>external\glew170\include;external\devil178\include;external\sfml23\include;$(IncludePath)</IncludePath>
<LibraryPath>external\glew170\lib;external\devil178\lib;external\sfml23\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
@ -126,7 +132,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>sfml-main-d.lib;sfml-system-d.lib;sfml-window-d.lib;sfml-graphics-d.lib;GlU32.Lib;OpenGL32.Lib;DevIL.lib;ILU.lib;ILUT.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>sfml-main-d.lib;sfml-system-d.lib;sfml-window-d.lib;sfml-graphics-d.lib;GlU32.Lib;OpenGL32.Lib;DevIL.lib;ILU.lib;ILUT.lib;glew32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

View File

@ -11,7 +11,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="blockarray3d.h">
<ClInclude Include="array3d.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="blockinfo.h">
@ -44,11 +44,20 @@
<ClInclude Include="player.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="shader.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="tool.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="vertexbuffer.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="array2d.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="blockarray3d.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="blockinfo.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
@ -73,6 +82,15 @@
<ClCompile Include="player.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="shader.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="tool.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="vertexbuffer.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="notes.txt" />

65
SQCSim2021/array2d.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef ARRAY2D_H__
#define ARRAY2D_H__
#include "define.h"
template <class T>
class Array2d
{
public:
Array2d(int x, int y);
~Array2d();
Array2d(const Array2d& array);
void Set(int x, int y, T type);
T Get(int x, int y) const;
void Reset(T type);
private:
int To1dIndex(int x, int y) const;
private:
int m_x, m_y;
T* m_array;
};
template <class T>
Array2d<T>::Array2d(int x, int y) : m_x(x), m_y(y) {
m_array = new T[m_x * m_y];
Reset(BTYPE_AIR);
}
template <class T>
Array2d<T>::~Array2d() { delete[] m_array; }
template <class T>
Array2d<T>::Array2d(const Array2d<T>& array) : m_x(array.m_x), m_y(array.m_y) {
m_array = new BlockType[m_x * m_y];
for (int i = 0; i < m_x * m_y; ++i)
m_array[i] = array.m_array[i];
}
template <class T>
void Array2d<T>::Set(int x, int y, T type) {
m_array[To1dIndex(x, y)] = type;
}
template <class T>
T Array2d<T>::Get(int x, int y) const {
return m_array[To1dIndex(x, y)];
}
template <class T>
void Array2d<T>::Reset(T type) {
for (int i = 0; i < m_x * m_y; ++i)
m_array[i] = type;
}
template <class T>
int Array2d<T>::To1dIndex(int x, int y) const {
return x + (y * m_x);
}
#endif // ARRAY2D_H__

66
SQCSim2021/array3d.h Normal file
View File

@ -0,0 +1,66 @@
#ifndef ARRAY3D_H__
#define ARRAY3D_H__
#include "define.h"
template <class T>
class Array3d
{
public:
Array3d(int x, int y, int z);
~Array3d();
Array3d(const Array3d& array);
void Set(int x, int y, int z, T type);
T Get(int x, int y, int z) const;
void Reset(T type);
private:
int To1dIndex(int x, int y, int z) const;
private:
int m_x, m_y, m_z;
T* m_array;
};
template <class T>
Array3d<T>::Array3d(int x, int y, int z) : m_x(x), m_y(y), m_z(z) {
m_array = new T[m_x * m_y * m_z];
Reset(BTYPE_AIR);
}
template <class T>
Array3d<T>::~Array3d() { delete[] m_array; }
template <class T>
Array3d<T>::Array3d(const Array3d<T>& array) : m_x(array.m_x), m_y(array.m_y), m_z(array.m_z) {
m_array = new BlockType[m_x * m_y * m_z];
for (int i = 0; i < m_x * m_y * m_z; ++i)
m_array[i] = array.m_array[i];
}
template <class T>
void Array3d<T>::Set(int x, int y, int z, T type) {
m_array[To1dIndex(x, y, z)] = type;
}
template <class T>
T Array3d<T>::Get(int x, int y, int z) const {
return m_array[To1dIndex(x, y, z)];
}
template <class T>
void Array3d<T>::Reset(T type) {
for (int i = 0; i < m_x * m_y * m_z; ++i)
m_array[i] = type;
}
template <class T>
int Array3d<T>::To1dIndex(int x, int y, int z) const {
return x + (z * m_x) + (y * m_z * m_x);
}
#endif // ARRAY3D_H__

View File

@ -1,41 +0,0 @@
#include "blockarray3d.h"
BlockArray3d::BlockArray3d(int x, int y, int z) : m_x(x), m_y(y), m_z(z)
{
m_blocks = new BlockType[m_x * m_y * m_z];
Reset(BTYPE_AIR);
}
BlockArray3d::~BlockArray3d()
{
delete [] m_blocks;
}
BlockArray3d::BlockArray3d(const BlockArray3d& array) : m_x(array.m_x), m_y(array.m_y), m_z(array.m_z)
{
m_blocks = new BlockType[m_x * m_y * m_z];
for(int i = 0; i < m_x * m_y * m_z; ++i)
m_blocks[i] = array.m_blocks[i];
}
void BlockArray3d::Set(int x, int y, int z, BlockType type)
{
m_blocks[To1dIndex(x, y, z)] = type;
}
BlockType BlockArray3d::Get(int x, int y, int z) const
{
return m_blocks[To1dIndex(x, y, z)];
}
void BlockArray3d::Reset(BlockType type)
{
for(int i = 0; i < m_x * m_y * m_z; ++i)
m_blocks[i] = type;
}
int BlockArray3d::To1dIndex(int x, int y, int z) const
{
return x + (z * m_x) + (y * m_z * m_x);
}

View File

@ -1,26 +0,0 @@
#ifndef BLOCKARRAY3D_H__
#define BLOCKARRAY3D_H__
#include "define.h"
class BlockArray3d
{
public:
BlockArray3d(int x, int y, int z);
~BlockArray3d();
BlockArray3d(const BlockArray3d& array);
void Set(int x, int y, int z, BlockType type);
BlockType Get(int x, int y, int z) const;
void Reset(BlockType type);
private:
int To1dIndex(int x, int y, int z) const;
private:
int m_x, m_y, m_z;
BlockType* m_blocks;
};
#endif // BLOCKARRAY3D_H__

View File

@ -1,25 +1,83 @@
#include "chunk.h"
Chunk::Chunk() : BlockArray3d(CHUNK_SIZE_X, CHUNK_SIZE_Y, CHUNK_SIZE_Z)
{
Chunk::Chunk() {}
Chunk::~Chunk() {}
void Chunk::RemoveBlock(int x, int y, int z) {
m_blocks.Set(x, y, z, BTYPE_AIR);
m_isDirty = true;
}
Chunk::~Chunk()
{
void Chunk::SetBlock(int x, int y, int z, BlockType type) {
m_blocks.Set(x, y, z, type);
m_isDirty = true;
}
void Chunk::RemoveBlock(int x, int y, int z)
{
Set(x, y, z, BTYPE_AIR);
BlockType Chunk::GetBlock(int x, int y, int z) { return m_blocks.Get(x, y, z); }
void Chunk::Update() {
// 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);
}
}
}
}
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::SetBlock(int x, int y, int z, BlockType type)
{
Set(x, y, z, type);
void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z) {
vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 0.f, 0.f);
vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 0.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, 1.f, 1.f);
vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, 1.f, 0.f);
}
BlockType Chunk::GetBlock(int x, int y, int z)
{
return Get(x, y, z);
}
void Chunk::Render() const { m_vertexBuffer.Render(); }
bool Chunk::IsDirty() const { return m_isDirty; }

View File

@ -1,16 +1,29 @@
#ifndef CHUNK_H__
#define CHUNK_H__
#include "blockarray3d.h"
#include "define.h"
#include "array3d.h"
#include "vertexbuffer.h"
class Chunk {
private:
Array3d<BlockType> m_blocks = Array3d<BlockType>(CHUNK_SIZE_X, CHUNK_SIZE_Y, CHUNK_SIZE_Z);
VertexBuffer m_vertexBuffer;
bool m_isDirty = true;
void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z);
class Chunk : public BlockArray3d
{
public:
Chunk();
~Chunk();
Chunk();
~Chunk();
void RemoveBlock(int x, int y, int z);
void SetBlock(int x, int y, int z, BlockType type);
BlockType GetBlock(int x, int y, int z);
void RemoveBlock(int x, int y, int z);
void SetBlock(int x, int y, int z, BlockType type);
BlockType GetBlock(int x, int y, int z);
void Update();
void Render() const;
bool IsDirty() const;
};
#endif // CHUNK_H__

View File

@ -3,23 +3,25 @@
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#include <GL/glew.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#else
#include <GL/glew.h>
#endif
#define CHUNK_SIZE_X 16
#define CHUNK_SIZE_Y 128
#define CHUNK_SIZE_Z 16
enum BlockType {BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS};
typedef uint8_t BlockType;
enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS };
#define TEXTURE_PATH "../SQCSim2021/media/textures/"
#define SHADER_PATH "../SQCSim2021/media/shaders/"
#define VIEW_DISTANCE 128
#endif // DEFINE_H__

View File

@ -1,7 +1,6 @@
#include "engine.h"
#include <algorithm>
#include <cmath>
#include <iostream>
#include "transformation.h"
#include "player.h"
@ -11,6 +10,13 @@ Engine::~Engine() { }
void Engine::Init()
{
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);
@ -24,9 +30,6 @@ void Engine::Init()
glEnable(GL_LINE_SMOOTH);
glEnable(GL_CULL_FACE);
// Cull!
glCullFace(GL_BACK);
// Light
GLfloat light0Pos[4] = { 0.0f, CHUNK_SIZE_Y, 0.0f, 1.0f };
GLfloat light0Amb[4] = { 0.9f, 0.9f, 0.9f, 1.f };
@ -50,6 +53,16 @@ void Engine::Init()
// Blend
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Init testChunk
for (int x = 0; x < CHUNK_SIZE_X; ++x) {
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
for (int y = 0; y < 32; ++y) {
if (x % 2 == 0 && y % 2 == 0 && z % 2 == 0)
m_testChunk.SetBlock(x, y, z, BTYPE_DIRT);
}
}
}
CenterMouse();
HideCursor();
}
@ -63,6 +76,13 @@ void Engine::LoadResource() {
LoadTexture(m_textureCube2, TEXTURE_PATH "metal2.png");
LoadTexture(m_textureCube3, TEXTURE_PATH "metal3.png");
LoadTexture(m_textureCube4, TEXTURE_PATH "metal4.png");
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);
}
}
void Engine::UnloadResource()
@ -173,97 +193,28 @@ void Engine::Render(float elapsedTime)
glVertex3f(-100.f, -2.f, -100.f);
glEnd();
// Cube
all.ApplyTranslation(0.f, 0.f, -10.f);
all.ApplyRotation(gameTime * 100.f, 0.f, 1.f, 0.f);
all.ApplyRotation(gameTime * 100.f, 0.f, 0.f, 1.f);
all.ApplyRotation(gameTime * 100.f, 1.f, 0.f, 0.f);
all.Use();
switch ((int)(gameTime*5) % 4) {
case 0:
m_textureCube1.Bind();
// Chunk
switch ((int)(gameTime * 5) % 4) {
case 0: m_textureCube1.Bind();
break;
case 1:
m_textureCube2.Bind();
case 1: m_textureCube2.Bind();
break;
case 2:
m_textureCube3.Bind();
case 2: m_textureCube3.Bind();
break;
case 3:
m_textureCube4.Bind();
case 3: m_textureCube4.Bind();
break;
}
glEnable(GL_BLEND);
glBegin(GL_QUADS);
if (m_testChunk.IsDirty())
m_testChunk.Update();
m_shader01.Use();
m_testChunk.Render();
Shader::Disable();
glNormal3f(0, 0, 1);
glTexCoord2f(0, 1);
glVertex3f(0.5f, 0.5f, 0.5f);
glTexCoord2f(1, 1);
glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(1, 0);
glVertex3f(-0.5f, -0.5f, 0.5f);
glTexCoord2f(0, 0);
glVertex3f(0.5f, -0.5f, 0.5f);
glNormal3f(0, 0, -1);
glTexCoord2f(1, 0);
glVertex3f(0.5f, -0.5f, -0.5f);
glTexCoord2f(0, 0);
glVertex3f(-0.5f, -0.5f, -0.5f);
glTexCoord2f(0, 1);
glVertex3f(-0.5f, 0.5f, -0.5f);
glTexCoord2f(1, 1);
glVertex3f(0.5f, 0.5f, -0.5f);
glNormal3f(-1, 0, 0);
glTexCoord2f(0, 1);
glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(1, 1);
glVertex3f(-0.5f, 0.5f, -0.5f);
glTexCoord2f(1, 0);
glVertex3f(-0.5f, -0.5f, -0.5f);
glTexCoord2f(0, 0);
glVertex3f(-0.5f, -0.5f, 0.5f);
glNormal3f(1, 0, 0);
glTexCoord2f(0, 1);
glVertex3f(0.5f, 0.5f, -0.5f);
glTexCoord2f(1, 1);
glVertex3f(0.5f, 0.5f, 0.5f);
glTexCoord2f(1, 0);
glVertex3f(0.5f, -0.5f, 0.5f);
glTexCoord2f(0, 0);
glVertex3f(0.5f, -0.5f, -0.5f);
glNormal3f(0, 1, 0);
glTexCoord2f(0, 0);
glVertex3f(-0.5f, 0.5f, -0.5f);
glTexCoord2f(0, 1);
glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(1, 1);
glVertex3f(0.5f, 0.5f, 0.5f);
glTexCoord2f(1, 0);
glVertex3f(0.5f, 0.5f, -0.5f);
glNormal3f(0, -1, 0);
glTexCoord2f(0, 0);
glVertex3f(-0.5f, -0.5f, 0.5f);
glTexCoord2f(0, 1);
glVertex3f(-0.5f, -0.5f, -0.5f);
glTexCoord2f(1, 1);
glVertex3f(0.5f, -0.5f, -0.5f);
glTexCoord2f(1, 0);
glVertex3f(0.5f, -0.5f, 0.5f);
glDisable(GL_BLEND);
glEnd();
}
void Engine::KeyPressEvent(unsigned char key)
{
switch (key)
{
switch (key) {
case 36: // ESC
Stop();
break;
@ -316,8 +267,7 @@ void Engine::KeyPressEvent(unsigned char key)
void Engine::KeyReleaseEvent(unsigned char key)
{
switch (key)
{
switch (key) {
case 24: // Y
m_wireframe = !m_wireframe;
if (m_wireframe)

View File

@ -4,7 +4,9 @@
#include "openglcontext.h"
#include "texture.h"
#include "transformation.h"
#include "shader.h""
#include "player.h"
#include "chunk.h"
class Engine : public OpenglContext
{
@ -35,6 +37,8 @@ private:
Texture m_textureCube3;
Texture m_textureCube4;
Shader m_shader01;
Chunk m_testChunk;
Player m_player = Player(Vector3f(0, 0, 0));
bool m_keyW = false;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,12 @@
uniform sampler2D tex;
varying vec4 light;
void main()
{
vec4 texel;
texel = texture2D(tex,gl_TexCoord[0].st);
texel *= light;
gl_FragColor = texel;
}

View File

@ -0,0 +1,8 @@
varying vec4 light;
void main()
{
light = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View File

@ -1,5 +0,0 @@
Keycodes:
W 22
A 0
S 18
D 3

155
SQCSim2021/shader.cpp Normal file
View File

@ -0,0 +1,155 @@
#include "shader.h"
#include "define.h"
#include "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

30
SQCSim2021/shader.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef SHADER_H__
#define SHADER_H__
#include <string>
#include "define.h"
class Shader
{
public:
bool Load(const std::string& vertFile, const std::string& fragFile, bool verbose = false);
void Use() const;
GLint BindIntUniform(const std::string& name) const;
void UpdateIntUniform(GLint name, GLint value) const;
void UpdateFloatUniform(GLint name, GLfloat value) const;
static void Disable();
private:
GLenum m_program;
GLenum m_vertexShader;
GLenum m_fragmentShader;
private:
bool CheckShaderError(GLenum shader, bool verbose);
bool CheckProgramError(GLenum program, bool showWarning, bool verbose);
};
#endif // SHADER_H__

67
SQCSim2021/tool.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "tool.h"
#include "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);
}
}

25
SQCSim2021/tool.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef TOOL_H__
#define TOOL_H__
#include <string>
// TODO ne pas oublier de ne pas definir DEBUGMODE en release
#ifndef DEBUGMODE
#define DEBUGMODE
#endif
#ifdef DEBUGMODE
# define CHECK_GL_ERROR() Tool::CheckGLError(__FILE__, __LINE__);
#else
# define CHECK_GL_ERROR()
#endif
class Tool
{
public:
static bool LoadTextFile(const std::string& filename, std::string& buffer);
static void CheckGLError(const char* file, int line);
};
#endif // TOOL_H__

View File

@ -0,0 +1,76 @@
#include "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;
}

42
SQCSim2021/vertexbuffer.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef VERTEXBUFFER_H__
#define VERTEXBUFFER_H__
#include "define.h"
class VertexBuffer
{
public:
// Structure représentant toutes les informations de chacuns des vertex
// S'assurer que le size de cette struct reste un multiple de 32
// octet pour un maximum de performance
// Au besoin, ajouter du padding
struct VertexData
{
float x, y, z;
float r, g, b;
float u, v;
VertexData() {}
VertexData(float x, float y, float z, float r, float g, float b, float u, float v) : x(x), y(y), z(z), r(r), g(g), b(b), u(u), v(v) {}
};
public:
VertexBuffer();
~VertexBuffer();
bool IsValid() const;
void SetMeshData(VertexData* vd, int vertexCount);
void Render() const;
int Count() const;
private:
bool m_isValid;
int m_vertexCount;
GLuint m_vertexVboId;
GLuint m_indexVboId;
};
#endif // VERTEXBUFFER_H__