diff --git a/CMakeLists.txt b/CMakeLists.txt index 770fd37..c8a27af 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,3 +30,4 @@ add_subdirectory(test) add_subdirectory(demos/demo1-wireframes) add_subdirectory(demos/demo2-blender-import) +add_subdirectory(demos/demo3-textures) diff --git a/demos/demo2-blender-import/converter.js b/demos/demo2-blender-import/converter.js index a692f9c..7f527aa 100644 --- a/demos/demo2-blender-import/converter.js +++ b/demos/demo2-blender-import/converter.js @@ -19,12 +19,8 @@ var result = "\t auto obj = new Mesh();\n"; var vertices = 0; -function addMesh(x, y, z) { - result += `\t obj->add(VectorFx::fromFloat(${x}, ${y}, ${z}));\n`; - vertices++; -} -function addMeshWithNormals(x, y, z, nx, ny, nz) { - result += `\t obj->add(VectorFx::fromFloat(${x}, ${y}, ${z}), VectorFx::fromFloat(${nx}, ${ny}, ${nz}));\n`; +function addMeshWithNormals(x, y, z, nx, ny, nz, u, v) { + result += `\t obj->add(VectorFx::fromFloat(${x}, ${y}, ${z}), VectorFx::fromFloat(${nx}, ${ny}, ${nz}), ${u}, ${v});\n`; vertices++; } var faces = 0; @@ -70,25 +66,33 @@ for(var meshIndex = 0; meshIndex < jsonObject.meshes.length; meshIndex++) { } var verticesCount = verticesArray.length / verticesStep; var facesCount = indicesArray.length / 3; - //var mesh = new SoftEngine.Mesh(jsonObject.meshes[meshIndex].name, verticesCount, facesCount); for(var index = 0; index < verticesCount; index++) { var x = verticesArray[index * verticesStep]; var y = verticesArray[index * verticesStep + 1]; var z = verticesArray[index * verticesStep + 2]; + var u = 0, v = 0; if(x !== undefined && y !== undefined && z !== undefined) { if(data && data.normals) { var nx = data.normals[index * verticesStep]; var ny = data.normals[index * verticesStep + 1]; var nz = data.normals[index * verticesStep + 2]; + if(data.uvs) { + u = data.uvs[index]; + v = data.uvs[index + 1]; + } - addMeshWithNormals(x, y, z, nx, ny, nz); + addMeshWithNormals(x, y, z, nx, ny, nz, u, v); } else { var nx = verticesArray[index * verticesStep + 3]; var ny = verticesArray[index * verticesStep + 4]; var nz = verticesArray[index * verticesStep + 5]; + if(uvCount > 0) { + u = verticesArray[index * verticesStep + 6]; + v = verticesArray[index * verticesStep + 7]; + } - addMeshWithNormals(x, y, z, nx, ny, nz); + addMeshWithNormals(x, y, z, nx, ny, nz, u, v); } } else { console.log(`WARN; vertices index ${index} with step ${verticesStep} contains invalid data: ${x}, ${y}, ${z}`) @@ -110,7 +114,7 @@ for(var meshIndex = 0; meshIndex < jsonObject.meshes.length; meshIndex++) { } done(); -fs.writeFileSync('src/mesh.cpp', result); +fs.writeFileSync(args[1], result); console.log(`mesh.cpp written; ${vertices} vertices and ${faces} faces. GLHF!`) if(vertices > 800) { console.log('WARNING lots of vertices detected, this will not run well...'); diff --git a/demos/demo3-textures/CMakeLists.txt b/demos/demo3-textures/CMakeLists.txt new file mode 100644 index 0000000..759fd30 --- /dev/null +++ b/demos/demo3-textures/CMakeLists.txt @@ -0,0 +1,13 @@ +project(textures) + +add_executable(${PROJECT_NAME}.elf + src/main.cpp + src/mesh.cpp + src/texturescene.cpp + ) + +target_link_libraries(${PROJECT_NAME}.elf gba-bitmap-engine) + +add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -v -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.gba + ) diff --git a/demos/demo3-textures/img/questionmark.png b/demos/demo3-textures/img/questionmark.png new file mode 100644 index 0000000..53192c9 Binary files /dev/null and b/demos/demo3-textures/img/questionmark.png differ diff --git a/demos/demo3-textures/src/main.cpp b/demos/demo3-textures/src/main.cpp new file mode 100644 index 0000000..d03748d --- /dev/null +++ b/demos/demo3-textures/src/main.cpp @@ -0,0 +1,23 @@ +// +// Created by Wouter Groeneveld on 11/07/20. +// + +#include +#include +#include + +#include "texturescene.h" + +int main() { + std::shared_ptr engine(new GBAEngine()); + engine.get()->setRenderer(new RasterizerRenderer()); + + TextureScene* startScene = new TextureScene(engine); + engine->setScene(startScene); + + while (true) { + engine->update(); + } + + return 0; +} \ No newline at end of file diff --git a/demos/demo3-textures/src/mesh.cpp b/demos/demo3-textures/src/mesh.cpp new file mode 100644 index 0000000..ed15519 --- /dev/null +++ b/demos/demo3-textures/src/mesh.cpp @@ -0,0 +1,42 @@ +#include +Mesh* createMesh() { + auto obj = new Mesh(); + obj->add(VectorFx::fromFloat(0.5, -0.5, 0.5), VectorFx::fromFloat(0, 0, 1), 1, 1); + obj->add(VectorFx::fromFloat(-0.5, -0.5, 0.5), VectorFx::fromFloat(0, 0, 1), 1, 0); + obj->add(VectorFx::fromFloat(-0.5, 0.5, 0.5), VectorFx::fromFloat(0, 0, 1), 0, 1); + obj->add(VectorFx::fromFloat(0.5, 0.5, 0.5), VectorFx::fromFloat(0, 0, 1), 1, 0); + obj->add(VectorFx::fromFloat(0.5, 0.5, -0.5), VectorFx::fromFloat(0, 0, -1), 0, 0); + obj->add(VectorFx::fromFloat(-0.5, 0.5, -0.5), VectorFx::fromFloat(0, 0, -1), 0, 1); + obj->add(VectorFx::fromFloat(-0.5, -0.5, -0.5), VectorFx::fromFloat(0, 0, -1), 1, 0); + obj->add(VectorFx::fromFloat(0.5, -0.5, -0.5), VectorFx::fromFloat(0, 0, -1), 0, 1); + obj->add(VectorFx::fromFloat(0.5, 0.5, -0.5), VectorFx::fromFloat(1, 0, 0), 1, 1); + obj->add(VectorFx::fromFloat(0.5, -0.5, -0.5), VectorFx::fromFloat(1, 0, 0), 1, 0); + obj->add(VectorFx::fromFloat(0.5, -0.5, 0.5), VectorFx::fromFloat(1, 0, 0), 0, 1); + obj->add(VectorFx::fromFloat(0.5, 0.5, 0.5), VectorFx::fromFloat(1, 0, 0), 1, 0); + obj->add(VectorFx::fromFloat(-0.5, 0.5, 0.5), VectorFx::fromFloat(-1, 0, 0), 0, 0); + obj->add(VectorFx::fromFloat(-0.5, -0.5, 0.5), VectorFx::fromFloat(-1, 0, 0), 0, 1); + obj->add(VectorFx::fromFloat(-0.5, -0.5, -0.5), VectorFx::fromFloat(-1, 0, 0), 1, 0); + obj->add(VectorFx::fromFloat(-0.5, 0.5, -0.5), VectorFx::fromFloat(-1, 0, 0), 0, 1); + obj->add(VectorFx::fromFloat(-0.5, 0.5, 0.5), VectorFx::fromFloat(0, 1, 0), 1, 1); + obj->add(VectorFx::fromFloat(-0.5, 0.5, -0.5), VectorFx::fromFloat(0, 1, 0), 1, 0); + obj->add(VectorFx::fromFloat(0.5, 0.5, -0.5), VectorFx::fromFloat(0, 1, 0), 0, 1); + obj->add(VectorFx::fromFloat(0.5, 0.5, 0.5), VectorFx::fromFloat(0, 1, 0), 1, 0); + obj->add(VectorFx::fromFloat(0.5, -0.5, 0.5), VectorFx::fromFloat(0, -1, 0), 0, 0); + obj->add(VectorFx::fromFloat(0.5, -0.5, -0.5), VectorFx::fromFloat(0, -1, 0), 0, 1); + obj->add(VectorFx::fromFloat(-0.5, -0.5, -0.5), VectorFx::fromFloat(0, -1, 0), 1, 0); + obj->add(VectorFx::fromFloat(-0.5, -0.5, 0.5), VectorFx::fromFloat(0, -1, 0), 0, 1); + obj->addFace(0, 1, 2); + obj->addFace(0, 2, 3); + obj->addFace(4, 5, 6); + obj->addFace(4, 6, 7); + obj->addFace(8, 9, 10); + obj->addFace(8, 10, 11); + obj->addFace(12, 13, 14); + obj->addFace(12, 14, 15); + obj->addFace(16, 17, 18); + obj->addFace(16, 18, 19); + obj->addFace(20, 21, 22); + obj->addFace(20, 22, 23); + obj->setPosition(VectorFx::fromInt(0, 0, 0)); + return obj; +} diff --git a/demos/demo3-textures/src/texturedata.h b/demos/demo3-textures/src/texturedata.h new file mode 100644 index 0000000..72d9f12 --- /dev/null +++ b/demos/demo3-textures/src/texturedata.h @@ -0,0 +1,85 @@ +// +// Created by Wouter Groeneveld on 16/07/20. +// + +#ifndef GBA_BITMAP_ENGINE_PROJECT_TEXTURE_H +#define GBA_BITMAP_ENGINE_PROJECT_TEXTURE_H + + +//{{BLOCK(questionmark) + +//====================================================================== +// +// questionmark, 16x16@16, +// + 4 tiles not compressed +// Total size: 512 = 512 +// +// Time-stamp: 2020-07-15, 20:38:24 +// Exported by Cearn's GBA Image Transmogrifier, v0.8.6 +// ( http://www.coranac.com/projects/#grit ) +// +//====================================================================== + +// BLUE: 2 +// DARK: 3 +// LIGHT: 4 +// BLACK: 0 + +#define QUESTIONMARK_TILES_LENGTH 256 + +const unsigned short questionmarkTiles[QUESTIONMARK_TILES_LENGTH] __attribute__((aligned(4)))= + { + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 3, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, + 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, + 3, 4, 4, 4, 3, 3, 0, 0, 3, 3, 3, 0, 4, 4, 4, 0, + 3, 4, 4, 4, 3, 3, 0, 4, 3, 3, 3, 0, 4, 4, 4, 0, + 3, 4, 4, 4, 3, 3, 0, 4, 3, 3, 3, 0, 4, 4, 4, 0, + 3, 4, 4, 4, 4, 0, 0, 4, 3, 0, 0, 0, 4, 4, 4, 0, + 3, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0, 0, 4, 4, 4, 0, + 3, 4, 4, 4, 4, 4, 4, 3, 3, 0, 4, 4, 4, 4, 4, 0, + 3, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 0, + 3, 4, 4, 4, 4, 4, 4, 3, 3, 4, 4, 4, 4, 4, 4, 0, + 3, 4, 4, 4, 4, 4, 4, 3, 3, 0, 4, 4, 4, 4, 4, 0, + 3, 4, 0, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 0, 4, 0, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + +//}}BLOCK(questionmark) + +//{{BLOCK(Shared) + +//====================================================================== +// +// Shared, 16x16@8, +// + palette 4 entries, not compressed +// Total size: 8 = 8 +// +// Time-stamp: 2020-07-15, 20:38:24 +// Exported by Cearn's GBA Image Transmogrifier, v0.8.6 +// ( http://www.coranac.com/projects/#grit ) +// +//====================================================================== + +unsigned short color(unsigned int r, unsigned int g, unsigned int b) { + r = (float) r / 255 * 31; + g = (float) g / 255 * 31; + b = (float) b / 255 * 31; + + unsigned short c = (b & 0x1f) << 10; + c |= (g & 0x1f) << 5; + c |= (r & 0x1f); + return c; +} + +const unsigned short sharedPal[] __attribute__((aligned(4)))= + { + 0x0000, color(255, 255, 255), color(92, 148, 252), color(200, 76, 12), color(252, 152, 56) + }; + +//}}BLOCK(Shared) + + +#endif //GBA_BITMAP_ENGINE_PROJECT_TEXTURE_H diff --git a/demos/demo3-textures/src/texturescene.cpp b/demos/demo3-textures/src/texturescene.cpp new file mode 100644 index 0000000..01f3b0b --- /dev/null +++ b/demos/demo3-textures/src/texturescene.cpp @@ -0,0 +1,25 @@ +// +// Created by Wouter Groeneveld on 16/07/20. +// + +#include "texturescene.h" +#include "texturedata.h" + +std::vector TextureScene::meshes() { + return { box.get() }; +} + +Camera TextureScene::camera() { + return Camera(VectorFx::fromInt(0, 0, 10), VectorFx::fromInt(0, 0, 0)); +} + +void TextureScene::load() { + foregroundPalette = std::unique_ptr(new ForegroundPaletteManager()); + backgroundPalette = std::unique_ptr(new BackgroundPaletteManager(sharedPal, sizeof(sharedPal))); + + box = std::unique_ptr(createMesh()); +} + +void TextureScene::tick(u16 keys) { + box->rotate(10, 10); +} diff --git a/demos/demo3-textures/src/texturescene.h b/demos/demo3-textures/src/texturescene.h new file mode 100644 index 0000000..dce9221 --- /dev/null +++ b/demos/demo3-textures/src/texturescene.h @@ -0,0 +1,32 @@ +// +// Created by Wouter Groeneveld on 16/07/20. +// + +#ifndef GBA_BITMAP_ENGINE_PROJECT_TEXTURESCENE_H +#define GBA_BITMAP_ENGINE_PROJECT_TEXTURESCENE_H + +#include +#include +#include +#include +#include + +// forward declaration of generated mesh.cpp file +Mesh* createMesh(); + +class TextureScene : public Scene { + std::unique_ptr box; + +public: + + TextureScene(std::shared_ptr engine) : Scene(engine) {} + + void load() override; + void tick(u16 keys) override; + std::vector meshes() override; + Camera camera() override; + +}; + + +#endif //GBA_BITMAP_ENGINE_PROJECT_TEXTURESCENE_H diff --git a/engine/include/libgba-bitmap-engine/mesh.h b/engine/include/libgba-bitmap-engine/mesh.h index eb7bb79..1f16188 100644 --- a/engine/include/libgba-bitmap-engine/mesh.h +++ b/engine/include/libgba-bitmap-engine/mesh.h @@ -23,6 +23,7 @@ private: public: void add(VectorFx coords, VectorFx normal); + void add(VectorFx coords, VectorFx normal, float u, float v); void add(VectorFx v); void addFace(int a, int b, int c); diff --git a/engine/include/libgba-bitmap-engine/vertex.h b/engine/include/libgba-bitmap-engine/vertex.h index f18f35f..ec2d4a7 100644 --- a/engine/include/libgba-bitmap-engine/vertex.h +++ b/engine/include/libgba-bitmap-engine/vertex.h @@ -11,14 +11,17 @@ class Vertex { private: VectorFx coordinates; VectorFx norm; - // texture coords here + FIXED tU, tV; public: - Vertex(const VectorFx& coord) : coordinates(coord), norm(VectorFx()) {} - Vertex(const VectorFx& coord, const VectorFx& theNorm) : coordinates(coord), norm(theNorm) {} + Vertex(const VectorFx& coord) : coordinates(coord), norm(VectorFx()), tU(0), tV(0) {} + Vertex(const VectorFx& coord, const VectorFx& theNorm) : coordinates(coord), norm(theNorm), tU(0), tV(0) {} + Vertex(const VectorFx& coord, const VectorFx& theNorm, float theU, float theV) : coordinates(coord), norm(theNorm), tU(float2fx(theU)), tV(float2fx(theV)) {} inline const VectorFx& coords() const { return coordinates; } inline const VectorFx& normal() const { return norm; } + inline FIXED u() { return tU; } + inline FIXED v() { return tV; } }; #endif //GBA_BITMAP_ENGINE_PROJECT_VERTEX_H diff --git a/engine/src/mesh.cpp b/engine/src/mesh.cpp index 4616dd0..208da9d 100644 --- a/engine/src/mesh.cpp +++ b/engine/src/mesh.cpp @@ -14,6 +14,10 @@ void Mesh::add(VectorFx coords, VectorFx normal) { verticesArr.push_back(std::unique_ptr(new Vertex(coords, normal))); } +void Mesh::add(VectorFx coords, VectorFx normal, float u, float v) { + verticesArr.push_back(std::unique_ptr(new Vertex(coords, normal, u, v))); +} + void Mesh::addFace(int a, int b, int c) { auto &vertexA = verticesArr[a]; auto &vertexB = verticesArr[b];