mirror of
https://github.com/danule222/xrbDS.git
synced 2025-06-18 14:25:33 -04:00
Implement .obj load & rendering
This commit is contained in:
parent
f7da063cfe
commit
6e0d5f92ea
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
build/*.obj
|
||||
*.elf
|
||||
*.lst
|
||||
*.nds
|
||||
|
@ -5,6 +5,7 @@ project(xrbDS)
|
||||
include_directories(
|
||||
engine
|
||||
include/xrbds
|
||||
include/tinyobjloader
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
|
||||
|
5
engine/components/component.cpp
Normal file
5
engine/components/component.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "components/component.h"
|
||||
|
||||
PtrUnq<Component> Component::Initialize() {
|
||||
return PtrUnq<Component>(new Component());
|
||||
}
|
15
engine/components/mesh_filter.cpp
Normal file
15
engine/components/mesh_filter.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "components/mesh_filter.h"
|
||||
|
||||
#include "resources/resource.h"
|
||||
#include "utils/file.h"
|
||||
|
||||
MeshFilter::MeshFilter(const FString &path) {
|
||||
// Load the mesh from the file
|
||||
auto vertices = Utils::File::ReadObjFile(path);
|
||||
|
||||
mesh = LoadResource<Mesh>(vertices);
|
||||
}
|
||||
|
||||
PtrUnq<MeshFilter> MeshFilter::Initialize(const FString &path) {
|
||||
return PtrUnq<MeshFilter>(new MeshFilter(path));
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
#include "graphics/renderer.h"
|
||||
#include "scene/3d/node_3d.h"
|
||||
#include "utils/file.h"
|
||||
#include "scene/3d/mesh_instance_3d.h"
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// Main function
|
||||
@ -43,24 +44,18 @@ PtrUnq<Engine> &Engine::GetInstance() {
|
||||
}
|
||||
|
||||
void Engine::run() {
|
||||
// Initialize the main loop
|
||||
// - VBlank IRQ
|
||||
irqSet(IRQ_VBLANK, Engine::VblankCallback);
|
||||
VblankCallback();
|
||||
|
||||
// TEST ------------------------
|
||||
|
||||
PtrShr<Node3D> node = NewNode<Node3D>();
|
||||
node->getComponent<Transform>()->position = {1.0f, 2.0f, 3.0f};
|
||||
|
||||
FString ahuevo = Utils::File::ReadTextFile("hola.txt");
|
||||
iprintf("ahuevo: %s\n", ahuevo.c_str());
|
||||
// Create a MeshInstance3D
|
||||
PtrShr<MeshInstance3D> meshInstance =
|
||||
NewNode<MeshInstance3D>("meshes/mococo/mococo.obj");
|
||||
|
||||
// -----------------------------
|
||||
|
||||
while (pmMainLoop()) {
|
||||
processInput();
|
||||
update();
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +65,22 @@ void Engine::update() {
|
||||
// Update
|
||||
}
|
||||
|
||||
void Engine::render() { Renderer::GetInstance()->render(); }
|
||||
void Engine::render() {
|
||||
if (!ComponentManager::GetInstance())
|
||||
return;
|
||||
PtrUnq<Renderer> &renderer = Renderer::GetInstance();
|
||||
|
||||
void Engine::VblankCallback() { Engine::GetInstance()->render(); }
|
||||
renderer->beginFrame();
|
||||
|
||||
auto view = ComponentManager::GetInstance()->view<Transform, MeshFilter>();
|
||||
for (auto &[entity, transform, meshFilter] : view) {
|
||||
renderer->render(*transform, *meshFilter);
|
||||
}
|
||||
|
||||
renderer->endFrame();
|
||||
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
Engine::Engine() {
|
||||
// Initialize nitroFS
|
||||
|
@ -1,30 +1,21 @@
|
||||
#include "renderer.h"
|
||||
|
||||
#include "core/types.h"
|
||||
#include "components/mesh_filter.h"
|
||||
#include "components/transform.h"
|
||||
#include "resources/mesh.h"
|
||||
#include <nds.h>
|
||||
#include <stdio.h>
|
||||
|
||||
std::unique_ptr<Renderer> Renderer::Instance;
|
||||
PtrUnq<Renderer> Renderer::Instance;
|
||||
|
||||
std::unique_ptr<Renderer> &Renderer::GetInstance() {
|
||||
PtrUnq<Renderer> &Renderer::GetInstance() {
|
||||
if (!Instance)
|
||||
Instance = std::unique_ptr<Renderer>(new Renderer());
|
||||
Instance = PtrUnq<Renderer>(new Renderer());
|
||||
|
||||
return Instance;
|
||||
}
|
||||
|
||||
void Renderer::render() {
|
||||
clearScreen(); // Clear the screen
|
||||
beginFrame(); // Prepare for rendering
|
||||
glLoadIdentity(); // Load the identity matrix
|
||||
|
||||
// Render scene
|
||||
glTranslatef(0.f, 0.f, -4.f); // Move the camera back
|
||||
glRotatef(45, 1, 1, 0); // Rotation
|
||||
drawCube(1.0f); // Draw a cube
|
||||
|
||||
endFrame(); // Finish rendering
|
||||
}
|
||||
|
||||
void Renderer::beginFrame() {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
@ -34,6 +25,30 @@ void Renderer::beginFrame() {
|
||||
glPushMatrix(); // Save the current matrix state
|
||||
|
||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
|
||||
|
||||
glLoadIdentity(); // Load the identity matrix
|
||||
|
||||
// Render scene
|
||||
glTranslatef(0.f, 0.f, -4.f); // Move the camera back
|
||||
glRotatef(45, 1, 1, 0); // Rotation
|
||||
}
|
||||
|
||||
void Renderer::render(const Transform &transform,
|
||||
const MeshFilter &meshFilter) {
|
||||
// drawCube(1.0f); // Draw a cube
|
||||
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);
|
||||
glTexCoord2f(vertex.texCoords.x, vertex.texCoords.y);
|
||||
}
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glPopMatrix(1);
|
||||
}
|
||||
|
||||
void Renderer::endFrame() {
|
||||
|
@ -23,8 +23,12 @@
|
||||
#ifndef RENDERER_H
|
||||
#define RENDERER_H
|
||||
|
||||
#include "core/types.h"
|
||||
#include <memory>
|
||||
|
||||
struct Transform;
|
||||
struct MeshFilter;
|
||||
|
||||
/**
|
||||
* @class Renderer
|
||||
* @brief A base class for rendering operations.
|
||||
@ -46,7 +50,14 @@ public:
|
||||
*
|
||||
* @return A unique pointer to a Renderer instance.
|
||||
*/
|
||||
static std::unique_ptr<Renderer> &GetInstance();
|
||||
static PtrUnq<Renderer> &GetInstance();
|
||||
|
||||
/**
|
||||
* @brief Prepares the renderer for a new frame.
|
||||
*
|
||||
* This method is called at the beginning of the rendering process.
|
||||
*/
|
||||
void beginFrame();
|
||||
|
||||
/**
|
||||
* @brief Renders the current frame.
|
||||
@ -54,15 +65,7 @@ public:
|
||||
* This method handles the rendering process, including frame management
|
||||
* and drawing operations.
|
||||
*/
|
||||
void render();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Prepares the renderer for a new frame.
|
||||
*
|
||||
* This method is called at the beginning of the rendering process.
|
||||
*/
|
||||
void beginFrame();
|
||||
void render(const Transform &transform, const MeshFilter &meshFilter);
|
||||
|
||||
/**
|
||||
* @brief Finalizes the rendering of the current frame.
|
||||
@ -71,14 +74,6 @@ private:
|
||||
*/
|
||||
void endFrame();
|
||||
|
||||
/**
|
||||
* @brief Clears the screen to prepare for rendering.
|
||||
*
|
||||
* This method resets the screen to a default state, typically clearing
|
||||
* any previous drawings.
|
||||
*/
|
||||
void clearScreen();
|
||||
|
||||
/**
|
||||
* @brief Draws a cube of the specified size.
|
||||
*
|
||||
@ -86,7 +81,16 @@ private:
|
||||
*/
|
||||
void drawCube(float size);
|
||||
|
||||
static std::unique_ptr<Renderer> Instance;
|
||||
private:
|
||||
static PtrUnq<Renderer> Instance;
|
||||
|
||||
/**
|
||||
* @brief Clears the screen to prepare for rendering.
|
||||
*
|
||||
* This method resets the screen to a default state, typically clearing
|
||||
* any previous drawings.
|
||||
*/
|
||||
void clearScreen();
|
||||
|
||||
/**
|
||||
* @brief Constructor for the Renderer class.
|
||||
|
@ -1 +1,8 @@
|
||||
#include "resources/mesh.h"
|
||||
#include "resources/mesh.h"
|
||||
|
||||
Mesh Mesh::Load(const TVector<TVector<FVertex>> &vertices) {
|
||||
return std::move(Mesh(vertices));
|
||||
}
|
||||
|
||||
Mesh::Mesh(const TVector<TVector<FVertex>> &vertices)
|
||||
: Super(), vertices(vertices) {}
|
@ -1,6 +1,3 @@
|
||||
#include "resources/resource.h"
|
||||
|
||||
Resource::Resource(const FString &name, const FString &path)
|
||||
: name(name), path(path) {
|
||||
// Constructor implementation
|
||||
}
|
||||
Resource Resource::Load() { return std::move(Resource()); }
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "components/mesh_filter.h"
|
||||
|
||||
MeshInstance3D::MeshInstance3D() {
|
||||
ComponentManager::GetInstance()->addComponent<MeshFilter>(id,
|
||||
MeshFilter("test"));
|
||||
MeshInstance3D::MeshInstance3D(const FString &path) {
|
||||
ComponentManager::GetInstance()->addComponent<MeshFilter>(
|
||||
id, *MeshFilter::Initialize(path));
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
#include "utils/file.h"
|
||||
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "tiny_obj_loader.h"
|
||||
|
||||
namespace Utils::File {
|
||||
|
||||
FString AssetPath(const FString &path) { return "nitro:/" + path; }
|
||||
@ -27,4 +30,78 @@ FString ReadTextFile(const FString &path) {
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
TVector<TVector<FVertex>> ReadObjFile(const FString &path) {
|
||||
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);
|
||||
|
||||
if (ret)
|
||||
iprintf("Cargado correctamente\n");
|
||||
else
|
||||
iprintf("Error al cargar el archivo: %s\n", err.c_str());
|
||||
|
||||
iprintf("Numero de materiales: %d\n", materials.size());
|
||||
|
||||
TVector<TVector<FVertex>> vertices;
|
||||
|
||||
// Loop over shapes
|
||||
for (size_t s = 0; s < shapes.size(); s++) {
|
||||
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++) {
|
||||
size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]);
|
||||
|
||||
// Loop over vertices in the face.
|
||||
for (size_t v = 0; v < fv; v++) {
|
||||
// access to vertex
|
||||
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
|
||||
|
||||
tinyobj::real_t vx = attrib.vertices[3 * size_t(idx.vertex_index) + 0];
|
||||
tinyobj::real_t vy = attrib.vertices[3 * size_t(idx.vertex_index) + 1];
|
||||
tinyobj::real_t vz = attrib.vertices[3 * size_t(idx.vertex_index) + 2];
|
||||
|
||||
FVector3 positions(vx, vy, vz);
|
||||
|
||||
// Check if `normal_index` is zero or positive. negative = no normal
|
||||
// data
|
||||
FVector3 normals(0, 0, 0);
|
||||
if (idx.normal_index >= 0) {
|
||||
tinyobj::real_t nx = attrib.normals[3 * size_t(idx.normal_index) + 0];
|
||||
tinyobj::real_t ny = attrib.normals[3 * size_t(idx.normal_index) + 1];
|
||||
tinyobj::real_t nz = attrib.normals[3 * size_t(idx.normal_index) + 2];
|
||||
|
||||
normals = FVector3(nx, ny, nz);
|
||||
}
|
||||
|
||||
// Check if `texcoord_index` is zero or positive. negative = no texcoord
|
||||
// data
|
||||
FVector2 texCoords(0, 0);
|
||||
if (idx.texcoord_index >= 0) {
|
||||
tinyobj::real_t tx =
|
||||
attrib.texcoords[2 * size_t(idx.texcoord_index) + 0];
|
||||
tinyobj::real_t ty =
|
||||
attrib.texcoords[2 * size_t(idx.texcoord_index) + 1];
|
||||
|
||||
texCoords = FVector2(tx, ty);
|
||||
}
|
||||
|
||||
vertices[s].push_back(FVertex(positions, normals, texCoords));
|
||||
}
|
||||
|
||||
index_offset += fv;
|
||||
|
||||
// per-face material
|
||||
// shapes[s].mesh.material_ids[f];
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(vertices);
|
||||
}
|
||||
|
||||
} // namespace Utils::File
|
||||
|
2029
include/tinyobjloader/tiny_obj_loader.h
Normal file
2029
include/tinyobjloader/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,11 @@
|
||||
#ifndef COMPONENT_H
|
||||
#define COMPONENT_H
|
||||
|
||||
#include "core/types.h"
|
||||
|
||||
struct Component {
|
||||
virtual ~Component() = default;
|
||||
public:
|
||||
static PtrUnq<Component> Initialize();
|
||||
};
|
||||
|
||||
#endif // COMPONENT_H
|
@ -1,7 +0,0 @@
|
||||
#include "mesh_filter.h"
|
||||
|
||||
#include "resources/resource.h"
|
||||
|
||||
MeshFilter::MeshFilter(const FString &name) : meshName(name) {
|
||||
mesh = LoadResource<Mesh>(name);
|
||||
}
|
@ -8,11 +8,14 @@ class Mesh;
|
||||
|
||||
struct MeshFilter : public Component {
|
||||
public:
|
||||
MeshFilter(const FString &name);
|
||||
static PtrUnq<MeshFilter> Initialize(const FString &path);
|
||||
|
||||
PtrShr<Mesh> getMesh() const { return mesh; }
|
||||
|
||||
private:
|
||||
FString meshName;
|
||||
PtrShr<Mesh> mesh;
|
||||
|
||||
MeshFilter(const FString &path);
|
||||
};
|
||||
|
||||
#endif // MESH_FILTER_H
|
@ -6,32 +6,28 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct Vertex {
|
||||
struct FVertex {
|
||||
FVector3 position;
|
||||
FVector3 normal;
|
||||
FVector2 texCoords;
|
||||
|
||||
Vertex(const FVector3 &pos, const FVector3 &norm, const FVector2 &tex)
|
||||
FVertex(const FVector3 &pos, const FVector3 &norm, const FVector2 &tex)
|
||||
: position(pos), normal(norm), texCoords(tex) {}
|
||||
};
|
||||
|
||||
class Mesh : public Resource {
|
||||
using Super = Resource;
|
||||
|
||||
public:
|
||||
static PtrShr<Mesh> Load(FString path);
|
||||
static Mesh Load(const TVector<TVector<FVertex>> &vertices);
|
||||
|
||||
const TVector<Vertex> &getVertices() const;
|
||||
const TVector<unsigned int> &getIndices() const;
|
||||
|
||||
void setVertices(const TVector<Vertex> &vertices);
|
||||
void setIndices(const TVector<unsigned int> &indices);
|
||||
TVector<TVector<FVertex>> getVertices() const { return vertices; }
|
||||
|
||||
private:
|
||||
TVector<Vertex> m_vertices;
|
||||
TVector<unsigned int> m_indices;
|
||||
TVector<TVector<FVertex>> vertices;
|
||||
|
||||
Mesh() = delete;
|
||||
Mesh(const Mesh &) = delete;
|
||||
Mesh(const TVector<Vertex> &vertices, const TVector<unsigned int> &indices);
|
||||
Mesh() = default;
|
||||
Mesh(const TVector<TVector<FVertex>> &vertices);
|
||||
};
|
||||
|
||||
#endif // XRBDS_RESOURCES_MESH_H
|
@ -4,19 +4,80 @@
|
||||
#include "core/types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
template <typename T, typename... Args> PtrShr<T> LoadResource(Args &&...args) {
|
||||
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
/**
|
||||
* @struct FResourceData
|
||||
* @brief Represents resource data with a name and a file path.
|
||||
*
|
||||
* This structure is used to store information about a resource, including
|
||||
* its name and the path to its location.
|
||||
*
|
||||
* @var FResourceData::name
|
||||
* The name of the resource.
|
||||
*
|
||||
* @var FResourceData::path
|
||||
* The file path to the resource.
|
||||
*
|
||||
* @param name The name of the resource.
|
||||
* @param path The file path to the resource.
|
||||
*/
|
||||
struct FResourceData {
|
||||
/**
|
||||
* @brief Constructs an FResourceData object with the specified name and path.
|
||||
*
|
||||
* @param name The name of the resource.
|
||||
* @param path The file path of the resource.
|
||||
*/
|
||||
FResourceData(const FString &name, const FString &path)
|
||||
: name(name), path(path) {}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
class Resource {
|
||||
public:
|
||||
Resource(const FString &name, const FString &path);
|
||||
|
||||
private:
|
||||
FString name;
|
||||
FString path;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Resource
|
||||
* @brief Represents a resource that encapsulates data of type FResourceData.
|
||||
*
|
||||
* This class is used to manage and store resource data. It provides a
|
||||
* constructor to initialize the resource with the given data.
|
||||
*
|
||||
* @note The class currently only stores the data and does not provide any
|
||||
* additional functionality or accessors.
|
||||
*/
|
||||
class Resource {
|
||||
public:
|
||||
static Resource Load();
|
||||
|
||||
protected:
|
||||
Resource() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Loads a resource by creating a shared pointer to an instance of the
|
||||
* specified type.
|
||||
*
|
||||
* @tparam T The type of the resource to be loaded. Must be constructible
|
||||
with
|
||||
* the provided arguments.
|
||||
* @tparam Args The types of the arguments to be forwarded to the constructor
|
||||
of
|
||||
* T.
|
||||
* @param args The arguments to be forwarded to the constructor of T.
|
||||
* @return PtrShr<T> A shared pointer to the newly created instance of T.
|
||||
*
|
||||
* @note This function uses perfect forwarding to pass the arguments to the
|
||||
* constructor of T. Ensure that the type T is compatible with the provided
|
||||
* arguments.
|
||||
*/
|
||||
template <typename T, typename... Args> PtrShr<T> LoadResource(Args &&...args) {
|
||||
if constexpr (!std::is_base_of<Resource, T>::value) {
|
||||
iprintf("Error: Type T must be derived from Resource.\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ptr = std::make_shared<T>(T::Load(std::forward<Args>(args)...));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endif // RESOURCE_H
|
@ -9,7 +9,7 @@ public:
|
||||
using Super = Node3D;
|
||||
|
||||
public:
|
||||
MeshInstance3D();
|
||||
MeshInstance3D(const FString &path);
|
||||
};
|
||||
|
||||
#endif // XRBDS_SCENE_3D_MESH_INSTANCE_H
|
@ -2,11 +2,32 @@
|
||||
#define XRBDS_UTILS_FILE_H
|
||||
|
||||
#include "core/types.h"
|
||||
#include "resources/mesh.h"
|
||||
|
||||
namespace Utils::File {
|
||||
|
||||
/**
|
||||
* @brief Reads the contents of a text file and returns it as a string.
|
||||
*
|
||||
* @param path The file path to the text file to be read.
|
||||
* @return FString The contents of the file as a string.
|
||||
* @throws std::runtime_error If the file cannot be opened or read.
|
||||
*/
|
||||
FString ReadTextFile(const FString &path);
|
||||
|
||||
/**
|
||||
* @brief Reads a Wavefront OBJ file and parses its contents into a nested
|
||||
* 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.
|
||||
*
|
||||
* @note Ensure the file at the specified path exists and is in a valid OBJ
|
||||
* format.
|
||||
*/
|
||||
TVector<TVector<FVertex>> ReadObjFile(const FString &path);
|
||||
|
||||
} // namespace Utils::File
|
||||
|
||||
#endif // XRBDS_UTILS_FILE_H
|
46
samples/hello_world/assets/meshes/mococo/cube.obj
Normal file
46
samples/hello_world/assets/meshes/mococo/cube.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# 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
|
12
samples/hello_world/assets/meshes/mococo/mococo.mtl
Normal file
12
samples/hello_world/assets/meshes/mococo/mococo.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender 4.4.1 MTL File: 'mococo.blend'
|
||||
# www.blender.org
|
||||
|
||||
newmtl mococo_mat
|
||||
Ns 0.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
illum 1
|
||||
map_Kd mococotexture_face1.png
|
||||
map_d mococotexture_face1.png
|
1890
samples/hello_world/assets/meshes/mococo/mococo.obj
Normal file
1890
samples/hello_world/assets/meshes/mococo/mococo.obj
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Loading…
Reference in New Issue
Block a user