This commit is contained in:
bjorn 2016-10-31 13:54:32 -07:00
parent 9d6b6dddb4
commit fb6c1c28ed
13 changed files with 129 additions and 6 deletions

View File

@ -133,6 +133,22 @@ void lovrBufferSetVertex(Buffer* buffer, int index, void* data) {
}
}
void lovrBufferSetVertices(Buffer* buffer, float* vertices, int count) {
memcpy(buffer->data, vertices, buffer->stride * count);
glBindVertexArray(buffer->vao);
glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo);
glBufferData(GL_ARRAY_BUFFER, buffer->size * buffer->stride, buffer->data, buffer->usage);
int i;
BufferAttribute attribute;
size_t offset = 0;
vec_foreach(&buffer->format, attribute, i) {
glVertexAttribPointer(i, attribute.size, attribute.type, GL_FALSE, buffer->stride, (void*) offset);
offset += attribute.size + sizeof(attribute.type);
}
}
unsigned int* lovrBufferGetVertexMap(Buffer* buffer, int* count) {
*count = buffer->map.length;
return buffer->map.data;

View File

@ -58,6 +58,7 @@ int lovrBufferGetVertexSize(Buffer* buffer);
void* lovrBufferGetScratchVertex(Buffer* buffer);
void lovrBufferGetVertex(Buffer* buffer, int index, void* dest);
void lovrBufferSetVertex(Buffer* buffer, int index, void* vertex);
void lovrBufferSetVertices(Buffer* buffer, float* vertices, int count);
unsigned int* lovrBufferGetVertexMap(Buffer* buffer, int* count);
void lovrBufferSetVertexMap(Buffer* buffer, unsigned int* map, int count);
char lovrBufferIsRangeEnabled(Buffer* buffer);

View File

@ -7,7 +7,6 @@
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "../model/model.h"
static GraphicsState state;

View File

@ -6,7 +6,6 @@
#ifndef LOVR_GRAPHICS_TYPES
#define LOVR_GRAPHICS_TYPES
typedef vec_t(mat4) vec_mat4_t;
#define LOVR_COLOR(r, g, b, a) ((a << 0) | (b << 8) | (g << 16) | (r << 24))
#define LOVR_COLOR_R(c) (c >> 24 & 0xff)

View File

@ -1,9 +1,76 @@
#include "model.h"
#include <stdlib.h>
static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec_float_t* vertices, vec_uint_t* indices) {
mat4 newTransform;
if (!transform) {
newTransform = mat4_init();
} else {
newTransform = mat4_copy(transform);
}
mat4_multiply(newTransform, node->transform);
int indexOffset = vertices->length / 3;
// Meshes
for (int m = 0; m < node->meshes.length; m++) {
ModelMesh* mesh = modelData->meshes.data[node->meshes.data[m]];
// Transformed vertices
for (int v = 0; v < mesh->vertices.length; v++) {
ModelVertex vertex = mesh->vertices.data[v];
float v[4] = {
vertex.x,
vertex.y,
vertex.z,
1.f
};
mat4_multiplyVector(newTransform, v);
vec_pusharr(vertices, v, 3);
}
// Face vertex indices
for (int f = 0; f < mesh->faces.length; f++) {
ModelFace face = mesh->faces.data[f];
for (int v = 0; v < face.indices.length; v++) {
vec_push(indices, face.indices.data[v] + indexOffset);
}
}
}
for (int c = 0; c < node->children.length; c++) {
visitNode(modelData, node->children.data[c], newTransform, vertices, indices);
}
}
Model* lovrModelCreate(const char* filename) {
Model* model = malloc(sizeof(model));
model->modelData = lovrModelDataCreate(filename);
vec_float_t vertices;
vec_init(&vertices);
vec_uint_t indices;
vec_init(&indices);
visitNode(model->modelData, model->modelData->root, NULL, &vertices, &indices);
BufferFormat format;
BufferAttribute position = { .name = "position", .type = BUFFER_FLOAT, .size = 3 };
vec_init(&format);
vec_push(&format, position);
model->buffer = lovrBufferCreate(vertices.length / 3, &format, BUFFER_TRIANGLES, BUFFER_STATIC);
lovrBufferSetVertices(model->buffer, vertices.data, vertices.length / 3);
lovrBufferSetVertexMap(model->buffer, indices.data, indices.length);
vec_deinit(&vertices);
vec_deinit(&indices);
return model;
}
@ -11,3 +78,7 @@ void lovrModelDestroy(Model* model) {
lovrModelDataDestroy(model->modelData);
free(model);
}
void lovrModelDraw(Model* model) {
lovrBufferDraw(model->buffer);
}

