mirror of https://github.com/bjornbytes/lovr.git
rm MaterialData;
This commit is contained in:
parent
4a68067e28
commit
14a54fa7b0
|
@ -248,7 +248,6 @@ set(LOVR_SRC
|
|||
src/audio/source.c
|
||||
src/data/audioStream.c
|
||||
src/data/data.c
|
||||
src/data/material.c
|
||||
src/data/model.c
|
||||
src/data/rasterizer.c
|
||||
src/data/texture.c
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "graphics/material.h"
|
||||
#include "graphics/mesh.h"
|
||||
#include "graphics/model.h"
|
||||
#include "data/material.h"
|
||||
#include "data/model.h"
|
||||
#include "data/rasterizer.h"
|
||||
#include "data/texture.h"
|
||||
|
@ -877,8 +876,7 @@ int l_lovrGraphicsNewFont(lua_State* L) {
|
|||
}
|
||||
|
||||
int l_lovrGraphicsNewMaterial(lua_State* L) {
|
||||
MaterialData* materialData = lovrMaterialDataCreateEmpty();
|
||||
Material* material = lovrMaterialCreate(materialData, false);
|
||||
Material* material = lovrMaterialCreate(false);
|
||||
|
||||
int index = 1;
|
||||
|
||||
|
@ -989,8 +987,7 @@ int l_lovrGraphicsNewModel(lua_State* L) {
|
|||
Blob* blob = luax_readblob(L, 2, "Texture");
|
||||
TextureData* textureData = lovrTextureDataFromBlob(blob);
|
||||
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true);
|
||||
MaterialData* materialData = lovrMaterialDataCreateEmpty();
|
||||
Material* material = lovrMaterialCreate(materialData, false);
|
||||
Material* material = lovrMaterialCreate(false);
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
|
||||
lovrModelSetMaterial(model, material);
|
||||
lovrRelease(&blob->ref);
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#include "data/material.h"
|
||||
|
||||
MaterialData* lovrMaterialDataCreateEmpty() {
|
||||
MaterialData* materialData = malloc(sizeof(MaterialData));
|
||||
|
||||
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
|
||||
materialData->colors[i] = (Color) { 1., 1., 1., 1. };
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
|
||||
materialData->textures[i] = NULL;
|
||||
}
|
||||
|
||||
return materialData;
|
||||
}
|
||||
|
||||
void lovrMaterialDataDestroy(MaterialData* materialData) {
|
||||
free(materialData);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#include "data/texture.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
COLOR_DIFFUSE,
|
||||
MAX_MATERIAL_COLORS
|
||||
} MaterialColor;
|
||||
|
||||
typedef enum {
|
||||
TEXTURE_DIFFUSE,
|
||||
TEXTURE_ENVIRONMENT_MAP,
|
||||
MAX_MATERIAL_TEXTURES
|
||||
} MaterialTexture;
|
||||
|
||||
typedef struct {
|
||||
Color colors[MAX_MATERIAL_COLORS];
|
||||
TextureData* textures[MAX_MATERIAL_TEXTURES];
|
||||
} MaterialData;
|
||||
|
||||
MaterialData* lovrMaterialDataCreateEmpty();
|
||||
void lovrMaterialDataDestroy(MaterialData* materialData);
|
165
src/data/model.c
165
src/data/model.c
|
@ -1,4 +1,5 @@
|
|||
#include "data/model.h"
|
||||
#include "data/texture.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#include "filesystem/file.h"
|
||||
#include "math/math.h"
|
||||
|
@ -18,39 +19,6 @@
|
|||
#include <assimp/vector3.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
static void assimpSumChildren(struct aiNode* assimpNode, int* totalChildren) {
|
||||
(*totalChildren)++;
|
||||
for (unsigned int i = 0; i < assimpNode->mNumChildren; i++) {
|
||||
assimpSumChildren(assimpNode->mChildren[i], totalChildren);
|
||||
}
|
||||
}
|
||||
|
||||
static void assimpNodeTraversal(ModelData* modelData, struct aiNode* assimpNode, int* nodeId) {
|
||||
int currentIndex = *nodeId;
|
||||
ModelNode* node = &modelData->nodes[currentIndex];
|
||||
node->name = strdup(assimpNode->mName.data);
|
||||
map_set(&modelData->nodeMap, node->name, currentIndex);
|
||||
|
||||
// Transform
|
||||
struct aiMatrix4x4 m = assimpNode->mTransformation;
|
||||
aiTransposeMatrix4(&m);
|
||||
mat4_set(node->transform, (float*) &m);
|
||||
|
||||
// Primitives
|
||||
vec_init(&node->primitives);
|
||||
vec_pusharr(&node->primitives, assimpNode->mMeshes, assimpNode->mNumMeshes);
|
||||
|
||||
// Children
|
||||
vec_init(&node->children);
|
||||
for (unsigned int n = 0; n < assimpNode->mNumChildren; n++) {
|
||||
(*nodeId)++;
|
||||
vec_push(&node->children, *nodeId);
|
||||
ModelNode* child = &modelData->nodes[*nodeId];
|
||||
child->parent = currentIndex;
|
||||
assimpNodeTraversal(modelData, assimpNode->mChildren[n], nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
static void normalizePath(char* path, char* dst, size_t size) {
|
||||
char* slash = path;
|
||||
while ((slash = strchr(path, '\\')) != NULL) { *slash++ = '/'; }
|
||||
|
@ -87,6 +55,91 @@ static void normalizePath(char* path, char* dst, size_t size) {
|
|||
*--dst = '\0';
|
||||
}
|
||||
|
||||
static void assimpSumChildren(struct aiNode* assimpNode, int* totalChildren) {
|
||||
(*totalChildren)++;
|
||||
for (unsigned int i = 0; i < assimpNode->mNumChildren; i++) {
|
||||
assimpSumChildren(assimpNode->mChildren[i], totalChildren);
|
||||
}
|
||||
}
|
||||
|
||||
static void assimpNodeTraversal(ModelData* modelData, struct aiNode* assimpNode, int* nodeId) {
|
||||
int currentIndex = *nodeId;
|
||||
ModelNode* node = &modelData->nodes[currentIndex];
|
||||
node->name = strdup(assimpNode->mName.data);
|
||||
map_set(&modelData->nodeMap, node->name, currentIndex);
|
||||
|
||||
// Transform
|
||||
struct aiMatrix4x4 m = assimpNode->mTransformation;
|
||||
aiTransposeMatrix4(&m);
|
||||
mat4_set(node->transform, (float*) &m);
|
||||
|
||||
// Primitives
|
||||
vec_init(&node->primitives);
|
||||
vec_pusharr(&node->primitives, assimpNode->mMeshes, assimpNode->mNumMeshes);
|
||||
|
||||
// Children
|
||||
vec_init(&node->children);
|
||||
for (unsigned int n = 0; n < assimpNode->mNumChildren; n++) {
|
||||
(*nodeId)++;
|
||||
vec_push(&node->children, *nodeId);
|
||||
ModelNode* child = &modelData->nodes[*nodeId];
|
||||
child->parent = currentIndex;
|
||||
assimpNodeTraversal(modelData, assimpNode->mChildren[n], nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
static Color readMaterialColor(struct aiMaterial* assimpMaterial, const char* key, unsigned int type, unsigned int index) {
|
||||
struct aiColor4D assimpColor;
|
||||
if (aiGetMaterialColor(assimpMaterial, key, type, index, &assimpColor) == aiReturn_SUCCESS) {
|
||||
Color color;
|
||||
color.r = assimpColor.r;
|
||||
color.g = assimpColor.g;
|
||||
color.b = assimpColor.b;
|
||||
color.a = assimpColor.a;
|
||||
return color;
|
||||
} else {
|
||||
return (Color) { 1, 1, 1, 1 };
|
||||
}
|
||||
}
|
||||
|
||||
static int readMaterialTexture(struct aiMaterial* assimpMaterial, enum aiTextureType type, ModelData* modelData, map_int_t* textureCache, const char* dirname) {
|
||||
struct aiString str;
|
||||
if (aiGetMaterialTexture(assimpMaterial, type, 0, &str, NULL, NULL, NULL, NULL, NULL, NULL) == aiReturn_SUCCESS) {
|
||||
char* path = str.data;
|
||||
|
||||
int* cachedTexture = map_get(textureCache, path);
|
||||
if (cachedTexture) {
|
||||
return *cachedTexture;
|
||||
}
|
||||
|
||||
int textureIndex = modelData->textures.length;
|
||||
|
||||
char fullPath[LOVR_PATH_MAX];
|
||||
char normalizedPath[LOVR_PATH_MAX];
|
||||
strncpy(fullPath, dirname, LOVR_PATH_MAX);
|
||||
char* lastSlash = strrchr(fullPath, '/');
|
||||
if (lastSlash) lastSlash[1] = '\0';
|
||||
strncat(fullPath, path, LOVR_PATH_MAX);
|
||||
normalizePath(fullPath, normalizedPath, LOVR_PATH_MAX);
|
||||
|
||||
size_t size;
|
||||
void* data = lovrFilesystemRead(normalizedPath, &size);
|
||||
if (data) {
|
||||
Blob* blob = lovrBlobCreate(data, size, path);
|
||||
vec_push(&modelData->textures, lovrTextureDataFromBlob(blob));
|
||||
} else {
|
||||
vec_push(&modelData->textures, NULL);
|
||||
}
|
||||
|
||||
map_set(textureCache, path, textureIndex);
|
||||
return textureIndex;
|
||||
} else {
|
||||
int textureIndex = modelData->textures.length;
|
||||
vec_push(&modelData->textures, NULL);
|
||||
return textureIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Blob IO (to avoid reading data twice)
|
||||
static size_t assimpBlobRead(struct aiFile* assimpFile, char* buffer, size_t size, size_t count) {
|
||||
Blob* blob = (Blob*) assimpFile->UserData;
|
||||
|
@ -349,41 +402,19 @@ ModelData* lovrModelDataCreate(Blob* blob) {
|
|||
}
|
||||
|
||||
// Materials
|
||||
map_int_t textureCache;
|
||||
map_init(&textureCache);
|
||||
vec_init(&modelData->textures);
|
||||
modelData->materialCount = scene->mNumMaterials;
|
||||
modelData->materials = malloc(modelData->materialCount * sizeof(MaterialData*));
|
||||
modelData->materials = malloc(modelData->materialCount * sizeof(ModelMaterial));
|
||||
for (unsigned int m = 0; m < scene->mNumMaterials; m++) {
|
||||
MaterialData* materialData = lovrMaterialDataCreateEmpty();
|
||||
struct aiMaterial* material = scene->mMaterials[m];
|
||||
struct aiColor4D color;
|
||||
struct aiString str;
|
||||
ModelMaterial* material = &modelData->materials[m];
|
||||
struct aiMaterial* assimpMaterial = scene->mMaterials[m];
|
||||
|
||||
if (aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &color) == aiReturn_SUCCESS) {
|
||||
materialData->colors[COLOR_DIFFUSE].r = color.r;
|
||||
materialData->colors[COLOR_DIFFUSE].g = color.g;
|
||||
materialData->colors[COLOR_DIFFUSE].b = color.b;
|
||||
materialData->colors[COLOR_DIFFUSE].a = color.a;
|
||||
}
|
||||
|
||||
if (aiGetMaterialTexture(material, aiTextureType_DIFFUSE, 0, &str, NULL, NULL, NULL, NULL, NULL, NULL) == aiReturn_SUCCESS) {
|
||||
char* path = str.data;
|
||||
char fullPath[LOVR_PATH_MAX];
|
||||
char normalizedPath[LOVR_PATH_MAX];
|
||||
strncpy(fullPath, blob->name, LOVR_PATH_MAX);
|
||||
char* lastSlash = strrchr(fullPath, '/');
|
||||
if (lastSlash) lastSlash[1] = '\0';
|
||||
strncat(fullPath, path, LOVR_PATH_MAX);
|
||||
normalizePath(fullPath, normalizedPath, LOVR_PATH_MAX);
|
||||
|
||||
size_t size;
|
||||
void* data = lovrFilesystemRead(normalizedPath, &size);
|
||||
if (data) {
|
||||
Blob* blob = lovrBlobCreate(data, size, path);
|
||||
materialData->textures[TEXTURE_DIFFUSE] = lovrTextureDataFromBlob(blob);
|
||||
}
|
||||
}
|
||||
|
||||
modelData->materials[m] = materialData;
|
||||
material->diffuseColor = readMaterialColor(assimpMaterial, AI_MATKEY_COLOR_DIFFUSE);
|
||||
material->diffuseTexture = readMaterialTexture(assimpMaterial, aiTextureType_DIFFUSE, modelData, &textureCache, blob->name);
|
||||
}
|
||||
map_deinit(&textureCache);
|
||||
|
||||
// Nodes
|
||||
modelData->nodeCount = 0;
|
||||
|
@ -476,10 +507,12 @@ void lovrModelDataDestroy(const Ref* ref) {
|
|||
map_deinit(&animation->channels);
|
||||
}
|
||||
|
||||
for (int i = 0; i < modelData->materialCount; i++) {
|
||||
lovrMaterialDataDestroy(modelData->materials[i]);
|
||||
for (int i = 0; i < modelData->textures.length; i++) {
|
||||
TextureData* textureData = modelData->textures.data[i];
|
||||
lovrRelease(&textureData->ref);
|
||||
}
|
||||
|
||||
vec_deinit(&modelData->textures);
|
||||
map_deinit(&modelData->nodeMap);
|
||||
|
||||
free(modelData->nodes);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "filesystem/blob.h"
|
||||
#include "data/material.h"
|
||||
#include "util.h"
|
||||
#include "lib/vertex.h"
|
||||
#include "lib/map/map.h"
|
||||
|
@ -66,7 +65,8 @@ typedef struct {
|
|||
map_int_t nodeMap;
|
||||
ModelPrimitive* primitives;
|
||||
Animation* animations;
|
||||
MaterialData** materials;
|
||||
ModelMaterial* materials;
|
||||
vec_void_t textures;
|
||||
VertexFormat format;
|
||||
VertexData vertices;
|
||||
IndexData indices;
|
||||
|
|
|
@ -1169,8 +1169,7 @@ void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) {
|
|||
|
||||
Material* lovrGraphicsGetDefaultMaterial() {
|
||||
if (!state.defaultMaterial) {
|
||||
MaterialData* materialData = lovrMaterialDataCreateEmpty();
|
||||
state.defaultMaterial = lovrMaterialCreate(materialData, true);
|
||||
state.defaultMaterial = lovrMaterialCreate(true);
|
||||
}
|
||||
|
||||
return state.defaultMaterial;
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
#include "graphics/graphics.h"
|
||||
#include "graphics/material.h"
|
||||
|
||||
Material* lovrMaterialCreate(MaterialData* materialData, bool isDefault) {
|
||||
Material* lovrMaterialCreate(bool isDefault) {
|
||||
Material* material = lovrAlloc(sizeof(Material), lovrMaterialDestroy);
|
||||
if (!material) return NULL;
|
||||
|
||||
material->materialData = materialData;
|
||||
material->isDefault = isDefault;
|
||||
|
||||
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
|
||||
material->colors[i] = (Color) { 1, 1, 1, 1 };
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
|
||||
if (materialData->textures[i]) {
|
||||
material->textures[i] = lovrTextureCreate(TEXTURE_2D, &materialData->textures[i], 1, true);
|
||||
} else {
|
||||
material->textures[i] = NULL;
|
||||
}
|
||||
material->textures[i] = NULL;
|
||||
}
|
||||
|
||||
return material;
|
||||
|
@ -30,11 +29,11 @@ void lovrMaterialDestroy(const Ref* ref) {
|
|||
}
|
||||
|
||||
Color lovrMaterialGetColor(Material* material, MaterialColor colorType) {
|
||||
return material->materialData->colors[colorType];
|
||||
return material->colors[colorType];
|
||||
}
|
||||
|
||||
void lovrMaterialSetColor(Material* material, MaterialColor colorType, Color color) {
|
||||
material->materialData->colors[colorType] = color;
|
||||
material->colors[colorType] = color;
|
||||
}
|
||||
|
||||
Texture* lovrMaterialGetTexture(Material* material, MaterialTexture textureType) {
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
#include "util.h"
|
||||
#include "graphics/texture.h"
|
||||
#include "data/material.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
COLOR_DIFFUSE,
|
||||
MAX_MATERIAL_COLORS
|
||||
} MaterialColor;
|
||||
|
||||
typedef enum {
|
||||
TEXTURE_DIFFUSE,
|
||||
TEXTURE_ENVIRONMENT_MAP,
|
||||
MAX_MATERIAL_TEXTURES
|
||||
} MaterialTexture;
|
||||
|
||||
typedef struct {
|
||||
Ref ref;
|
||||
MaterialData* materialData;
|
||||
Color colors[MAX_MATERIAL_COLORS];
|
||||
Texture* textures[MAX_MATERIAL_TEXTURES];
|
||||
bool isDefault;
|
||||
} Material;
|
||||
|
||||
Material* lovrMaterialCreate(MaterialData* materialData, bool isDefault);
|
||||
Material* lovrMaterialCreate(bool isDefault);
|
||||
void lovrMaterialDestroy(const Ref* ref);
|
||||
Color lovrMaterialGetColor(Material* material, MaterialColor colorType);
|
||||
void lovrMaterialSetColor(Material* material, MaterialColor colorType, Color color);
|
||||
|
|
|
@ -33,7 +33,7 @@ static void renderNode(Model* model, int nodeIndex, int instances) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!model->material) {
|
||||
if (!model->material && model->materials) {
|
||||
lovrMeshSetMaterial(model->mesh, model->materials[primitive->material]);
|
||||
}
|
||||
|
||||
|
@ -66,9 +66,30 @@ Model* lovrModelCreate(ModelData* modelData) {
|
|||
lovrMeshSetVertexMap(model->mesh, modelData->indices.data, modelData->indexCount);
|
||||
lovrMeshSetRangeEnabled(model->mesh, true);
|
||||
|
||||
model->materials = malloc(modelData->materialCount * sizeof(Material*));
|
||||
for (int i = 0; i < modelData->materialCount; i++) {
|
||||
model->materials[i] = lovrMaterialCreate(modelData->materials[i], false);
|
||||
if (modelData->textures.length > 0) {
|
||||
model->textures = malloc(modelData->textures.length * sizeof(Texture*));
|
||||
for (int i = 0; i < modelData->textures.length; i++) {
|
||||
if (modelData->textures.data[i]) {
|
||||
model->textures[i] = lovrTextureCreate(TEXTURE_2D, (TextureData**) &modelData->textures.data[i], 1, true);
|
||||
} else {
|
||||
model->textures[i] = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
model->textures = NULL;
|
||||
}
|
||||
|
||||
if (modelData->materialCount > 0) {
|
||||
model->materials = malloc(modelData->materialCount * sizeof(Material*));
|
||||
for (int i = 0; i < modelData->materialCount; i++) {
|
||||
ModelMaterial* materialData = &modelData->materials[i];
|
||||
Material* material = lovrMaterialCreate(false);
|
||||
lovrMaterialSetColor(material, COLOR_DIFFUSE, materialData->diffuseColor);
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, model->textures[materialData->diffuseTexture]);
|
||||
model->materials[i] = material;
|
||||
}
|
||||
} else {
|
||||
model->materials = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BONES; i++) {
|
||||
|
@ -93,6 +114,11 @@ Model* lovrModelCreate(ModelData* modelData) {
|
|||
|
||||
void lovrModelDestroy(const Ref* ref) {
|
||||
Model* model = containerof(ref, Model);
|
||||
for (int i = 0; i < model->modelData->textures.length; i++) {
|
||||
if (model->textures[i]) {
|
||||
lovrRelease(&model->textures[i]->ref);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < model->modelData->materialCount; i++) {
|
||||
lovrRelease(&model->materials[i]->ref);
|
||||
}
|
||||
|
@ -102,6 +128,7 @@ void lovrModelDestroy(const Ref* ref) {
|
|||
if (model->material) {
|
||||
lovrRelease(&model->material->ref);
|
||||
}
|
||||
free(model->textures);
|
||||
free(model->materials);
|
||||
lovrRelease(&model->modelData->ref);
|
||||
lovrRelease(&model->mesh->ref);
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
typedef struct {
|
||||
Ref ref;
|
||||
ModelData* modelData;
|
||||
Mesh* mesh;
|
||||
Texture** textures;
|
||||
Material** materials;
|
||||
Material* material;
|
||||
Animator* animator;
|
||||
Mesh* mesh;
|
||||
float pose[MAX_BONES][16];
|
||||
float (*nodeTransforms)[16];
|
||||
float aabb[6];
|
||||
|
|
|
@ -679,7 +679,7 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
|
|||
modelData->nodes = malloc(1 * sizeof(ModelNode));
|
||||
modelData->primitives = malloc(1 * sizeof(ModelPrimitive));
|
||||
modelData->animations = NULL;
|
||||
modelData->materials = malloc(1 * sizeof(MaterialData*));
|
||||
modelData->materials = malloc(1 * sizeof(ModelMaterial));
|
||||
|
||||
// Geometry
|
||||
map_init(&modelData->nodeMap);
|
||||
|
@ -700,6 +700,8 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
|
|||
TextureData* textureData = malloc(sizeof(TextureData));
|
||||
if (!textureData) return NULL;
|
||||
|
||||
vec_push(&modelData->textures, textureData);
|
||||
|
||||
int width = vrTexture->unWidth;
|
||||
int height = vrTexture->unHeight;
|
||||
size_t size = width * height * 4;
|
||||
|
@ -712,8 +714,8 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
|
|||
textureData->generateMipmaps = true;
|
||||
vec_init(&textureData->mipmaps);
|
||||
|
||||
modelData->materials[0] = lovrMaterialDataCreateEmpty();
|
||||
modelData->materials[0]->textures[TEXTURE_DIFFUSE] = textureData;
|
||||
modelData->materials[0].diffuseColor = (Color) { 1, 1, 1, 1 };
|
||||
modelData->materials[0].diffuseTexture = 0;
|
||||
|
||||
return modelData;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue