mirror of
https://github.com/danule222/xrbDS.git
synced 2025-06-18 14:25:33 -04:00
Implement runtime texture loading
This commit is contained in:
parent
f22b9e1bb6
commit
cb1d89065f
@ -5,9 +5,30 @@
|
||||
|
||||
MeshFilter::MeshFilter(const FString &path) {
|
||||
// Load the mesh from the file
|
||||
auto vertices = Utils::File::ReadObjFile(path);
|
||||
auto [shapes, materials] = Utils::File::ReadObjFile(path);
|
||||
|
||||
mesh = LoadResource<Mesh>(vertices);
|
||||
TVector<PtrShr<Texture>> textures;
|
||||
for (const auto &material : materials) {
|
||||
auto texture_binary = Utils::File::ReadBinaryFile<unsigned int>(
|
||||
path.substr(0, path.find_last_of("/"))
|
||||
.append("/")
|
||||
.append(material.diffuse_texname.substr(
|
||||
0, material.diffuse_texname.find_last_of(".")))
|
||||
.append(".img.bin"));
|
||||
|
||||
// auto palette_binary = Utils::File::ReadBinaryFile<unsigned short>(
|
||||
// path.substr(0, path.find_last_of("/"))
|
||||
// .append("/")
|
||||
// .append(material.diffuse_texname.substr(
|
||||
// 0, material.diffuse_texname.find_last_of(".")))
|
||||
// .append(".pal.bin"));
|
||||
|
||||
auto palette_binary = TVector<unsigned short>();
|
||||
|
||||
textures.push_back(LoadResource<Texture>(texture_binary, palette_binary));
|
||||
}
|
||||
|
||||
mesh = LoadResource<Mesh>(shapes, materials, textures);
|
||||
}
|
||||
|
||||
PtrUnq<MeshFilter> MeshFilter::Initialize(const FString &path) {
|
||||
|
@ -44,12 +44,19 @@ PtrUnq<Engine> &Engine::GetInstance() {
|
||||
}
|
||||
|
||||
void Engine::run() {
|
||||
// TEST ------------------------
|
||||
Renderer::GetInstance();
|
||||
|
||||
// TEST ------------------------
|
||||
// Create a MeshInstance3D
|
||||
PtrShr<MeshInstance3D> meshInstance =
|
||||
NewNode<MeshInstance3D>("meshes/mococo/mococo.obj");
|
||||
|
||||
// PtrShr<MeshInstance3D> meshIPnstance =
|
||||
// NewNode<MeshInstance3D>("meshes/cube/cube-tex.obj");
|
||||
|
||||
// PtrShr<MeshInstance3D> meshInstance =
|
||||
// NewNode<MeshInstance3D>("meshes/quad/quad.obj");
|
||||
|
||||
// -----------------------------
|
||||
|
||||
while (pmMainLoop()) {
|
||||
@ -63,6 +70,9 @@ void Engine::processInput() { Input::Update(); }
|
||||
|
||||
void Engine::update() {
|
||||
// Update
|
||||
if (Input::IsButtonDown(EButton::A)) {
|
||||
iprintf("A button pressed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::render() {
|
||||
@ -84,8 +94,7 @@ void Engine::render() {
|
||||
|
||||
Engine::Engine() {
|
||||
// Initialize nitroFS
|
||||
char nitroFSPath[32];
|
||||
strcpy(nitroFSPath, "assets");
|
||||
char nitroFSPath[] = {"assets"};
|
||||
char *nitroFSPathptr = nitroFSPath;
|
||||
if (!nitroFSInit(&nitroFSPathptr))
|
||||
exit(-1);
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <nds.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "input/input.h"
|
||||
|
||||
PtrUnq<Renderer> Renderer::Instance;
|
||||
|
||||
PtrUnq<Renderer> &Renderer::GetInstance() {
|
||||
@ -16,34 +18,45 @@ PtrUnq<Renderer> &Renderer::GetInstance() {
|
||||
return Instance;
|
||||
}
|
||||
|
||||
// TEST -------------------
|
||||
float rotation = 45.f;
|
||||
// TEST -------------------
|
||||
void Renderer::beginFrame() {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(70, 256.0 / 192.0, 0.1, 100);
|
||||
// glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
|
||||
|
||||
// glMatrixMode(GL_TEXTURE);
|
||||
// glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Save the current matrix state
|
||||
|
||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
|
||||
|
||||
glLoadIdentity(); // Load the identity matrix
|
||||
|
||||
// TEST -------------------
|
||||
if (Input::IsButtonHeld(EButton::LEFT))
|
||||
rotation++;
|
||||
if (Input::IsButtonHeld(EButton::RIGHT))
|
||||
rotation--;
|
||||
// TEST -------------------
|
||||
|
||||
// Render scene
|
||||
glTranslatef(0.f, 0.f, -4.f); // Move the camera back
|
||||
glRotatef(45, 1, 1, 0); // Rotation
|
||||
glTranslatef(0.f, -.75f, -2.f); // Move the camera back
|
||||
glRotatef(rotation, 1, 1, 0); // Rotation
|
||||
}
|
||||
|
||||
void Renderer::render(const Transform &transform,
|
||||
const MeshFilter &meshFilter) {
|
||||
// drawCube(1.0f); // Draw a cube
|
||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
|
||||
glBindTexture(0, meshFilter.getMesh()->getTextures()[0]->getId());
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
for (const auto &shapes : meshFilter.getMesh()->getVertices()) {
|
||||
for (const auto &vertex : shapes) {
|
||||
glColor3f(1.0, 0.0, 0.0); // Red
|
||||
glVertex3f(vertex.position.x, vertex.position.y, vertex.position.z);
|
||||
glNormal3f(vertex.normal.x, vertex.normal.y, vertex.normal.z);
|
||||
glColor3b(255, 255, 255);
|
||||
for (const auto &shape : meshFilter.getMesh()->getShapes()) {
|
||||
for (const auto &vertex : shape.vertices) {
|
||||
// glNormal3f(vertex.normal.x, vertex.normal.y, vertex.normal.z);
|
||||
glTexCoord2f(vertex.texCoords.x, vertex.texCoords.y);
|
||||
glVertex3f(vertex.position.x, vertex.position.y, vertex.position.z);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,16 +126,27 @@ Renderer::Renderer() {
|
||||
lcdMainOnTop(); // Set the main screen on top
|
||||
videoSetMode(MODE_0_3D); // Set 3D rendering mode
|
||||
videoSetModeSub(MODE_5_2D); // Set 2D rendering mode for the sub-screen
|
||||
vramSetBankA(VRAM_A_MAIN_BG); // Allocate VRAM for textures
|
||||
vramSetBankB(VRAM_B_TEXTURE);
|
||||
vramSetBankC(VRAM_C_TEXTURE);
|
||||
vramSetBankD(VRAM_D_TEXTURE);
|
||||
vramSetBankE(VRAM_E_TEX_PALETTE);
|
||||
vramSetBankF(VRAM_F_LCD);
|
||||
// vramSetBankG(VRAM_G_TEX_PALETTE);
|
||||
|
||||
// Initialize the 3D engine
|
||||
glInit();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glViewport(0, 0, 255, 191); // Set viewport
|
||||
glEnable(GL_ANTIALIAS);
|
||||
glClearColor(0, 0, 0, 31); // Set clear color (black)
|
||||
glClearPolyID(63); // Set default polygon ID
|
||||
glClearDepth(GL_MAX_DEPTH); // Set clear depth
|
||||
glViewport(0, 0, 255, 191); // Set viewport
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
vramSetBankA(VRAM_A_TEXTURE); // Allocate VRAM for textures
|
||||
vramSetBankB(VRAM_B_LCD);
|
||||
|
||||
// Debug
|
||||
consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 23, 2, false, true);
|
||||
consoleDemoInit();
|
||||
}
|
||||
|
@ -4,20 +4,20 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// Static members
|
||||
u32 Input::KeysHeldState = 0;
|
||||
u32 Input::KeysDownState = 0;
|
||||
u32 Input::KeysUpState = 0;
|
||||
u32 Input::ButtonsHeldState = 0;
|
||||
u32 Input::ButtonsDownState = 0;
|
||||
u32 Input::ButtonsUpState = 0;
|
||||
|
||||
void Input::Update() {
|
||||
// Update key states
|
||||
scanKeys();
|
||||
KeysHeldState = keysHeld();
|
||||
KeysDownState = keysDown();
|
||||
KeysUpState = keysUp();
|
||||
ButtonsHeldState = keysHeld();
|
||||
ButtonsDownState = keysDown();
|
||||
ButtonsUpState = keysUp();
|
||||
}
|
||||
|
||||
bool Input::IsKeyHeld(EKey key) { return KeysHeldState & key; }
|
||||
bool Input::IsButtonHeld(EButton key) { return ButtonsHeldState & key; }
|
||||
|
||||
bool Input::IsKeyDown(EKey key) { return KeysDownState & key; }
|
||||
bool Input::IsButtonDown(EButton key) { return ButtonsDownState & key; }
|
||||
|
||||
bool Input::IsKeyUp(EKey key) { return KeysUpState & key; }
|
||||
bool Input::IsButtonUp(EButton key) { return ButtonsUpState & key; }
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include "resources/mesh.h"
|
||||
|
||||
Mesh Mesh::Load(const TVector<TVector<FVertex>> &vertices) {
|
||||
return std::move(Mesh(vertices));
|
||||
Mesh Mesh::Load(const TVector<FShape> &shapes,
|
||||
const TVector<FMaterial> &materials,
|
||||
const TVector<PtrShr<Texture>> &textures) {
|
||||
return std::move(Mesh(shapes, materials, textures));
|
||||
}
|
||||
|
||||
Mesh::Mesh(const TVector<TVector<FVertex>> &vertices)
|
||||
: Super(), vertices(vertices) {}
|
||||
Mesh::Mesh(const TVector<FShape> &shapes, const TVector<FMaterial> &materials,
|
||||
const TVector<PtrShr<Texture>> &textures)
|
||||
: Super(), shapes(shapes), materials(materials), textures(textures) {}
|
27
engine/resources/texture.cpp
Normal file
27
engine/resources/texture.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "resources/texture.h"
|
||||
|
||||
#include <nds/arm9/videoGL.h>
|
||||
|
||||
Texture::~Texture() {
|
||||
// TODO: Check what the hell is happening here
|
||||
// glBindTexture(0, id);
|
||||
// glColorTableEXT(0, 0, 0, 0, 0, nullptr);
|
||||
// glDeleteTextures(1, &id);
|
||||
|
||||
// iprintf("Texture %d deleted\n", id);
|
||||
}
|
||||
|
||||
Texture Texture::Load(TVector<unsigned int> &data,
|
||||
TVector<unsigned short> &palette) {
|
||||
return Texture(data, palette);
|
||||
}
|
||||
|
||||
Texture::Texture(TVector<unsigned int> &data, TVector<unsigned short> &palette)
|
||||
: Super() {
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(0, id);
|
||||
// TODO: Manage different texture formats
|
||||
glTexImage2D(0, 0, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
|
||||
TEXGEN_TEXCOORD, (u8 *)data.data());
|
||||
// glColorTableEXT(0, 0, 32, 0, 0, (u16 *)palette.data());
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "tiny_obj_loader.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace Utils::File {
|
||||
|
||||
@ -11,15 +12,13 @@ FString ReadTextFile(const FString &path) {
|
||||
FString result;
|
||||
FILE *f = fopen(AssetPath(path).c_str(), "rb");
|
||||
if (!f) {
|
||||
iprintf("No se pudo abrir el archivo\n");
|
||||
// TODO: iprintf("No se pudo abrir el archivo\n");
|
||||
} else {
|
||||
iprintf("Archivo abierto\n");
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t size = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
TVector<uint8_t> buffer(size);
|
||||
TVector<u8> buffer(size);
|
||||
fread(buffer.data(), 1, size, f);
|
||||
fclose(f);
|
||||
|
||||
@ -30,28 +29,29 @@ FString ReadTextFile(const FString &path) {
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
TVector<TVector<FVertex>> ReadObjFile(const FString &path) {
|
||||
TTuple<TVector<FShape>, TVector<FMaterial>> ReadObjFile(const FString &path) {
|
||||
FString nitroPath = AssetPath(path);
|
||||
FString baseFolder =
|
||||
nitroPath.substr(0, nitroPath.find_last_of("/")).append("/");
|
||||
|
||||
tinyobj::attrib_t attrib;
|
||||
TVector<tinyobj::shape_t> shapes;
|
||||
TVector<tinyobj::material_t> materials;
|
||||
FString err;
|
||||
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err,
|
||||
AssetPath(path).c_str(),
|
||||
AssetPath(path + "/..").c_str(), true);
|
||||
nitroPath.c_str(), baseFolder.c_str(), true);
|
||||
|
||||
if (ret)
|
||||
iprintf("Cargado correctamente\n");
|
||||
else
|
||||
iprintf("Error al cargar el archivo: %s\n", err.c_str());
|
||||
if (!ret) {
|
||||
// TODO: print error
|
||||
return {TVector<FShape>(), TVector<FMaterial>()};
|
||||
}
|
||||
|
||||
iprintf("Numero de materiales: %d\n", materials.size());
|
||||
|
||||
TVector<TVector<FVertex>> vertices;
|
||||
TVector<FShape> shape_vertices;
|
||||
|
||||
// Loop over shapes
|
||||
for (size_t s = 0; s < shapes.size(); s++) {
|
||||
vertices.push_back({});
|
||||
shape_vertices.push_back({});
|
||||
// Loop over faces(polygon)
|
||||
size_t index_offset = 0;
|
||||
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||
@ -88,20 +88,23 @@ TVector<TVector<FVertex>> ReadObjFile(const FString &path) {
|
||||
tinyobj::real_t ty =
|
||||
attrib.texcoords[2 * size_t(idx.texcoord_index) + 1];
|
||||
|
||||
// I lost 3 days bacause of this :')
|
||||
ty = 1.0f - std::clamp(ty, 0.0f, 1.0f);
|
||||
|
||||
texCoords = FVector2(tx, ty);
|
||||
}
|
||||
|
||||
vertices[s].push_back(FVertex(positions, normals, texCoords));
|
||||
shape_vertices[s].vertices.push_back(
|
||||
FVertex(positions, normals, texCoords));
|
||||
}
|
||||
|
||||
index_offset += fv;
|
||||
|
||||
// per-face material
|
||||
// shapes[s].mesh.material_ids[f];
|
||||
// shape_materials.push_back(materials[shapes[s].mesh.material_ids[f]]);
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(vertices);
|
||||
return {shape_vertices, materials};
|
||||
}
|
||||
|
||||
} // namespace Utils::File
|
||||
|
@ -23,6 +23,7 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// xrbDS 0.1 : Change TINYOBJ_SSCANF_BUFFER_SIZE to 512
|
||||
// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124)
|
||||
// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43)
|
||||
// version 1.0.4 : Support multiple filenames for 'mtllib'(#112)
|
||||
@ -98,11 +99,11 @@ namespace tinyobj {
|
||||
// cube_left | cube_right
|
||||
|
||||
#ifdef TINYOBJLOADER_USE_DOUBLE
|
||||
//#pragma message "using double"
|
||||
typedef double real_t;
|
||||
// #pragma message "using double"
|
||||
typedef double real_t;
|
||||
#else
|
||||
//#pragma message "using float"
|
||||
typedef float real_t;
|
||||
// #pragma message "using float"
|
||||
typedef float real_t;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
@ -254,18 +255,12 @@ typedef struct callback_t_ {
|
||||
void (*object_cb)(void *user_data, const char *name);
|
||||
|
||||
callback_t_()
|
||||
: vertex_cb(NULL),
|
||||
normal_cb(NULL),
|
||||
texcoord_cb(NULL),
|
||||
index_cb(NULL),
|
||||
usemtl_cb(NULL),
|
||||
mtllib_cb(NULL),
|
||||
group_cb(NULL),
|
||||
object_cb(NULL) {}
|
||||
: vertex_cb(NULL), normal_cb(NULL), texcoord_cb(NULL), index_cb(NULL),
|
||||
usemtl_cb(NULL), mtllib_cb(NULL), group_cb(NULL), object_cb(NULL) {}
|
||||
} callback_t;
|
||||
|
||||
class MaterialReader {
|
||||
public:
|
||||
public:
|
||||
MaterialReader() {}
|
||||
virtual ~MaterialReader();
|
||||
|
||||
@ -276,7 +271,7 @@ class MaterialReader {
|
||||
};
|
||||
|
||||
class MaterialFileReader : public MaterialReader {
|
||||
public:
|
||||
public:
|
||||
explicit MaterialFileReader(const std::string &mtl_basedir)
|
||||
: m_mtlBaseDir(mtl_basedir) {}
|
||||
virtual ~MaterialFileReader() {}
|
||||
@ -284,12 +279,12 @@ class MaterialFileReader : public MaterialReader {
|
||||
std::vector<material_t> *materials,
|
||||
std::map<std::string, int> *matMap, std::string *err);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string m_mtlBaseDir;
|
||||
};
|
||||
|
||||
class MaterialStreamReader : public MaterialReader {
|
||||
public:
|
||||
public:
|
||||
explicit MaterialStreamReader(std::istream &inStream)
|
||||
: m_inStream(inStream) {}
|
||||
virtual ~MaterialStreamReader() {}
|
||||
@ -297,7 +292,7 @@ class MaterialStreamReader : public MaterialReader {
|
||||
std::vector<material_t> *materials,
|
||||
std::map<std::string, int> *matMap, std::string *err);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::istream &m_inStream;
|
||||
};
|
||||
|
||||
@ -361,7 +356,7 @@ namespace tinyobj {
|
||||
|
||||
MaterialReader::~MaterialReader() {}
|
||||
|
||||
#define TINYOBJ_SSCANF_BUFFER_SIZE (4096)
|
||||
#define TINYOBJ_SSCANF_BUFFER_SIZE (512)
|
||||
|
||||
struct vertex_index {
|
||||
int v_idx, vt_idx, vn_idx;
|
||||
@ -404,11 +399,13 @@ static std::istream &safeGetline(std::istream &is, std::string &t) {
|
||||
case '\n':
|
||||
return is;
|
||||
case '\r':
|
||||
if (sb->sgetc() == '\n') sb->sbumpc();
|
||||
if (sb->sgetc() == '\n')
|
||||
sb->sbumpc();
|
||||
return is;
|
||||
case EOF:
|
||||
// Also handle the case when the last line has no line ending
|
||||
if (t.empty()) is.setstate(std::ios::eofbit);
|
||||
if (t.empty())
|
||||
is.setstate(std::ios::eofbit);
|
||||
return is;
|
||||
default:
|
||||
t += static_cast<char>(c);
|
||||
@ -423,8 +420,10 @@ static std::istream &safeGetline(std::istream &is, std::string &t) {
|
||||
|
||||
// Make index zero-base, and also support relative index.
|
||||
static inline int fixIndex(int idx, int n) {
|
||||
if (idx > 0) return idx - 1;
|
||||
if (idx == 0) return 0;
|
||||
if (idx > 0)
|
||||
return idx - 1;
|
||||
if (idx == 0)
|
||||
return 0;
|
||||
return n + idx; // negative value = relative
|
||||
}
|
||||
|
||||
@ -521,9 +520,11 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
||||
}
|
||||
|
||||
// We must make sure we actually got something.
|
||||
if (read == 0) goto fail;
|
||||
if (read == 0)
|
||||
goto fail;
|
||||
// We allow numbers of form "#", "###" etc.
|
||||
if (!end_not_reached) goto assemble;
|
||||
if (!end_not_reached)
|
||||
goto assemble;
|
||||
|
||||
// Read the decimal part.
|
||||
if (*curr == '.') {
|
||||
@ -548,7 +549,8 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
||||
goto assemble;
|
||||
}
|
||||
|
||||
if (!end_not_reached) goto assemble;
|
||||
if (!end_not_reached)
|
||||
goto assemble;
|
||||
|
||||
// Read the exponent part.
|
||||
if (*curr == 'e' || *curr == 'E') {
|
||||
@ -574,13 +576,14 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
||||
end_not_reached = (curr != s_end);
|
||||
}
|
||||
exponent *= (exp_sign == '+' ? 1 : -1);
|
||||
if (read == 0) goto fail;
|
||||
if (read == 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
assemble:
|
||||
*result =
|
||||
(sign == '+' ? 1 : -1) *
|
||||
(exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) : mantissa);
|
||||
*result = (sign == '+' ? 1 : -1) *
|
||||
(exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent)
|
||||
: mantissa);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
@ -603,8 +606,8 @@ static inline void parseReal2(real_t *x, real_t *y, const char **token,
|
||||
(*y) = parseReal(token, default_y);
|
||||
}
|
||||
|
||||
static inline void parseReal3(real_t *x, real_t *y, real_t *z, const char **token,
|
||||
const double default_x = 0.0,
|
||||
static inline void parseReal3(real_t *x, real_t *y, real_t *z,
|
||||
const char **token, const double default_x = 0.0,
|
||||
const double default_y = 0.0,
|
||||
const double default_z = 0.0) {
|
||||
(*x) = parseReal(token, default_x);
|
||||
@ -638,8 +641,9 @@ static inline bool parseOnOff(const char **token, bool default_value = true) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline texture_type_t parseTextureType(
|
||||
const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) {
|
||||
static inline texture_type_t
|
||||
parseTextureType(const char **token,
|
||||
texture_type_t default_value = TEXTURE_TYPE_NONE) {
|
||||
(*token) += strspn((*token), " \t");
|
||||
const char *end = (*token) + strcspn((*token), " \t\r");
|
||||
texture_type_t ty = default_value;
|
||||
@ -887,8 +891,9 @@ static void InitMaterial(material_t *material) {
|
||||
material->unknown_parameter.clear();
|
||||
}
|
||||
|
||||
static bool exportFaceGroupToShape(
|
||||
shape_t *shape, const std::vector<std::vector<vertex_index> > &faceGroup,
|
||||
static bool
|
||||
exportFaceGroupToShape(shape_t *shape,
|
||||
const std::vector<std::vector<vertex_index>> &faceGroup,
|
||||
const std::vector<tag_t> &tags, const int material_id,
|
||||
const std::string &name, bool triangulate) {
|
||||
if (faceGroup.empty()) {
|
||||
@ -1004,9 +1009,11 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
token += strspn(token, " \t");
|
||||
|
||||
assert(token);
|
||||
if (token[0] == '\0') continue; // empty line
|
||||
if (token[0] == '\0')
|
||||
continue; // empty line
|
||||
|
||||
if (token[0] == '#') continue; // comment line
|
||||
if (token[0] == '#')
|
||||
continue; // comment line
|
||||
|
||||
// new mtl
|
||||
if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) {
|
||||
@ -1431,7 +1438,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
std::vector<real_t> vn;
|
||||
std::vector<real_t> vt;
|
||||
std::vector<tag_t> tags;
|
||||
std::vector<std::vector<vertex_index> > faceGroup;
|
||||
std::vector<std::vector<vertex_index>> faceGroup;
|
||||
std::string name;
|
||||
|
||||
// material
|
||||
@ -1464,9 +1471,11 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
token += strspn(token, " \t");
|
||||
|
||||
assert(token);
|
||||
if (token[0] == '\0') continue; // empty line
|
||||
if (token[0] == '\0')
|
||||
continue; // empty line
|
||||
|
||||
if (token[0] == '#') continue; // comment line
|
||||
if (token[0] == '#')
|
||||
continue; // comment line
|
||||
|
||||
// vertex
|
||||
if (token[0] == 'v' && IS_SPACE((token[1]))) {
|
||||
@ -1564,8 +1573,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
|
||||
if (filenames.empty()) {
|
||||
if (err) {
|
||||
(*err) +=
|
||||
"WARN: Looks like empty filename for mtllib. Use default "
|
||||
(*err) += "WARN: Looks like empty filename for mtllib. Use default "
|
||||
"material. \n";
|
||||
}
|
||||
} else {
|
||||
@ -1586,8 +1594,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
|
||||
if (!found) {
|
||||
if (err) {
|
||||
(*err) +=
|
||||
"WARN: Failed to load material file(s). Use default "
|
||||
(*err) += "WARN: Failed to load material file(s). Use default "
|
||||
"material.\n";
|
||||
}
|
||||
}
|
||||
@ -1770,9 +1777,11 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
||||
token += strspn(token, " \t");
|
||||
|
||||
assert(token);
|
||||
if (token[0] == '\0') continue; // empty line
|
||||
if (token[0] == '\0')
|
||||
continue; // empty line
|
||||
|
||||
if (token[0] == '#') continue; // comment line
|
||||
if (token[0] == '#')
|
||||
continue; // comment line
|
||||
|
||||
// vertex
|
||||
if (token[0] == 'v' && IS_SPACE((token[1]))) {
|
||||
@ -1873,8 +1882,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
||||
|
||||
if (filenames.empty()) {
|
||||
if (err) {
|
||||
(*err) +=
|
||||
"WARN: Looks like empty filename for mtllib. Use default "
|
||||
(*err) += "WARN: Looks like empty filename for mtllib. Use default "
|
||||
"material. \n";
|
||||
}
|
||||
} else {
|
||||
@ -1895,8 +1903,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
||||
|
||||
if (!found) {
|
||||
if (err) {
|
||||
(*err) +=
|
||||
"WARN: Failed to load material file(s). Use default "
|
||||
(*err) += "WARN: Failed to load material file(s). Use default "
|
||||
"material.\n";
|
||||
}
|
||||
} else {
|
||||
|
@ -19,9 +19,11 @@
|
||||
#include <bits/unique_ptr.h>
|
||||
#include <bits/shared_ptr.h>
|
||||
#include <calico/types.h>
|
||||
#include <tiny_obj_loader.h>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
/////////////////////////////////////
|
||||
// MEMORY
|
||||
@ -71,6 +73,17 @@ template <typename T> using TVector = std::vector<T>;
|
||||
* @tparam S The size of the array.
|
||||
*/
|
||||
template <typename T, size_t S> using TArray = std::array<T, S>;
|
||||
/**
|
||||
* @brief Alias template for creating a std::tuple with a variadic list of
|
||||
* types.
|
||||
*
|
||||
* This alias simplifies the usage of std::tuple by allowing the user to write
|
||||
* TTuple<T...> instead of std::tuple<T...>.
|
||||
*
|
||||
* @tparam T... Variadic template parameter pack representing the types to be
|
||||
* included in the tuple.
|
||||
*/
|
||||
template <typename... T> using TTuple = std::tuple<T...>;
|
||||
|
||||
/////////////////////////////////////
|
||||
// BASIC TYPES
|
||||
@ -141,4 +154,10 @@ using FVector3 = glm::vec3;
|
||||
*/
|
||||
using FVector3Int = glm::ivec3;
|
||||
|
||||
/////////////////////////////////////
|
||||
// SHAPES
|
||||
/////////////////////////////////////
|
||||
|
||||
using FMaterial = tinyobj::material_t;
|
||||
|
||||
#endif // XRBDS_CORE_TYPES_H
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* This header defines the Input class, which provides static methods to query
|
||||
* the state of keys (held, pressed, or released) on the system. It also defines
|
||||
* the EKey enumeration for representing individual keys.
|
||||
* the EButton enumeration for representing individual keys.
|
||||
*
|
||||
* The Input class is designed as a utility class and cannot be instantiated.
|
||||
* It maintains internal states for keys and provides methods to update and
|
||||
@ -14,8 +14,8 @@
|
||||
*
|
||||
* Usage:
|
||||
* - Call Input::Update() periodically to refresh the key states.
|
||||
* - Use Input::IsKeyHeld(), Input::IsKeyDown(), or Input::IsKeyUp() to query
|
||||
* the state of specific keys.
|
||||
* - Use Input::IsButtonHeld(), Input::IsButtonDown(), or Input::IsButtonUp() to
|
||||
* query the state of specific keys.
|
||||
*
|
||||
* @author Daniel Ramirez Morilla
|
||||
* @date 2025-04-19
|
||||
@ -33,7 +33,7 @@
|
||||
#include <nds/input.h>
|
||||
|
||||
/**
|
||||
* @enum EKey
|
||||
* @enum EButton
|
||||
* @brief Represents the keys available on the NDS platform.
|
||||
*
|
||||
* This enumeration defines constants for each key on the NDS system, mapping
|
||||
@ -44,7 +44,7 @@
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* if (Input::IsKeyDown(EKey::A)) {
|
||||
* if (Input::IsButtonDown(EButton::A)) {
|
||||
* // Handle A button press
|
||||
* }
|
||||
* @endcode
|
||||
@ -52,7 +52,7 @@
|
||||
* @note These key codes are specific to the NDS platform and rely on the
|
||||
* platform's key definitions.
|
||||
*/
|
||||
enum EKey : u16 {
|
||||
enum EButton : u16 {
|
||||
A = KEY_A,
|
||||
B = KEY_B,
|
||||
X = KEY_X,
|
||||
@ -70,9 +70,9 @@ enum EKey : u16 {
|
||||
|
||||
/**
|
||||
* @class Input
|
||||
* @brief Provides static methods to handle input states for keys.
|
||||
* @brief Provides static methods to handle input states for buttons.
|
||||
*
|
||||
* The Input class is a utility class that allows querying the state of keys
|
||||
* The Input class is a utility class that allows querying the state of buttons
|
||||
* (held, pressed, or released) using static methods. It is not meant to be
|
||||
* instantiated.
|
||||
*/
|
||||
@ -81,46 +81,47 @@ public:
|
||||
/**
|
||||
* @brief Updates the internal state of the input system.
|
||||
*
|
||||
* This method should be called periodically to refresh the key states.
|
||||
* This method should be called periodically to refresh the button states.
|
||||
*/
|
||||
static void Update();
|
||||
|
||||
/**
|
||||
* @brief Checks if a specific key is currently being held down.
|
||||
* @param key The key to check.
|
||||
* @return True if the key is held down, false otherwise.
|
||||
* @brief Checks if a specific button is currently being held down.
|
||||
* @param button The button to check.
|
||||
* @return True if the button is held down, false otherwise.
|
||||
*/
|
||||
static bool IsKeyHeld(EKey key);
|
||||
static bool IsButtonHeld(EButton button);
|
||||
|
||||
/**
|
||||
* @brief Checks if a specific key was pressed in the current update cycle.
|
||||
* @param key The key to check.
|
||||
* @return True if the key was pressed, false otherwise.
|
||||
* @brief Checks if a specific button was pressed in the current update cycle.
|
||||
* @param button The button to check.
|
||||
* @return True if the button was pressed, false otherwise.
|
||||
*/
|
||||
static bool IsKeyDown(EKey key);
|
||||
static bool IsButtonDown(EButton button);
|
||||
|
||||
/**
|
||||
* @brief Checks if a specific key was released in the current update cycle.
|
||||
* @param key The key to check.
|
||||
* @return True if the key was released, false otherwise.
|
||||
* @brief Checks if a specific button was released in the current update
|
||||
* cycle.
|
||||
* @param button The button to check.
|
||||
* @return True if the button was released, false otherwise.
|
||||
*/
|
||||
static bool IsKeyUp(EKey key);
|
||||
static bool IsButtonUp(EButton button);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Stores the state of keys currently being held down.
|
||||
* @brief Stores the state of buttons currently being held down.
|
||||
*/
|
||||
static u32 KeysHeldState;
|
||||
static u32 ButtonsHeldState;
|
||||
|
||||
/**
|
||||
* @brief Stores the state of keys pressed in the current update cycle.
|
||||
* @brief Stores the state of buttons pressed in the current update cycle.
|
||||
*/
|
||||
static u32 KeysDownState;
|
||||
static u32 ButtonsDownState;
|
||||
|
||||
/**
|
||||
* @brief Stores the state of keys released in the current update cycle.
|
||||
* @brief Stores the state of buttons released in the current update cycle.
|
||||
*/
|
||||
static u32 KeysUpState;
|
||||
static u32 ButtonsUpState;
|
||||
|
||||
/**
|
||||
* @brief Deleted constructor to prevent instantiation of the Input class.
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "resource.h"
|
||||
#include "core/types.h"
|
||||
#include "resources/texture.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -15,19 +16,30 @@ struct FVertex {
|
||||
: position(pos), normal(norm), texCoords(tex) {}
|
||||
};
|
||||
|
||||
struct FShape {
|
||||
TVector<FVertex> vertices;
|
||||
};
|
||||
|
||||
class Mesh : public Resource {
|
||||
using Super = Resource;
|
||||
|
||||
public:
|
||||
static Mesh Load(const TVector<TVector<FVertex>> &vertices);
|
||||
static Mesh Load(const TVector<FShape> &shapes,
|
||||
const TVector<FMaterial> &materials,
|
||||
const TVector<PtrShr<Texture>> &textures);
|
||||
|
||||
TVector<TVector<FVertex>> getVertices() const { return vertices; }
|
||||
const TVector<FShape> &getShapes() const { return shapes; }
|
||||
const TVector<FMaterial> &getMaterials() const { return materials; }
|
||||
const TVector<PtrShr<Texture>> &getTextures() const { return textures; }
|
||||
|
||||
private:
|
||||
TVector<TVector<FVertex>> vertices;
|
||||
TVector<FShape> shapes;
|
||||
TVector<FMaterial> materials;
|
||||
TVector<PtrShr<Texture>> textures;
|
||||
|
||||
Mesh() = default;
|
||||
Mesh(const TVector<TVector<FVertex>> &vertices);
|
||||
Mesh(const TVector<FShape> &shapes, const TVector<FMaterial> &materials,
|
||||
const TVector<PtrShr<Texture>> &textures);
|
||||
};
|
||||
|
||||
#endif // XRBDS_RESOURCES_MESH_H
|
46
include/xrbds/resources/texture.h
Normal file
46
include/xrbds/resources/texture.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef XRBDS_RESOURCES_TEXTURE_H
|
||||
#define XRBDS_RESOURCES_TEXTURE_H
|
||||
|
||||
#include "resource.h"
|
||||
#include "core/types.h"
|
||||
|
||||
/**
|
||||
* @class Texture
|
||||
* @brief Represents a texture resource that includes pixel data and a color
|
||||
* palette.
|
||||
*
|
||||
* The Texture class is derived from the Resource class and provides
|
||||
* functionality to load and manage texture data and its associated palette. It
|
||||
* also provides access to the texture's unique identifier.
|
||||
*/
|
||||
class Texture : public Resource {
|
||||
using Super = Resource;
|
||||
|
||||
public:
|
||||
virtual ~Texture();
|
||||
|
||||
/**
|
||||
* @brief Loads a texture from the given pixel data and palette.
|
||||
*
|
||||
* @param data A reference to a vector containing the texture's pixel data.
|
||||
* @param palette A reference to a vector containing the texture's color
|
||||
* palette.
|
||||
* @return A Texture object initialized with the provided data and palette.
|
||||
*/
|
||||
static Texture Load(TVector<unsigned int> &data,
|
||||
TVector<unsigned short> &palette);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the unique identifier of the texture.
|
||||
*
|
||||
* @return The unique identifier of the texture as an unsigned 8-bit integer.
|
||||
*/
|
||||
const u8 getId() { return id; }
|
||||
|
||||
private:
|
||||
Texture(TVector<unsigned int> &data, TVector<unsigned short> &palette);
|
||||
|
||||
int id;
|
||||
};
|
||||
|
||||
#endif // XRBDS_RESOURCES_TEXTURE_H
|
@ -4,8 +4,14 @@
|
||||
#include "core/types.h"
|
||||
#include "resources/mesh.h"
|
||||
|
||||
struct FObjData {
|
||||
TVector<TVector<FVertex>> vertices;
|
||||
};
|
||||
|
||||
namespace Utils::File {
|
||||
|
||||
FString AssetPath(const FString &path);
|
||||
|
||||
/**
|
||||
* @brief Reads the contents of a text file and returns it as a string.
|
||||
*
|
||||
@ -20,13 +26,38 @@ FString ReadTextFile(const FString &path);
|
||||
* vector of vertices.
|
||||
*
|
||||
* @param path The file path to the OBJ file as an FString.
|
||||
* @return A TVector of TVector of FVertex, where each inner vector represents a
|
||||
* group of vertices.
|
||||
* @return A TVector of TVector of FVertex, where each inner vector represents
|
||||
* a group of vertices.
|
||||
*
|
||||
* @note Ensure the file at the specified path exists and is in a valid OBJ
|
||||
* format.
|
||||
*/
|
||||
TVector<TVector<FVertex>> ReadObjFile(const FString &path);
|
||||
TTuple<TVector<FShape>, TVector<FMaterial>> ReadObjFile(const FString &path);
|
||||
|
||||
/**
|
||||
* @brief Reads a binary file and returns its contents as a TVector of type T.
|
||||
*
|
||||
* @tparam T The type of data to read from the binary file.
|
||||
* @param path The file path to the binary file to be read.
|
||||
* @return TVector<T> A vector containing the contents of the binary file.
|
||||
*/
|
||||
template <typename T> TVector<T> ReadBinaryFile(const FString &path) {
|
||||
FILE *file = fopen(AssetPath(path).c_str(), "rb");
|
||||
if (!file) {
|
||||
// TODO: iprintf("Error abriendo: %s\n", path.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
TVector<T> buffer(size);
|
||||
fread(buffer.data(), 1, size, file);
|
||||
fclose(file);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
} // namespace Utils::File
|
||||
|
||||
|
98
samples/hello_world/assets/meshes/cube/cube-tex.obj
Normal file
98
samples/hello_world/assets/meshes/cube/cube-tex.obj
Normal file
@ -0,0 +1,98 @@
|
||||
# cube-tex.obj
|
||||
# Import into Blender with Y-forward, Z-up
|
||||
#
|
||||
# Vertices: Faces:
|
||||
# f-------g +-------+
|
||||
# /. /| /. 5 /| 3 back
|
||||
# / . / | / . / |
|
||||
# e-------h | 2 +-------+ 1|
|
||||
# | b . .|. c z right | . . .|. +
|
||||
# | . | / | /y | . 4 | /
|
||||
# |. |/ |/ |. |/
|
||||
# a-------d +---- x +-------+
|
||||
# 6
|
||||
# bottom
|
||||
|
||||
# Material defined in separate file.
|
||||
mtllib cube.mtl
|
||||
|
||||
g cube
|
||||
|
||||
# Vertices
|
||||
v 0.0 0.0 0.0 # 1 a
|
||||
v 0.0 1.0 0.0 # 2 b
|
||||
v 1.0 1.0 0.0 # 3 c
|
||||
v 1.0 0.0 0.0 # 4 d
|
||||
v 0.0 0.0 1.0 # 5 e
|
||||
v 0.0 1.0 1.0 # 6 f
|
||||
v 1.0 1.0 1.0 # 7 g
|
||||
v 1.0 0.0 1.0 # 8 h
|
||||
|
||||
# Normal vectors
|
||||
# One for each face. Shared by all vertices in that face.
|
||||
vn 1.0 0.0 0.0 # 1 cghd
|
||||
vn -1.0 0.0 0.0 # 2 aefb
|
||||
vn 0.0 1.0 0.0 # 3 gcbf
|
||||
vn 0.0 -1.0 0.0 # 4 dhea
|
||||
vn 0.0 0.0 1.0 # 5 hgfe
|
||||
vn 0.0 0.0 -1.0 # 6 cdab
|
||||
|
||||
# Texture
|
||||
# (u,v) coordinate into texture map image, ranging from 0.0 - 1.0.
|
||||
# +---f---g---+---+
|
||||
# | | 5 | | |
|
||||
# f---e---h---g---+
|
||||
# | 2 | 4 | 1 | | v
|
||||
# b---a---d---c---+ |
|
||||
# | | 6 | | | |
|
||||
# +---b---c---+---+ +---- u
|
||||
# | | 3 | | |
|
||||
# +---f---g---+---+
|
||||
vt 0.25 1.00 # 1 f(5) = f for face 5
|
||||
vt 0.50 1.00 # 2 g(5)
|
||||
vt 0 0.75 # 3 f(2)
|
||||
vt 0.25 0.75 # 4 e(2,4,5)
|
||||
vt 0.50 0.75 # 5 h(1,4,5)
|
||||
vt 0.75 0.75 # 6 g(1)
|
||||
vt 0 0.50 # 7 b(2)
|
||||
vt 0.25 0.50 # 8 a(2,4,6)
|
||||
vt 0.50 0.50 # 9 d(1,4,6)
|
||||
vt 0.75 0.50 # 10 c(1)
|
||||
vt 0.25 0.25 # 11 b(3,6)
|
||||
vt 0.50 0.25 # 12 c(3,6)
|
||||
vt 0.25 0 # 13 f(3)
|
||||
vt 0.50 0 # 14 g(3)
|
||||
|
||||
# Define material for the following faces
|
||||
usemtl texture
|
||||
|
||||
# Faces v/vt/vn
|
||||
# 3-------2
|
||||
# | - |
|
||||
# | # | Each face = 2 triangles (ccw)
|
||||
# | - | = 1-2-3 + 1-3-4
|
||||
# 4-------1
|
||||
|
||||
# Face 1: cghd = cgh + chd
|
||||
f 3/10/1 7/6/1 8/5/1
|
||||
f 3/10/1 8/5/1 4/9/1
|
||||
|
||||
# Face 2: aefb = aef + afb
|
||||
f 1/8/2 5/4/2 6/3/2
|
||||
f 1/8/2 6/3/2 2/7/2
|
||||
|
||||
# Face 3: gcbf = gcb + gbf
|
||||
f 7/14/3 3/12/3 2/11/3
|
||||
f 7/14/3 2/11/3 6/13/3
|
||||
|
||||
# Face 4: dhea = dhe + dea
|
||||
f 4/9/4 8/5/4 5/4/4
|
||||
f 4/9/4 5/4/4 1/8/4
|
||||
|
||||
# Face 5: hgfe = hgf + hfe
|
||||
f 8/5/5 7/2/5 6/1/5
|
||||
f 8/5/5 6/1/5 5/4/5
|
||||
|
||||
# Face 6: cdab = cda + cab
|
||||
f 3/12/6 4/9/6 1/8/6
|
||||
f 3/12/6 1/8/6 2/11/6
|
7
samples/hello_world/assets/meshes/cube/cube.mtl
Normal file
7
samples/hello_world/assets/meshes/cube/cube.mtl
Normal file
@ -0,0 +1,7 @@
|
||||
newmtl texture
|
||||
Ka 0.0 0.0 0.0
|
||||
Kd 0.5 0.5 0.5
|
||||
Ks 0.0 0.0 0.0
|
||||
Ns 10.0
|
||||
illum 2
|
||||
map_Kd texture.png
|
1
samples/hello_world/assets/meshes/cube/texture.img.bin
Normal file
1
samples/hello_world/assets/meshes/cube/texture.img.bin
Normal file
File diff suppressed because one or more lines are too long
BIN
samples/hello_world/assets/meshes/cube/texture.png
Normal file
BIN
samples/hello_world/assets/meshes/cube/texture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
6
samples/hello_world/assets/meshes/mococo/ATTRIBUTION.txt
Normal file
6
samples/hello_world/assets/meshes/mococo/ATTRIBUTION.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Model: mococo.obj
|
||||
Author: pyr0xene
|
||||
License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
|
||||
Source: https://sketchfab.com/3d-models/mococo-2c53699f4fe647beb52a7926821f5d9c
|
||||
|
||||
This model is used under the terms of the Creative Commons Attribution-NonCommercial license.
|
@ -1,46 +0,0 @@
|
||||
# Blender v2.76 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -0.999999
|
||||
v 0.999999 1.000000 1.000001
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
vt 1.000000 0.333333
|
||||
vt 1.000000 0.666667
|
||||
vt 0.666667 0.666667
|
||||
vt 0.666667 0.333333
|
||||
vt 0.666667 0.000000
|
||||
vt 0.000000 0.333333
|
||||
vt 0.000000 0.000000
|
||||
vt 0.333333 0.000000
|
||||
vt 0.333333 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.666667
|
||||
vt 0.333333 0.333333
|
||||
vt 0.333333 0.666667
|
||||
vt 1.000000 0.000000
|
||||
vn 0.000000 -1.000000 0.000000
|
||||
vn 0.000000 1.000000 0.000000
|
||||
vn 1.000000 0.000000 0.000000
|
||||
vn -0.000000 0.000000 1.000000
|
||||
vn -1.000000 -0.000000 -0.000000
|
||||
vn 0.000000 0.000000 -1.000000
|
||||
usemtl Material
|
||||
s off
|
||||
f 2/1/1 3/2/1 4/3/1
|
||||
f 8/1/2 7/4/2 6/5/2
|
||||
f 5/6/3 6/7/3 2/8/3
|
||||
f 6/8/4 7/5/4 3/4/4
|
||||
f 3/9/5 7/10/5 8/11/5
|
||||
f 1/12/6 4/13/6 8/11/6
|
||||
f 1/4/1 2/1/1 4/3/1
|
||||
f 5/14/2 8/1/2 6/5/2
|
||||
f 1/12/3 5/6/3 2/8/3
|
||||
f 2/12/4 6/8/4 3/4/4
|
||||
f 4/13/5 3/9/5 8/11/5
|
||||
f 5/6/6 1/12/6 8/11/6
|
File diff suppressed because one or more lines are too long
BIN
samples/hello_world/assets/meshes/mococo/mococotexture_face1.png
Normal file
BIN
samples/hello_world/assets/meshes/mococo/mococotexture_face1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
Before Width: | Height: | Size: 34 KiB |
7
samples/hello_world/assets/meshes/quad/quad.mtl
Normal file
7
samples/hello_world/assets/meshes/quad/quad.mtl
Normal file
@ -0,0 +1,7 @@
|
||||
newmtl texture
|
||||
Ka 0.0 0.0 0.0
|
||||
Kd 0.5 0.5 0.5
|
||||
Ks 0.0 0.0 0.0
|
||||
Ns 10.0
|
||||
illum 2
|
||||
map_Kd texture.png
|
15
samples/hello_world/assets/meshes/quad/quad.obj
Normal file
15
samples/hello_world/assets/meshes/quad/quad.obj
Normal file
@ -0,0 +1,15 @@
|
||||
# Blender v2.57 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib quad.mtl
|
||||
o Cube_Cube.001
|
||||
v -1.000000 1.000000 0.000000
|
||||
v 1.000000 1.000000 0.000000
|
||||
v -1.000000 -1.000000 0.000000
|
||||
v 1.000000 -1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
s off
|
||||
f 4/4 3/3 1/2
|
||||
f 2/1 4/4 1/2
|
BIN
samples/hello_world/assets/meshes/quad/texture.img.bin
Normal file
BIN
samples/hello_world/assets/meshes/quad/texture.img.bin
Normal file
Binary file not shown.
BIN
samples/hello_world/assets/meshes/quad/texture.png
Normal file
BIN
samples/hello_world/assets/meshes/quad/texture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
Loading…
Reference in New Issue
Block a user