From 7a9b2949454e9e8eb5e9461d36059171fd5be26b Mon Sep 17 00:00:00 2001 From: h4570 Date: Tue, 26 Jul 2022 19:32:20 +0200 Subject: [PATCH] free ram and tyrobj wip --- ROADMAP.txt | 7 +- engine/inc/info/info.hpp | 6 + engine/inc/loaders/3d/md2/md2_loader.hpp | 10 +- .../inc/loaders/3d/tyrobj/tyrobj_loader.hpp | 68 ++++ engine/inc/loaders/loader.hpp | 1 + engine/inc/renderer/renderer_settings.hpp | 15 +- engine/src/info/info.cpp | 67 ++++ .../3d/builder/mesh_builder_frame_data.cpp | 4 + engine/src/loaders/3d/md2/md2_loader.cpp | 12 +- .../src/loaders/3d/tyrobj/tyrobj_loader.cpp | 320 ++++++++++++++++++ engine/src/loaders/loader.cpp | 5 + .../src/renderer/core/2d/renderer_core_2d.cpp | 3 +- engine/src/renderer/renderer_settings.cpp | 5 +- samples/h4570/inc/h4570.hpp | 1 + samples/h4570/src/h4570.cpp | 53 ++- 15 files changed, 550 insertions(+), 27 deletions(-) create mode 100644 engine/inc/loaders/3d/tyrobj/tyrobj_loader.hpp create mode 100644 engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp diff --git a/ROADMAP.txt b/ROADMAP.txt index f960a19..21bd5ce 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -1,16 +1,12 @@ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------ --- H4570 -- [Loaders] Think about ".tyrobj" format - implement it (add multicolor support) +- [Loaders] ".tyrobj" format - [Loaders] DFF loader as static Mesh loader - [Game] Update intellisense from docker - [Texture] Test cache hits with large amount of textures (dolphin sample?) - [Demo] Create cool demo which will show all features of Tyra (I will take this one) ---- Wellinator -- [General] Physics and stuff from threeJS - ---- Unassigned - [General] Control generated id to avoid duplication. Maybe Just increment from 0? Add interface IIdentificable? @@ -54,3 +50,4 @@ because Mesh rendering uses only core.render() - [3D] Add drawLine(x, y , color, size) - [3D] Add drawBBox(x, y , color, size) - [File] Async file loading +- [tyrobj] Add multicolor support to tyrobj diff --git a/engine/inc/info/info.hpp b/engine/inc/info/info.hpp index bb8cb1e..7cf983e 100644 --- a/engine/inc/info/info.hpp +++ b/engine/inc/info/info.hpp @@ -11,6 +11,7 @@ #pragma once #include +#include #include "time/timer.hpp" namespace Tyra { @@ -25,8 +26,13 @@ class Info { const u32& getFps() const { return fps; }; + /** @return Available RAM in MB */ + float getAvailableRAM(); + private: float calcFps(); + void* allocateLargestFreeRAMBlock(size_t* size); + size_t getFreeRAMSize(); u8 fpsDelayer; u32 fps; diff --git a/engine/inc/loaders/3d/md2/md2_loader.hpp b/engine/inc/loaders/3d/md2/md2_loader.hpp index cf3052e..c77fef5 100644 --- a/engine/inc/loaders/3d/md2/md2_loader.hpp +++ b/engine/inc/loaders/3d/md2/md2_loader.hpp @@ -20,12 +20,12 @@ class MD2Loader : public Loader { MD2Loader(); ~MD2Loader(); - MeshBuilderData* load(const char* fullpath, const float& t_scale, - const u8& t_invertT); + MeshBuilderData* load(const char* fullpath, const float& scale, + const bool& invertT); - inline MeshBuilderData* load(const std::string& fullpath, - const float& t_scale, const u8& t_invertT) { - return load(fullpath.c_str(), t_scale, t_invertT); + inline MeshBuilderData* load(const std::string& fullpath, const float& scale, + const bool& invertT) { + return load(fullpath.c_str(), scale, invertT); } }; diff --git a/engine/inc/loaders/3d/tyrobj/tyrobj_loader.hpp b/engine/inc/loaders/3d/tyrobj/tyrobj_loader.hpp new file mode 100644 index 0000000..8a134f5 --- /dev/null +++ b/engine/inc/loaders/3d/tyrobj/tyrobj_loader.hpp @@ -0,0 +1,68 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2020, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +#include "../../loader.hpp" +#include "../builder/mesh_builder_data.hpp" +#include + +namespace Tyra { + +struct TyraobjData { + u32 vertexCount, stsCount, normalsCount, colorsCount, materialsCount, + framesCount; + u32* materialsFaces; + float scale; + bool invertT; +}; + +struct TyraobjReadInfo { + u32 verticesI, coordsI, normalsI, colorsI, faceI; + s16 materialsI; +}; + +/** Class responsible for loading&parsing custom Tyra obj files */ +class TyrobjLoader : public Loader { + public: + TyrobjLoader(); + ~TyrobjLoader(); + + /** Load multiple tyrobj files (dynamic) */ + MeshBuilderData* load(const char* fullpath, const u16& count, + const float& scale, const bool& invertT); + + inline MeshBuilderData* load(const std::string& fullpath, const u16& count, + const float& scale, const bool& invertT) { + return load(fullpath.c_str(), count, scale, invertT); + } + + private: + TyraobjData scan(FILE* file, const u32& framesCount); + void loadFile(FILE* file, const std::string& path, const u16& frameIndex, + const TyraobjData& inputData, MeshBuilderData* outputData); + + void initReadInfo(TyraobjReadInfo* info); + void readVertices(TyraobjReadInfo* info, FILE* file, const u16& frameIndex, + const TyraobjData& inputData, MeshBuilderData* outputData); + void readTextureCoords(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, const TyraobjData& inputData, + MeshBuilderData* outputData); + void readNormals(TyraobjReadInfo* info, FILE* file, const u16& frameIndex, + const TyraobjData& inputData, MeshBuilderData* outputData); + void readColors(TyraobjReadInfo* info, FILE* file, const u16& frameIndex, + const TyraobjData& inputData, MeshBuilderData* outputData); + void readMaterials(TyraobjReadInfo* info, FILE* file, const u16& frameIndex, + const TyraobjData& inputData, MeshBuilderData* outputData); + void readFaces(TyraobjReadInfo* info, FILE* file, const u16& frameIndex, + const TyraobjData& inputData, MeshBuilderData* outputData); +}; + +} // namespace Tyra diff --git a/engine/inc/loaders/loader.hpp b/engine/inc/loaders/loader.hpp index eb093c9..334b3eb 100644 --- a/engine/inc/loaders/loader.hpp +++ b/engine/inc/loaders/loader.hpp @@ -18,6 +18,7 @@ class Loader { protected: std::string getFilenameFromPath(const std::string& path); std::string getFilenameWithoutExtension(const std::string& filename); + std::string getExtensionOfFilename(const std::string& filename); }; } // namespace Tyra diff --git a/engine/inc/renderer/renderer_settings.hpp b/engine/inc/renderer/renderer_settings.hpp index 3317c7d..55804bb 100644 --- a/engine/inc/renderer/renderer_settings.hpp +++ b/engine/inc/renderer/renderer_settings.hpp @@ -20,10 +20,12 @@ class RendererSettings { RendererSettings() : width(640.0F), height(448.0F), + interlacedHeightF(height / 2), near(0.1F), far(4096.0F), projectionScale(4096.0F), - aspectRatio(width / height) {} + aspectRatio(width / height), + interlacedHeightUI(static_cast(interlacedHeightF)) {} ~RendererSettings(); const float& getWidth() const { return width; } @@ -32,10 +34,9 @@ class RendererSettings { const float& getFar() const { return far; } const float& getProjectionScale() const { return projectionScale; } const float& getAspectRatio() const { return aspectRatio; } - - float getInterlacedHeightF() const { return getHeight() / 2; } - unsigned int getInterlacedHeightUI() const { - return static_cast(getInterlacedHeightF()); + const float& getInterlacedHeightF() const { return interlacedHeightF; } + const unsigned int& getInterlacedHeightUI() const { + return interlacedHeightUI; } static void copy(RendererSettings* out, const RendererSettings* in); @@ -45,7 +46,9 @@ class RendererSettings { std::string getPrint() const; private: - float width, height, near, far, projectionScale, aspectRatio; + float width, height, interlacedHeightF, near, far, projectionScale, + aspectRatio; + unsigned int interlacedHeightUI; }; } // namespace Tyra diff --git a/engine/src/info/info.cpp b/engine/src/info/info.cpp index d08077b..af30fd1 100644 --- a/engine/src/info/info.cpp +++ b/engine/src/info/info.cpp @@ -10,6 +10,8 @@ */ #include "info/info.hpp" +#include "strings.h" +#include namespace Tyra { @@ -36,4 +38,69 @@ float Info::calcFps() { return 15625.0F / (float)timeDelta; // PAL } +float Info::getAvailableRAM() { + size_t bits = getFreeRAMSize(); + return bits / 1024.0F / 1024.0F; +} + +void* Info::allocateLargestFreeRAMBlock(size_t* Size) { + size_t s0, s1; + void* p; + + s0 = ~(size_t)0 ^ (~(size_t)0 >> 1); + + while (s0 && (p = malloc(s0)) == NULL) s0 >>= 1; + + if (p) free(p); + + s1 = s0 >> 1; + + while (s1) { + if ((p = malloc(s0 + s1)) != NULL) { + s0 += s1; + free(p); + } + s1 >>= 1; + } + + while (s0 && (p = malloc(s0)) == NULL) s0 ^= s0 & -s0; + + *Size = s0; + return p; +} + +size_t Info::getFreeRAMSize() { + size_t total = 0; + void* pFirst = NULL; + void* pLast = NULL; + + for (;;) { + size_t largest; + void* p = allocateLargestFreeRAMBlock(&largest); + + if (largest < sizeof(void*)) { + if (p != NULL) free(p); + break; + } + + *(void**)p = NULL; + + total += largest; + + if (pFirst == NULL) pFirst = p; + + if (pLast != NULL) *(void**)pLast = p; + + pLast = p; + } + + while (pFirst != NULL) { + void* p = *(void**)pFirst; + free(pFirst); + pFirst = p; + } + + return total; +} + } // Namespace Tyra \ No newline at end of file diff --git a/engine/src/loaders/3d/builder/mesh_builder_frame_data.cpp b/engine/src/loaders/3d/builder/mesh_builder_frame_data.cpp index e7d7513..71d5d8f 100644 --- a/engine/src/loaders/3d/builder/mesh_builder_frame_data.cpp +++ b/engine/src/loaders/3d/builder/mesh_builder_frame_data.cpp @@ -40,21 +40,25 @@ MeshBuilderFrameData::~MeshBuilderFrameData() { } void MeshBuilderFrameData::allocateTextureCoords(const u32& count) { + if (count == 0) return; textureCoordsCount = count; textureCoords = new Vec4[count]; } void MeshBuilderFrameData::allocateVertices(const u32& count) { + if (count == 0) return; verticesCount = count; vertices = new Vec4[count]; } void MeshBuilderFrameData::allocateNormals(const u32& count) { + if (count == 0) return; normalsCount = count; normals = new Vec4[count]; } void MeshBuilderFrameData::allocateColors(const u32& count) { + if (count == 0) return; colorsCount = count; colors = new Color[count]; } diff --git a/engine/src/loaders/3d/md2/md2_loader.cpp b/engine/src/loaders/3d/md2/md2_loader.cpp index f5d796e..a1f1933 100644 --- a/engine/src/loaders/3d/md2/md2_loader.cpp +++ b/engine/src/loaders/3d/md2/md2_loader.cpp @@ -75,8 +75,8 @@ MD2Loader::MD2Loader() {} MD2Loader::~MD2Loader() {} -MeshBuilderData* MD2Loader::load(const char* fullpath, const float& t_scale, - const u8& t_invertT) { +MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale, + const bool& invertT) { std::string path = fullpath; TYRA_ASSERT(!path.empty(), "Provided path is empty!"); @@ -131,11 +131,11 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& t_scale, for (u32 i = 0; i < vertexCount; i++) { temp.set( ((frame->verts[i].v[0] * frame->scale[0]) + frame->translate[0]) * - t_scale, + scale, ((frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1]) * - t_scale, + scale, ((frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]) * - t_scale); + scale); result->frames[j]->vertices[i].set(temp); @@ -159,7 +159,7 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& t_scale, temp.set(static_cast(texCoord->s) / header.skinwidth, static_cast(texCoord->t) / header.skinheight, 1.0F, 0.0F); - if (t_invertT) temp.y = 1.0F - temp.y; + if (invertT) temp.y = 1.0F - temp.y; for (u32 j = 0; j < framesCount; j++) result->frames[j]->textureCoords[i].set(temp); diff --git a/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp b/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp new file mode 100644 index 0000000..f7c6b72 --- /dev/null +++ b/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp @@ -0,0 +1,320 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2020, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Michał Mostowik +*/ + +#include +#include +#include +#include "math/vec2.hpp" +#include "math/vec4.hpp" +#include "renderer/models/color.hpp" +#include "debug/debug.hpp" +#include "loaders/3d/tyrobj/tyrobj_loader.hpp" + +namespace Tyra { + +TyrobjLoader::TyrobjLoader() {} + +TyrobjLoader::~TyrobjLoader() {} + +MeshBuilderData* TyrobjLoader::load(const char* fullpath, const u16& count, + const float& scale, const bool& invertT) { + std::string path = fullpath; + TYRA_ASSERT(!path.empty(), "Provided path is empty!"); + + auto rawFilename = getFilenameWithoutExtension(path); + auto extension = getExtensionOfFilename(path); + + auto firstFile = rawFilename + "1." + extension; + FILE* firstFileHandler = fopen(firstFile.c_str(), "rb"); + TYRA_ASSERT(firstFileHandler != nullptr, "Failed to load: ", firstFile); + auto data = scan(firstFileHandler, count); + data.scale = scale; + data.invertT = invertT; + fclose(firstFileHandler); + + auto result = new MeshBuilderData(); + result->allocate(data.framesCount, data.materialsCount); + result->normalsEnabled = data.normalsCount > 0; + result->textureCoordsEnabled = data.stsCount > 0; + result->manyColorsEnabled = data.colorsCount > 0; + + for (u16 i = 1; i <= count; i++) { + auto path = rawFilename + std::to_string(i) + "." + extension; + FILE* fileHandler = fopen(path.c_str(), "rb"); + TYRA_ASSERT(fileHandler != nullptr, "Failed to load: ", path); + loadFile(fileHandler, path, i - 1, data, result); + fclose(fileHandler); + } + + delete data.materialsFaces; + return result; +} + +TyraobjData TyrobjLoader::scan(FILE* file, const u32& framesCount) { + TyraobjData result; + result.vertexCount = 0; + result.stsCount = 0; + result.normalsCount = 0; + result.colorsCount = 0; + result.materialsCount = 0; + result.framesCount = framesCount; + + while (1) { + char lineHeader[128]; + int res = fscanf(file, "%s", lineHeader); + if (res != EOF) { + if (strcmp(lineHeader, "v") == 0) + result.vertexCount += 1; + else if (strcmp(lineHeader, "vt") == 0) + result.stsCount += 1; + else if (strcmp(lineHeader, "vn") == 0) + result.normalsCount += 1; + else if (strcmp(lineHeader, "vc") == 0) + result.colorsCount += 1; + else if (strcmp(lineHeader, "usemtl") == 0) + result.materialsCount += 1; + } else + break; + } + + result.materialsFaces = new u32[result.materialsCount]; + s16 currentMatI = -1; + + fseek(file, 0, SEEK_SET); + u32 facesCounter = 0; + while (1) { + char lineHeader[128]; + int res = fscanf(file, "%s", lineHeader); + if (res != EOF) { + if (strcmp(lineHeader, "usemtl") == 0) { + if (currentMatI >= 0) // Skip -1 + { + result.materialsFaces[currentMatI] = facesCounter; + facesCounter = 0; + } + currentMatI++; + } else if (strcmp(lineHeader, "f") == 0) + facesCounter += 3; + } else + break; + } + + result.materialsFaces[currentMatI] = facesCounter; // Allocate last one + + return result; +} + +void TyrobjLoader::loadFile(FILE* file, const std::string& path, + const u16& frameIndex, const TyraobjData& inputData, + MeshBuilderData* outputData) { + outputData->frames[frameIndex]->allocateVertices(inputData.vertexCount); + outputData->frames[frameIndex]->allocateNormals(inputData.normalsCount); + outputData->frames[frameIndex]->allocateTextureCoords(inputData.stsCount); + outputData->frames[frameIndex]->allocateColors(inputData.colorsCount); + + TyraobjReadInfo readInfo; + initReadInfo(&readInfo); + + int res = 0; + char* lineHeader = new char[128]; + + while (res != EOF) { + res = fscanf(file, "%s", lineHeader); + + if (strcmp(lineHeader, "v") == 0) { + readVertices(&readInfo, file, frameIndex, inputData, outputData); + } else if (strcmp(lineHeader, "vt") == 0) { + readTextureCoords(&readInfo, file, frameIndex, inputData, outputData); + } else if (strcmp(lineHeader, "vn") == 0) { + readNormals(&readInfo, file, frameIndex, inputData, outputData); + } else if (strcmp(lineHeader, "vc") == 0) { + readColors(&readInfo, file, frameIndex, inputData, outputData); + } else if (strcmp(lineHeader, "usemtl") == 0) { + readMaterials(&readInfo, file, frameIndex, inputData, outputData); + } else if (strcmp(lineHeader, "f") == 0) { + readFaces(&readInfo, file, frameIndex, inputData, outputData); + } + } + + delete[] lineHeader; +} + +void TyrobjLoader::initReadInfo(TyraobjReadInfo* info) { + info->verticesI = 0; + info->coordsI = 0; + info->normalsI = 0; + info->colorsI = 0; + info->faceI = 0; + info->materialsI = -1; +} + +void TyrobjLoader::readVertices(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, + const TyraobjData& inputData, + MeshBuilderData* outputData) { + Vec4 vector(0.0F, 0.0F, 0.0F, 1.0F); + fscanf(file, "%f %f %f\n", &vector.x, &vector.y, &vector.z); + outputData->frames[frameIndex]->vertices[info->verticesI++].set( + vector * inputData.scale); +} + +void TyrobjLoader::readTextureCoords(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, + const TyraobjData& inputData, + MeshBuilderData* outputData) { + Vec2 point(0.0F, 0.0F); + fscanf(file, "%f %f\n", &point.x, &point.y); + if (inputData.invertT) point.y = 1.0F - point.y; + outputData->frames[frameIndex]->textureCoords[info->coordsI++].set( + point.x, point.y, 1.0F, 0.0F); +} + +void TyrobjLoader::readNormals(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, + const TyraobjData& inputData, + MeshBuilderData* outputData) { + Vec4 vector(0.0F, 0.0F, 0.0F, 1.0F); + fscanf(file, "%f %f %f\n", &vector.x, &vector.y, &vector.z); + outputData->frames[frameIndex]->normals[info->normalsI++].set(vector); +} + +void TyrobjLoader::readColors(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, + const TyraobjData& inputData, + MeshBuilderData* outputData) { + Color color(128.0F, 128.0F, 128.0F, 128.0F); + fscanf(file, "%f %f %f %f\n", &color.r, &color.g, &color.b, &color.a); + outputData->frames[frameIndex]->colors[info->colorsI++].set(color); +} + +void TyrobjLoader::readMaterials(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, + const TyraobjData& inputData, + MeshBuilderData* outputData) { + char temp[30]; + fscanf(file, "%s\n", temp); + info->materialsI++; + outputData->materials[info->materialsI]->allocateFaces( + inputData.materialsFaces[info->materialsI]); + outputData->materials[info->materialsI]->name = temp; + info->faceI = 0; +} + +void TyrobjLoader::readFaces(TyraobjReadInfo* info, FILE* file, + const u16& frameIndex, + const TyraobjData& inputData, + MeshBuilderData* outputData) { + // int* x = nullptr; + // fpos_t start; + // fgetpos(file, &start); + // int matches = + // fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", x, x, x, x, x, x, x, x, + // x); + // fsetpos(file, &start); + // int newerMatches = 0; + + // // TODO: No support of vc! + // u32 vertexIndex[3], coordIndex[3], normalIndex[3]; // ,colorIndex[3]; + // for (u16 i = 0; i < 3; i++) { + // vertexIndex[i] = 0; + // coordIndex[i] = 0; + // normalIndex[i] = 0; + // // colorIndex[i] = 0; + // } + + // switch (matches) { + // /** Vs, VTs and VNs all set */ + // case 9: { + // fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], + // &coordIndex[0], &normalIndex[0], &vertexIndex[1], + // &coordIndex[1], &normalIndex[1], &vertexIndex[2], + // &coordIndex[2], &normalIndex[2]); + // } break; + + // /** Loaded only two digits (V, VT) succesfuly. Not setting + // VN. */ + // case 3: { + // fscanf(file, "%d/%d/ %d/%d/ %d/%d/\n", &vertexIndex[0], &coordIndex[0], + // &vertexIndex[1], &coordIndex[1], &vertexIndex[2], + // &coordIndex[2]); + // } break; + + // /** Only V set. Checking for existance of VT or VN. */ + // case 1: { + // /** Check for existance of V/// configuration.. */ + // newerMatches = fscanf(file, "%d// %d// %d//\n", x, x, x); + // fsetpos(file, &start); + // if (newerMatches == 3) { + // /** Configuration confirmed. */ + // fscanf(file, "%d// %d// %d//\n", &vertexIndex[0], &vertexIndex[1], + // &vertexIndex[2]); + // } else { + // /** Failed, checking configuration V//VN */ + // newerMatches = fscanf(file, "%d//%d %d//%d %d//%d", x, x, x, x, x, + // x); fsetpos(file, &start); TYRA_ASSERT(newerMatches == 6, "Unknown + // .obj face for .obj file!"); + // /** Configuration confirmed. */ + // newerMatches = fscanf(file, "%d//%d %d//%d %d//%d", &vertexIndex[0], + // &normalIndex[0], &vertexIndex[1], + // &normalIndex[1], &vertexIndex[2], + // &normalIndex[2]); + // } + // break; + // } break; + // default: { + // TYRA_TRAP("Unknown faces format in .obj file!"); + // break; + // } + // } + + // if (matches == 9 || matches == 2 || matches == 1) { + // outputData->materials[info->materialsI]->vertexFaces[info->faceI] = + // vertexIndex[0] - 1; + // outputData->materials[info->materialsI]->vertexFaces[info->faceI + 1] = + // vertexIndex[1] - 1; + // outputData->materials[info->materialsI]->vertexFaces[info->faceI + 2] = + // vertexIndex[2] - 1; + // } + + // if (matches == 9 || matches == 2) { + // outputData->materials[info->materialsI]->textureCoordFaces[info->faceI] = + // coordIndex[0] - 1; + // outputData->materials[info->materialsI] + // ->textureCoordFaces[info->faceI + 1] = coordIndex[1] - 1; + // outputData->materials[info->materialsI] + // ->textureCoordFaces[info->faceI + 2] = coordIndex[2] - 1; + // } + + // if (matches == 9) { + // outputData->materials[info->materialsI]->normalFaces[info->faceI] = + // normalIndex[0] - 1; + // outputData->materials[info->materialsI]->normalFaces[info->faceI + 1] = + // normalIndex[1] - 1; + // outputData->materials[info->materialsI]->normalFaces[info->faceI + 2] = + // normalIndex[2] - 1; + // info->faceI += 3; + // } else if (matches == 2) { + // info->faceI += 2; + // } else if (matches == 1) { + // if (newerMatches == 3) { + // info->faceI += 1; + // } else if (newerMatches == 6) { + // outputData->materials[info->materialsI]->normalFaces[info->faceI] = + // normalIndex[0] - 1; + // outputData->materials[info->materialsI]->normalFaces[info->faceI + 1] = + // normalIndex[1] - 1; + // outputData->materials[info->materialsI]->normalFaces[info->faceI + 2] = + // normalIndex[2] - 1; + // info->faceI += 2; + // } + // } +} + +} // namespace Tyra diff --git a/engine/src/loaders/loader.cpp b/engine/src/loaders/loader.cpp index bff63ff..0e0ccce 100644 --- a/engine/src/loaders/loader.cpp +++ b/engine/src/loaders/loader.cpp @@ -26,4 +26,9 @@ std::string Loader::getFilenameWithoutExtension(const std::string& filename) { return filename.substr(0, lastindex); } +std::string Loader::getExtensionOfFilename(const std::string& filename) { + auto lastindex = filename.find_last_of("."); + return filename.substr(lastindex + 1); +} + } // namespace Tyra diff --git a/engine/src/renderer/core/2d/renderer_core_2d.cpp b/engine/src/renderer/core/2d/renderer_core_2d.cpp index cfc0377..4343e6a 100644 --- a/engine/src/renderer/core/2d/renderer_core_2d.cpp +++ b/engine/src/renderer/core/2d/renderer_core_2d.cpp @@ -72,11 +72,12 @@ void RendererCore2D::render(Sprite* sprite, rect->color.q = 0; rect->v0.x = sprite->position.x; - rect->v0.y = sprite->position.y; + rect->v0.y = sprite->position.y / 2.0F; // interlacing rect->v0.z = (u32)-1; rect->v1.x = (sprite->size.x * sprite->scale) + sprite->position.x; rect->v1.y = (sprite->size.y * sprite->scale) + sprite->position.y; + rect->v1.y /= 2.0F; // interlacing rect->v1.z = (u32)-1; auto* packet = packets[context]; diff --git a/engine/src/renderer/renderer_settings.cpp b/engine/src/renderer/renderer_settings.cpp index 277bafd..1053a58 100644 --- a/engine/src/renderer/renderer_settings.cpp +++ b/engine/src/renderer/renderer_settings.cpp @@ -21,6 +21,8 @@ void RendererSettings::copy(RendererSettings* out, const RendererSettings* in) { out->far = in->far; out->projectionScale = in->projectionScale; out->aspectRatio = in->aspectRatio; + out->interlacedHeightF = in->interlacedHeightF; + out->interlacedHeightUI = in->interlacedHeightUI; } void RendererSettings::set(const RendererSettings& v) { copy(this, &v); } @@ -38,7 +40,8 @@ std::string RendererSettings::getPrint() const { res << "near: " << near << ", "; res << "far: " << far << ", "; res << "projectionScale: " << projectionScale << ", "; - res << "aspectRatio: " << aspectRatio; + res << "aspectRatio: " << aspectRatio << ", "; + res << "interlaced height: " << interlacedHeightF; res << ")"; return res.str(); } diff --git a/samples/h4570/inc/h4570.hpp b/samples/h4570/inc/h4570.hpp index d340a18..90d06be 100644 --- a/samples/h4570/inc/h4570.hpp +++ b/samples/h4570/inc/h4570.hpp @@ -30,6 +30,7 @@ class H4570 : public Game { private: Engine* engine; + DynamicMesh* cube; StaticMesh* staticMesh; DynamicMesh* warrior; u8 warriorsCount; diff --git a/samples/h4570/src/h4570.cpp b/samples/h4570/src/h4570.cpp index f89589a..4907718 100644 --- a/samples/h4570/src/h4570.cpp +++ b/samples/h4570/src/h4570.cpp @@ -11,6 +11,7 @@ #include "h4570.hpp" #include "file/file_utils.hpp" #include "loaders/3d/md2/md2_loader.hpp" +#include "loaders/3d/tyrobj/tyrobj_loader.hpp" #include "thread/threading.hpp" namespace Tyra { @@ -29,6 +30,7 @@ H4570::~H4570() {} StaticMesh* getStaticMesh(Renderer* renderer); DynamicMesh* getWarrior(Renderer* renderer); +DynamicMesh* getCube(Renderer* renderer); StaPipOptions* getStaPipOptions(); DynPipOptions* getDynPipOptions(); void setPipelineOptions(PipelineOptions* options); @@ -36,7 +38,6 @@ Sprite* get2DPicture(Renderer* renderer); void H4570::init() { // Song - engine->audio.loadSong(FileUtils::fromCwd("mafikizolo-loot.wav")); engine->audio.setSongLoop(true); engine->audio.setSongVolume(30); @@ -48,6 +49,8 @@ void H4570::init() { staticMesh = getStaticMesh(&engine->renderer); + cube = getCube(&engine->renderer); + warrior = getWarrior(&engine->renderer); warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh( warrior->getMaterial(0)->getId()); @@ -120,8 +123,9 @@ void H4570::init() { u32 counter = 0; void H4570::loop() { - if (counter++ > 30) { - // TYRA_LOG(engine->info.getFps()); + if (counter++ > 100) { + TYRA_LOG("Free RAM: ", engine->info.getAvailableRAM(), " MB"); + TYRA_LOG("FPS: ", engine->info.getFps()); counter = 0; } @@ -137,11 +141,14 @@ void H4570::loop() { blocks[i].model = translations[i] * rotations[i] * scales[i]; } + engine->renderer.renderer2D.render(picture); + engine->renderer.renderer3D.usePipeline(&stapip); { stapip.render(staticMesh, staOptions); } engine->renderer.renderer3D.usePipeline(&dynpip); { + // dynpip.render(cube); Threading::switchThread(); for (u8 i = 0; i < warriorsCount; i++) { dynpip.render(warriors[i], dynOptions); @@ -186,6 +193,46 @@ DynamicMesh* getWarrior(Renderer* renderer) { return result; } +DynamicMesh* getCube(Renderer* renderer) { + TyrobjLoader loader; + auto* data = + loader.load(FileUtils::fromCwd("untitled.tyrobj"), 2, .08F, false); + + TYRA_LOG("Frames count: ", data->framesCount); + TYRA_LOG("Materials count: ", data->materialsCount); + + for (u32 i = 0; i < data->framesCount; i++) { + TYRA_LOG("Vertex count ", i, ": ", data->frames[i]->verticesCount); + for (u32 j = 0; j < data->frames[i]->verticesCount; j++) { + TYRA_LOG("Vertex ", j, ": ", data->frames[i]->vertices[j].getPrint()); + } + + TYRA_LOG("Normals count ", i, ": ", data->frames[i]->normalsCount); + for (u32 j = 0; j < data->frames[i]->normalsCount; j++) { + TYRA_LOG("Normal ", j, ": ", data->frames[i]->normals[j].getPrint()); + } + } + + for (u32 i = 0; i < data->materialsCount; i++) { + TYRA_LOG("Material ", i, ": ", data->materials[i]->name); + TYRA_LOG("Faces count: ", data->materials[i]->count); + for (u32 j = 0; j < data->materials[i]->count; j++) { + TYRA_LOG("Vertex face ", j, ": ", data->materials[i]->vertexFaces); + TYRA_LOG("Normal face ", j, ": ", data->materials[i]->normalFaces); + } + } + + TYRA_BREAKPOINT(); + auto* result = new DynamicMesh(*data); + // result->translation.translateZ(-30.0F); + delete data; + + result->playAnimation(0, result->getFramesCount() - 1); + result->setAnimSpeed(0.15F); + + return result; +} + Sprite* get2DPicture(Renderer* renderer) { auto* sprite = new Sprite;