multiple textures

main
Brett 2023-03-05 00:01:54 -05:00
parent e34d016abb
commit 4417359ebf
14 changed files with 98 additions and 49 deletions

View File

@ -90,3 +90,21 @@
2049 2123 1677989296260178714 libraries/BLT/libBLT.a b8f809e0bb7338ed 2049 2123 1677989296260178714 libraries/BLT/libBLT.a b8f809e0bb7338ed
2 3804 1677989302996363361 CMakeFiles/FinalProject.dir/src/render/textures.cpp.o 245d855e300d9590 2 3804 1677989302996363361 CMakeFiles/FinalProject.dir/src/render/textures.cpp.o 245d855e300d9590
3804 3953 1677989303148367528 FinalProject 743e0d59f44b5ac0 3804 3953 1677989303148367528 FinalProject 743e0d59f44b5ac0
3 818 1677991204992770044 CMakeFiles/FinalProject.dir/src/world/chunk/storage.cpp.o aba7285d6d94217e
2 1042 1677991205212776091 CMakeFiles/FinalProject.dir/src/main.cpp.o 1ae001c7e5feebcb
3 1256 1677991205428782026 CMakeFiles/FinalProject.dir/src/world/registry.cpp.o d042df377c55f1ff
3 1256 1677991205428782026 CMakeFiles/FinalProject.dir/src/world/chunk/world.cpp.o 7a550f9a4e0bfc9c
3 3841 1677991208008852927 CMakeFiles/FinalProject.dir/src/render/textures.cpp.o 245d855e300d9590
3841 3990 1677991208160857104 FinalProject 743e0d59f44b5ac0
2 1188 1677992111365563290 CMakeFiles/FinalProject.dir/src/world/chunk/storage.cpp.o aba7285d6d94217e
2 1308 1677992111485566327 CMakeFiles/FinalProject.dir/src/main.cpp.o 1ae001c7e5feebcb
2 1369 1677992111549567947 CMakeFiles/FinalProject.dir/src/world/registry.cpp.o d042df377c55f1ff
2 1477 1677992111653570579 CMakeFiles/FinalProject.dir/src/world/chunk/world.cpp.o 7a550f9a4e0bfc9c
1477 1614 1677992111793574121 FinalProject 743e0d59f44b5ac0
2 813 1677992416661428935 CMakeFiles/FinalProject.dir/src/world/chunk/storage.cpp.o aba7285d6d94217e
2 1062 1677992416909435417 CMakeFiles/FinalProject.dir/src/main.cpp.o 1ae001c7e5feebcb
2 1087 1677992416937436149 CMakeFiles/FinalProject.dir/src/world/chunk/world.cpp.o 7a550f9a4e0bfc9c
2 1137 1677992416985437403 CMakeFiles/FinalProject.dir/src/world/registry.cpp.o d042df377c55f1ff
1137 1282 1677992417129441168 FinalProject 743e0d59f44b5ac0
2 1062 1677992483647184263 CMakeFiles/FinalProject.dir/src/main.cpp.o 1ae001c7e5feebcb
1062 1210 1677992483791188045 FinalProject 743e0d59f44b5ac0

View File

@ -1,3 +1,3 @@
Start testing: Mar 04 23:09 EST Start testing: Mar 05 00:01 EST
---------------------------------------------------------- ----------------------------------------------------------
End testing: Mar 04 23:09 EST End testing: Mar 05 00:01 EST

View File

@ -7,6 +7,7 @@ precision mediump float;
out vec4 FragColor; out vec4 FragColor;
in vec2 uv; in vec2 uv;
in float index;
uniform mediump sampler2DArray texturep_palette; uniform mediump sampler2DArray texturep_palette;
@ -15,7 +16,7 @@ void main() {
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
else else
discard;*/ discard;*/
FragColor = texture(texturep_palette, vec3(uv, 0.0f)); FragColor = texture(texturep_palette, vec3(uv, index));
} }
")"; ")";

View File

@ -6,8 +6,10 @@ precision mediump float;
layout (location = 0) in vec3 vertex; layout (location = 0) in vec3 vertex;
layout (location = 1) in vec2 texture_coord; layout (location = 1) in vec2 texture_coord;
layout (location = 2) in float texture_index;
out vec2 uv; out vec2 uv;
out float index;
uniform mat4 translation; uniform mat4 translation;
@ -22,6 +24,7 @@ layout (std140) uniform StandardMatrices
}; };
void main() { void main() {
index = texture_index;
gl_Position = projection * view * translation * vec4(vertex.x, vertex.y, vertex.z, 1.0); gl_Position = projection * view * translation * vec4(vertex.x, vertex.y, vertex.z, 1.0);
uv = texture_coord; uv = texture_coord;
} }

