free ram and tyrobj wip

This commit is contained in:
h4570
2022-07-26 19:32:20 +02:00
parent 70028a8f18
commit 7a9b294945
15 changed files with 550 additions and 27 deletions
+6
View File
@@ -11,6 +11,7 @@
#pragma once
#include <tamtypes.h>
#include <stddef.h>
#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;
+5 -5
View File
@@ -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);
}
};
@@ -0,0 +1,68 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2020, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "../../loader.hpp"
#include "../builder/mesh_builder_data.hpp"
#include <string>
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
+1
View File
@@ -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
+9 -6
View File
@@ -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<unsigned int>(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<unsigned int>(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
+67
View File
@@ -10,6 +10,8 @@
*/
#include "info/info.hpp"
#include "strings.h"
#include <stdlib.h>
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
@@ -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];
}
+6 -6
View File
@@ -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<float>(texCoord->s) / header.skinwidth,
static_cast<float>(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);
@@ -0,0 +1,320 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2020, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Michał Mostowik <mostek3pl@gmail.com>
*/
#include <cstring>
#include <stdio.h>
#include <string>
#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
+5
View File
@@ -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
@@ -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];
+4 -1
View File
@@ -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();
}