View File

@ -1,11 +1,15 @@
#include "buffer.h"
#include "../model/modelData.h"
#include "../glfw.h"
#ifndef LOVR_MODEL_TYPES
#define LOVR_MODEL_TYPES
typedef struct {
ModelData* modelData;
Buffer* buffer;
} Model;
#endif
Model* lovrModelCreate(const char* filename);
void lovrModelDestroy(Model* model);
void lovrModelDraw(Model* model);

View File

@ -20,5 +20,12 @@ int luax_destroymodel(lua_State* L) {
}
const luaL_Reg lovrModel[] = {
{ "draw", l_lovrModelDraw },
{ NULL, NULL }
};
int l_lovrModelDraw(lua_State* L) {
Model* model = luax_checkmodel(L, 1);
lovrModelDraw(model);
return 0;
}

View File

@ -7,3 +7,5 @@ void luax_pushmodel(lua_State* L, Model* model);
Model* luax_checkmodel(lua_State* L, int index);
int luax_destroymodel(lua_State* L);
extern const luaL_Reg lovrModel[];
int l_lovrModelDraw(lua_State* L);

View File

@ -185,6 +185,17 @@ mat4 mat4_multiply(mat4 a, mat4 b) {
return a;
}
void mat4_multiplyVector(mat4 m, float* v) {
float v0 = v[0];
float v1 = v[1];
float v2 = v[2];
float v3 = v[3];
v[0] = v0 * m[0] + v1 * m[4] + v2 * m[8] + v3 * m[12];
v[1] = v0 * m[1] + v1 * m[5] + v2 * m[9] + v3 * m[13];
v[2] = v0 * m[2] + v1 * m[6] + v2 * m[10] + v3 * m[14];
v[3] = v0 * m[3] + v1 * m[7] + v2 * m[11] + v3 * m[15];
}
// Modified from gl-matrix.c
mat4 mat4_invert(mat4 m) {
float a00 = m[0], a01 = m[1], a02 = m[2], a03 = m[3],

View File

@ -1,4 +1,10 @@
#include "vendor/vec/vec.h"
#ifndef LOVR_MATRIX_TYPES
#define LOVR_MATRIX_TYPES
typedef float* mat4;
typedef vec_t(mat4) vec_mat4_t;
#endif
mat4 mat4_init();
void mat4_deinit(mat4 matrix);
@ -15,4 +21,5 @@ mat4 mat4_translate(mat4 matrix, float x, float y, float z);
mat4 mat4_rotate(mat4 matrix, float w, float x, float y, float z);
mat4 mat4_scale(mat4 matrix, float x, float y, float z);
mat4 mat4_multiply(mat4 a, mat4 b);
void mat4_multiplyVector(mat4 m, float* v);
mat4 mat4_invert(mat4 matrix);

View File

@ -1 +0,0 @@
// This page intentionally left blank

View File

@ -1 +0,0 @@
// This page intentionally left blank

View File

@ -3,7 +3,6 @@
#include <assimp/scene.h>
#include <assimp/cimport.h>
#include <assimp/postprocess.h>
#include <stdio.h>
static void assimpNodeTraversal(ModelNode* node, struct aiNode* assimpNode) {
@ -27,18 +26,25 @@ static void assimpNodeTraversal(ModelNode* node, struct aiNode* assimpNode) {
ModelData* lovrModelDataCreate(const char* filename) {
ModelData* modelData = malloc(sizeof(ModelData));
const struct aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality);
const struct aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_OptimizeGraph);
// Meshes
vec_init(&modelData->meshes);
for (int m = 0; m < scene->mNumMeshes; m++) {
struct aiMesh* assimpMesh = scene->mMeshes[m];
ModelMesh* mesh = malloc(sizeof(ModelMesh));
vec_push(&modelData->meshes, mesh);
// Faces
vec_init(&mesh->faces);
for (int f = 0; f < assimpMesh->mNumFaces; f++) {
struct aiFace assimpFace = assimpMesh->mFaces[f];
// Skip lines and points, polygons are triangulated
if (assimpFace.mNumIndices != 3) {
continue;
}
ModelFace face;
vec_init(&face.indices);
@ -57,6 +63,8 @@ ModelData* lovrModelDataCreate(const char* filename) {
vertex.x = assimpMesh->mVertices[v].x;
vertex.y = assimpMesh->mVertices[v].y;
vertex.z = assimpMesh->mVertices[v].z;
vec_push(&mesh->vertices, vertex);
}
}