View File

@ -62,7 +62,7 @@ namespace fp {
* @param face the direction the face is facing to be added to the mesh. * @param face the direction the face is facing to be added to the mesh.
* @param pos position of the face * @param pos position of the face
*/ */
void addFace(face face, const block_pos& pos); void addFace(face face, const block_pos& pos, unsigned char texture_index);
inline std::vector<vertex>& getVertices() { inline std::vector<vertex>& getVertices() {
return vertices; return vertices;

View File

@ -60,6 +60,7 @@ namespace fp {
typedef struct { typedef struct {
float x, y, z; float x, y, z;
float u, v; float u, v;
float index;
} vertex; } vertex;
namespace _static { namespace _static {
@ -96,7 +97,7 @@ namespace fp {
struct vertex_equality { struct vertex_equality {
inline bool operator()(const vertex& p1, const vertex& p2) const { inline bool operator()(const vertex& p1, const vertex& p2) const {
return f_equal(p1.x, p2.x) && f_equal(p1.y, p2.y) && f_equal(p1.z, p2.z) && return f_equal(p1.x, p2.x) && f_equal(p1.y, p2.y) && f_equal(p1.z, p2.z) &&
f_equal(p1.u, p2.u) && f_equal(p1.v, p2.v); f_equal(p1.u, p2.u) && f_equal(p1.v, p2.v) && p1.index == p2.index;
} }
}; };

View File

@ -86,9 +86,10 @@ namespace fp {
// since they both use the same amount of memory we will only store the vertices and draw with drawArrays, since it is less complex. // since they both use the same amount of memory we will only store the vertices and draw with drawArrays, since it is less complex.
// set up the VBOs which will be later updated when the mesh is generated. // set up the VBOs which will be later updated when the mesh is generated.
auto vbo = new VBO(ARRAY_BUFFER, nullptr, 0); auto vbo = new VBO(ARRAY_BUFFER, nullptr, 0);
auto data_size = 3 * sizeof(float) + 2 * sizeof(float); auto data_size = 3 * sizeof(float) + 2 * sizeof(float) + 1 * sizeof(float);
chunk_vao->bindVBO(vbo, 0, 3, GL_FLOAT, (int)data_size, 0); chunk_vao->bindVBO(vbo, 0, 3, GL_FLOAT, (int)data_size, 0);
chunk_vao->bindVBO(vbo, 1, 2, GL_FLOAT, (int)data_size, 3 * sizeof(float), true); chunk_vao->bindVBO(vbo, 1, 2, GL_FLOAT, (int)data_size, 3 * sizeof(float), true);
chunk_vao->bindVBO(vbo, 2, 1, GL_FLOAT, (int)data_size, 3 * sizeof(float) + 2 * sizeof(float), true);
chunk_vao->bindElementVBO(new VBO(ELEMENT_BUFFER, nullptr, 0)); chunk_vao->bindElementVBO(new VBO(ELEMENT_BUFFER, nullptr, 0));
} }

View File

@ -34,15 +34,17 @@ namespace fp::registry {
struct block_properties { struct block_properties {
// how should we handle this block? Blocks with transparent textures can be added to OPAQUE blocks // how should we handle this block? Blocks with transparent textures can be added to OPAQUE blocks
block_visibility visibility = OPAQUE; block_visibility visibility = OPAQUE;
// does this block produce light?
bool produces_light = false;
// WebGL doesn't default to empty textures, use index 0 to store an empty texture // WebGL doesn't default to empty textures, use index 0 to store an empty texture
std::string textureName = "Air"; std::string textureName = "Air";
// does this block produce light?
bool produces_light = false;
}; };
constexpr block_type AIR = 0; constexpr block_type AIR = 0;
constexpr block_type STONE = 1; constexpr block_type STONE = 1;
constexpr block_type DIRT = 2;
constexpr block_type COBBLE = 3;
constexpr block_type GRASS = 4;
void registerBlock(block_type id, block_properties properties); void registerBlock(block_type id, block_properties properties);
void registerTexture(texture::file_texture* texture); void registerTexture(texture::file_texture* texture);
@ -52,7 +54,7 @@ namespace fp::registry {
void generateTexturePalette(); void generateTexturePalette();
void cleanup(); void cleanup();
block_properties get(block_type id); block_properties& get(block_type id);
unsigned int getTextureID(); unsigned int getTextureID();
texture::texture_index getTextureIndex(const std::string& name); texture::texture_index getTextureIndex(const std::string& name);
@ -62,7 +64,9 @@ namespace fp::registry {
*/ */
inline void registerDefaultBlocks(){ inline void registerDefaultBlocks(){
registerBlock(AIR, {TRANSPARENT}); registerBlock(AIR, {TRANSPARENT});
registerBlock(STONE, {}); registerBlock(STONE, {OPAQUE, "Stone"});
registerBlock(DIRT, {OPAQUE, "Dolph"});
registerBlock(COBBLE, {OPAQUE, "Sit"});
} }
inline void registerDefaultTextures() { inline void registerDefaultTextures() {

View File

@ -61,12 +61,23 @@ int main() {
for (int i = 1; i < CHUNK_SIZE; i++) for (int i = 1; i < CHUNK_SIZE; i++)
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)
for (int k = 5; k < CHUNK_SIZE; k++) for (int k = 5; k < CHUNK_SIZE; k++)
world->setBlock({i,j,k}, 1); world->setBlock({i,j,k}, fp::registry::STONE);
for (int i = 1; i < CHUNK_SIZE; i++)
for (int j = 10; j < 15; j++)
for (int k = 5; k < CHUNK_SIZE; k++)
world->setBlock({i,j,k}, fp::registry::DIRT);
for (int i = 1; i < CHUNK_SIZE; i++)
for (int j = 24; j < 26; j++)
for (int k = 5; k < CHUNK_SIZE; k++)
world->setBlock({i,j,k}, fp::registry::COBBLE);
world->setBlock({-2, 2, 2}, 1); world->setBlock({-2, 2, 2}, 1);
world->setBlock({-2, 2, -2}, 1); world->setBlock({-2, 2, -2}, 1);
world->setBlock({2, 2, -2}, 1); world->setBlock({2, 2, -2}, 1);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK); glCullFace(GL_BACK);
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__

View File

@ -9,40 +9,46 @@
constexpr float scale = 0.5f; constexpr float scale = 0.5f;
const fp::vertex x_positive_vertices[VTX_ARR_SIZE] = { const fp::vertex x_positive_vertices[VTX_ARR_SIZE] = {
{scale, scale, scale, 1, 1}, // +x top right // x, y, z, u, v, index
{scale, scale, -scale, 1, 0}, // +x bottom right {scale, scale, scale, 1, 1, 0}, // +x top right
{scale, -scale, -scale, 0, 0}, // +x bottom left {scale, scale, -scale, 1, 0, 0}, // +x bottom right
{scale, -scale, scale, 0, 1} // +x top left {scale, -scale, -scale, 0, 0, 0}, // +x bottom left
{scale, -scale, scale, 0, 1, 0} // +x top left
}; };
const fp::vertex x_negative_vertices[VTX_ARR_SIZE] = { const fp::vertex x_negative_vertices[VTX_ARR_SIZE] = {
{-scale, scale, scale, 1, 1}, // -x top right // x, y, z, u, v, index
{-scale, scale, -scale, 1, 0}, // -x bottom right {-scale, scale, scale, 1, 1, 0}, // -x top right
{-scale, -scale, -scale, 0, 0}, // -x bottom left {-scale, scale, -scale, 1, 0, 0}, // -x bottom right
{-scale, -scale, scale, 0, 1} // -x top left {-scale, -scale, -scale, 0, 0, 0}, // -x bottom left
{-scale, -scale, scale, 0, 1, 0} // -x top left
}; };
const fp::vertex y_positive_vertices[VTX_ARR_SIZE] = { const fp::vertex y_positive_vertices[VTX_ARR_SIZE] = {
{scale, scale, scale, 1, 1}, // +y top right // x, y, z, u, v, index
{-scale, scale, scale, 1, 0}, // +y bottom right {scale, scale, scale, 1, 1, 0}, // +y top right
{-scale, scale, -scale, 0, 0}, // +y bottom left {-scale, scale, scale, 1, 0, 0}, // +y bottom right
{scale, scale, -scale, 0, 1}, // +y top left {-scale, scale, -scale, 0, 0, 0}, // +y bottom left
{scale, scale, -scale, 0, 1, 0}, // +y top left
}; };
const fp::vertex y_negative_vertices[VTX_ARR_SIZE] = { const fp::vertex y_negative_vertices[VTX_ARR_SIZE] = {
{scale, -scale, scale, 1, 1}, // -y top right // x, y, z, u, v, index
{-scale, -scale, scale, 1, 0}, // -y bottom right {scale, -scale, scale, 1, 1, 0}, // -y top right
{-scale, -scale, -scale, 0, 0}, // -y bottom left {-scale, -scale, scale, 1, 0, 0}, // -y bottom right
{scale, -scale, -scale, 0, 1}, // -y top left {-scale, -scale, -scale, 0, 0, 0}, // -y bottom left
{scale, -scale, -scale, 0, 1, 0}, // -y top left
}; };
const fp::vertex z_positive_vertices[VTX_ARR_SIZE] = { const fp::vertex z_positive_vertices[VTX_ARR_SIZE] = {
{scale, scale, scale, 1, 1}, // +z top right // x, y, z, u, v, index
{scale, -scale, scale, 1, 0}, // +z bottom right {scale, scale, scale, 1, 1, 0}, // +z top right
{-scale, -scale, scale, 0, 0}, // +z bottom left {scale, -scale, scale, 1, 0, 0}, // +z bottom right
{-scale, scale, scale, 0, 1}, // +z top left {-scale, -scale, scale, 0, 0, 0}, // +z bottom left
{-scale, scale, scale, 0, 1, 0}, // +z top left
}; };
const fp::vertex z_negative_vertices[VTX_ARR_SIZE] = { const fp::vertex z_negative_vertices[VTX_ARR_SIZE] = {
{scale, scale, -scale, 1, 1}, // -z top right // x, y, z, u, v, index
{scale, -scale, -scale, 1, 0}, // -z bottom right {scale, scale, -scale, 1, 1, 0}, // -z top right
{-scale, -scale, -scale, 0, 0}, // -z bottom left {scale, -scale, -scale, 1, 0, 0}, // -z bottom right
{-scale, scale, -scale, 0, 1}, // -z top left {-scale, -scale, -scale, 0, 0, 0}, // -z bottom left
{-scale, scale, -scale, 0, 1, 0}, // -z top left
}; };
// indices are the same on all axis but are flipped between negative / positive as a result of back-face culling. // indices are the same on all axis but are flipped between negative / positive as a result of back-face culling.
@ -65,7 +71,7 @@ const fp::vertex* face_decode[] = {
z_negative_vertices z_negative_vertices
}; };
void fp::mesh_storage::addFace(fp::face face, const block_pos& pos) { void fp::mesh_storage::addFace(fp::face face, const block_pos& pos, unsigned char texture_index) {
const auto* face_vertices = face_decode[face]; const auto* face_vertices = face_decode[face];
// negatives are odd numbered, positives are even. // negatives are odd numbered, positives are even.
const auto& face_indices = face % 2 == 0 ? positive_indices : negative_indices; const auto& face_indices = face % 2 == 0 ? positive_indices : negative_indices;
@ -76,6 +82,7 @@ void fp::mesh_storage::addFace(fp::face face, const block_pos& pos) {
for (int i = 0; i < VTX_ARR_SIZE; i++) { for (int i = 0; i < VTX_ARR_SIZE; i++) {
// first copy all the information over, since there is extra information we need to preserve like index and UV / normal // first copy all the information over, since there is extra information we need to preserve like index and UV / normal
translated_face_vertices[i] = face_vertices[i]; translated_face_vertices[i] = face_vertices[i];
translated_face_vertices[i].index = (float) texture_index;
// then we can apply the translation, since the face_vertex value is already there we can add the translation raw // then we can apply the translation, since the face_vertex value is already there we can add the translation raw
translated_face_vertices[i].x += (float) pos.x; translated_face_vertices[i].x += (float) pos.x;
translated_face_vertices[i].y += (float) pos.y; translated_face_vertices[i].y += (float) pos.y;

View File

@ -14,21 +14,22 @@ void fp::world::generateFullMesh(mesh_storage* mesh, fp::chunk* chunk) {
for (int i = 0; i < CHUNK_SIZE; i++) { for (int i = 0; i < CHUNK_SIZE; i++) {
for (int j = 0; j < CHUNK_SIZE; j++) { for (int j = 0; j < CHUNK_SIZE; j++) {
for (int k = 0; k < CHUNK_SIZE; k++) { for (int k = 0; k < CHUNK_SIZE; k++) {
auto block = chunk->storage->get({i, j, k}); auto& block = fp::registry::get(chunk->storage->get({i, j, k}));
auto texture_index = fp::registry::getTextureIndex(block.textureName);
// The main chunk mesh can handle opaque and transparent textures. (Transparency will be discarded) // The main chunk mesh can handle opaque and transparent textures. (Transparency will be discarded)
if (fp::registry::get(block).visibility <= registry::TRANSPARENT_TEXTURE) { if (block.visibility <= registry::TRANSPARENT_TEXTURE) {
if (fp::registry::get(chunk->storage->getBounded(outside, {i - 1, j, k})).visibility && !outside) if (fp::registry::get(chunk->storage->getBounded(outside, {i - 1, j, k})).visibility && !outside)
mesh->addFace(X_NEG, {i, j, k}); mesh->addFace(X_NEG, {i, j, k}, texture_index);
if (fp::registry::get(chunk->storage->getBounded(outside, {i + 1, j, k})).visibility && !outside) if (fp::registry::get(chunk->storage->getBounded(outside, {i + 1, j, k})).visibility && !outside)
mesh->addFace(X_POS, {i, j, k}); mesh->addFace(X_POS, {i, j, k}, texture_index);
if (fp::registry::get(chunk->storage->getBounded(outside, {i, j - 1, k})).visibility && !outside) if (fp::registry::get(chunk->storage->getBounded(outside, {i, j - 1, k})).visibility && !outside)
mesh->addFace(Y_NEG, {i, j, k}); mesh->addFace(Y_NEG, {i, j, k}, texture_index);
if (fp::registry::get(chunk->storage->getBounded(outside, {i, j + 1, k})).visibility && !outside) if (fp::registry::get(chunk->storage->getBounded(outside, {i, j + 1, k})).visibility && !outside)
mesh->addFace(Y_POS, {i, j, k}); mesh->addFace(Y_POS, {i, j, k}, texture_index);
if (fp::registry::get(chunk->storage->getBounded(outside, {i, j, k - 1})).visibility && !outside) if (fp::registry::get(chunk->storage->getBounded(outside, {i, j, k - 1})).visibility && !outside)
mesh->addFace(Z_NEG, {i, j, k}); mesh->addFace(Z_NEG, {i, j, k}, texture_index);
if (fp::registry::get(chunk->storage->getBounded(outside, {i, j, k + 1})).visibility && !outside) if (fp::registry::get(chunk->storage->getBounded(outside, {i, j, k + 1})).visibility && !outside)
mesh->addFace(Z_POS, {i, j, k}); mesh->addFace(Z_POS, {i, j, k}, texture_index);
} }
} }
} }
@ -41,10 +42,12 @@ void fp::world::generateFullMesh(mesh_storage* mesh, fp::chunk* chunk) {
inline void checkEdgeFaces( inline void checkEdgeFaces(
fp::mesh_storage* mesh, fp::chunk* chunk, fp::chunk* neighbour, fp::face face, const fp::block_pos& pos, const fp::block_pos& neighbour_pos fp::mesh_storage* mesh, fp::chunk* chunk, fp::chunk* neighbour, fp::face face, const fp::block_pos& pos, const fp::block_pos& neighbour_pos
) { ) {
auto block = chunk->storage->get(pos); auto& block = fp::registry::get(chunk->storage->get(pos));
if (fp::registry::get(block).visibility <= fp::registry::TRANSPARENT_TEXTURE) { auto texture_index = fp::registry::getTextureIndex(block.textureName);
if (block.visibility <= fp::registry::TRANSPARENT_TEXTURE) {
if (fp::registry::get(neighbour->storage->get(neighbour_pos)).visibility) if (fp::registry::get(neighbour->storage->get(neighbour_pos)).visibility)
mesh->addFace(face, pos); mesh->addFace(face, pos, texture_index);
} }
} }

View File

@ -32,7 +32,7 @@ void fp::registry::registerBlock(fp::block_type id, fp::registry::block_properti
blocks[id] = std::move(properties); blocks[id] = std::move(properties);
} }
fp::registry::block_properties fp::registry::get(fp::block_type id) { fp::registry::block_properties& fp::registry::get(fp::block_type id) {
return blocks.at(id); return blocks.at(id);
} }