rm MaterialData;

This commit is contained in:
bjorn 2018-01-29 21:44:32 -08:00
parent 4a68067e28
commit 14a54fa7b0
12 changed files with 163 additions and 137 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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];

View File

@ -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;
}