parent
8782bf27ac
commit
9c2856eb87
Binary file not shown.
Binary file not shown.
@ -1,10 +1,10 @@ |
|||||||
//include version.glsl |
//include version.glsl |
||||||
|
|
||||||
in vec4 color; |
uniform vec4 geom_color; |
||||||
|
|
||||||
out vec4 frag_color; |
out vec4 frag_color; |
||||||
|
|
||||||
void main() |
void main() |
||||||
{ |
{ |
||||||
frag_color = color; |
frag_color = geom_color; |
||||||
} |
} |
||||||
|
@ -0,0 +1,34 @@ |
|||||||
|
bl_info = { |
||||||
|
"name": "Export to Symmetry", |
||||||
|
"description": "Export to a format that can be read by Symmetry", |
||||||
|
"author": "Shariq Shah", |
||||||
|
"version": (0, 1), |
||||||
|
"blender": (2, 79, 0), |
||||||
|
"location": "File > Export > Export to Symmetry", |
||||||
|
"category": "Import-Export" |
||||||
|
} |
||||||
|
|
||||||
|
# Ensure that we reload our dependencies if we ourselves are reloaded by Blender |
||||||
|
if "bpy" in locals(): |
||||||
|
import imp; |
||||||
|
if "exporter" in locals(): |
||||||
|
imp.reload(exporter); |
||||||
|
|
||||||
|
import bpy |
||||||
|
from . import exporter |
||||||
|
|
||||||
|
|
||||||
|
def menu_func(self, context): |
||||||
|
self.layout.operator(ExportSymmetry.bl_idname, text="Symbres (.symbres)"); |
||||||
|
|
||||||
|
def register(): |
||||||
|
bpy.utils.register_module(__name__); |
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func); |
||||||
|
|
||||||
|
def unregister(): |
||||||
|
bpy.utils.unregister_module(__name__); |
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func); |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
register() |
@ -0,0 +1,95 @@ |
|||||||
|
import bpy |
||||||
|
import bmesh |
||||||
|
import struct |
||||||
|
from math import radians |
||||||
|
from bpy_extras.io_utils import ExportHelper |
||||||
|
|
||||||
|
class ExportSymmetry(bpy.types.Operator, ExportHelper): |
||||||
|
bl_idname = "export_symmetry.symbres"; |
||||||
|
bl_label = "Symmetry Exporter"; |
||||||
|
bl_options = {'PRESET'}; |
||||||
|
filename_ext = ".symbres"; |
||||||
|
|
||||||
|
def execute(self, context): |
||||||
|
scene = context.scene |
||||||
|
activeObject = scene.objects.active |
||||||
|
|
||||||
|
if not activeObject or str(activeObject.type) != 'MESH': |
||||||
|
raise NameError("Cannot export : Object %s is not a mesh" % activeObject) |
||||||
|
|
||||||
|
print("Exporting : " + activeObject.name) |
||||||
|
|
||||||
|
# Rotate -90 deg on x axis to compensate for blender's different orientation |
||||||
|
activeObject.rotation_euler[0] = radians(-90) |
||||||
|
bpy.ops.object.transform_apply(location = True, scale = True, rotation = True) |
||||||
|
|
||||||
|
mesh = activeObject.to_mesh(scene, True, 'PREVIEW') |
||||||
|
bm = bmesh.new() |
||||||
|
bm.from_mesh(mesh) |
||||||
|
bmesh.ops.triangulate(bm, faces = bm.faces) |
||||||
|
|
||||||
|
indices = [] |
||||||
|
vertices = [] |
||||||
|
normals = [] |
||||||
|
uvs = [] |
||||||
|
|
||||||
|
if len(mesh.uv_layers) > 0: |
||||||
|
uv_layer = bm.loops.layers.uv.values()[0] |
||||||
|
index = 0; |
||||||
|
for face in bm.faces: |
||||||
|
for loop in face.loops: |
||||||
|
uv = loop[uv_layer].uv |
||||||
|
uv.y = 1.0 - uv.y |
||||||
|
vert = loop.vert |
||||||
|
vertices.append(vert.co.to_tuple()) |
||||||
|
normals.append(vert.normal.to_tuple()) |
||||||
|
uvs.append(uv.to_tuple()) |
||||||
|
indices.append(index) |
||||||
|
index += 1 |
||||||
|
else: |
||||||
|
raise NameError("No uv layers detected. Did you forget to unwrap?") |
||||||
|
|
||||||
|
bm.free() |
||||||
|
del bm |
||||||
|
|
||||||
|
# Reset object's previous rotation |
||||||
|
activeObject.rotation_euler[0] = radians(90) |
||||||
|
bpy.ops.object.transform_apply(location = True, scale = True, rotation = True) |
||||||
|
|
||||||
|
file = open(self.filepath, 'bw') |
||||||
|
|
||||||
|
# Header |
||||||
|
file.write(struct.pack('i', len(indices))) |
||||||
|
file.write(struct.pack('i', len(vertices))) |
||||||
|
file.write(struct.pack('i', len(normals))) |
||||||
|
file.write(struct.pack('i', len(uvs))) |
||||||
|
|
||||||
|
print ("Num Indices : %d" % len(indices)) |
||||||
|
print ("Indices : \n %s \n\n" % str(indices)) |
||||||
|
|
||||||
|
print ("Num Vertices : %d" % len(vertices)) |
||||||
|
print ("Vertices : \n %s \n\n" % str(vertices)) |
||||||
|
|
||||||
|
print ("Num Normals : %d" % len(normals)) |
||||||
|
print ("Normals : \n %s \n\n" % str(normals)) |
||||||
|
|
||||||
|
print ("Num UVs : %d" % len(uvs)) |
||||||
|
print ("UVs : \n %s \n\n" % str(uvs)) |
||||||
|
|
||||||
|
# Body |
||||||
|
for index in indices: |
||||||
|
file.write(struct.pack('i', index)) |
||||||
|
|
||||||
|
for vertex in vertices: |
||||||
|
file.write(struct.pack('fff', vertex[0], vertex[1], vertex[2])) |
||||||
|
|
||||||
|
for normal in normals: |
||||||
|
file.write(struct.pack('fff', normal[0], normal[1], normal[2])) |
||||||
|
|
||||||
|
for uv in uvs: |
||||||
|
file.write(struct.pack('ff', uv[0], uv[1])) |
||||||
|
|
||||||
|
file.close() |
||||||
|
|
||||||
|
print("Done!") |
||||||
|
return {'FINISHED'}; |
@ -1,391 +1,391 @@ |
|||||||
#include "geometry.h" |
#include "geometry.h" |
||||||
#include "../common/array.h" |
#include "../common/array.h" |
||||||
#include "../common/string_utils.h" |
#include "../common/string_utils.h" |
||||||
#include "../common/log.h" |
#include "../common/log.h" |
||||||
#include "renderer.h" |
#include "renderer.h" |
||||||
#include "transform.h" |
#include "transform.h" |
||||||
#include "../common/common.h" |
#include "../common/common.h" |
||||||
#include "gl_load.h" |
#include "gl_load.h" |
||||||
|
|
||||||
#include <stdlib.h> |
#include <stdlib.h> |
||||||
#include <stdio.h> |
#include <stdio.h> |
||||||
#include <string.h> |
#include <string.h> |
||||||
#include <assert.h> |
#include <assert.h> |
||||||
#include <math.h> |
#include <math.h> |
||||||
#include <float.h> |
#include <float.h> |
||||||
|
|
||||||
/* Data */ |
/* Data */ |
||||||
static struct Geometry* geometry_list; |
static struct Geometry* geometry_list; |
||||||
static int* empty_indices; |
static int* empty_indices; |
||||||
static GLenum* draw_modes; |
static GLenum* draw_modes; |
||||||
|
|
||||||
static int load_from_file(struct Geometry* geometry, const char* filename); |
static int load_from_file(struct Geometry* geometry, const char* filename); |
||||||
static void create_vao(struct Geometry* geometry); |
static void create_vao(struct Geometry* geometry); |
||||||
static struct Geometry* generate_new_index(int* out_new_index); |
static struct Geometry* generate_new_index(int* out_new_index); |
||||||
|
|
||||||
void geom_init(void) |
void geom_init(void) |
||||||
{ |
{ |
||||||
geometry_list = array_new(struct Geometry); |
geometry_list = array_new(struct Geometry); |
||||||
empty_indices = array_new(int); |
empty_indices = array_new(int); |
||||||
draw_modes = array_new_cap(GLenum, GDM_NUM_DRAWMODES); |
draw_modes = array_new_cap(GLenum, GDM_NUM_DRAWMODES); |
||||||
draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; |
draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; |
||||||
draw_modes[GDM_LINES] = GL_LINES; |
draw_modes[GDM_LINES] = GL_LINES; |
||||||
draw_modes[GDM_POINTS] = GL_POINTS; |
draw_modes[GDM_POINTS] = GL_POINTS; |
||||||
} |
} |
||||||
|
|
||||||
int geom_find(const char* filename) |
int geom_find(const char* filename) |
||||||
{ |
{ |
||||||
int index = -1; |
int index = -1; |
||||||
for(int i = 0; i < array_len(geometry_list); i++) |
for(int i = 0; i < array_len(geometry_list); i++) |
||||||
{ |
{ |
||||||
struct Geometry* geometry = &geometry_list[i]; |
struct Geometry* geometry = &geometry_list[i]; |
||||||
if(strcmp(geometry->filename, filename) == 0) |
if(strcmp(geometry->filename, filename) == 0) |
||||||
{ |
{ |
||||||
index = i; |
index = i; |
||||||
break; |
break; |
||||||
} |
} |
||||||
} |
} |
||||||
return index; |
return index; |
||||||
} |
} |
||||||
|
|
||||||
void geom_bounding_volume_generate(int index) |
void geom_bounding_volume_generate(int index) |
||||||
{ |
{ |
||||||
struct Geometry* geometry = &geometry_list[index]; |
struct Geometry* geometry = &geometry_list[index]; |
||||||
struct Bounding_Box* box = &geometry->bounding_box; |
struct Bounding_Box* box = &geometry->bounding_box; |
||||||
struct Bounding_Sphere* sphere = &geometry->bounding_sphere; |
struct Bounding_Sphere* sphere = &geometry->bounding_sphere; |
||||||
|
|
||||||
vec3_fill(&box->max, -FLT_MIN, -FLT_MIN, -FLT_MIN); |
vec3_fill(&box->max, -FLT_MIN, -FLT_MIN, -FLT_MIN); |
||||||
vec3_fill(&box->min, FLT_MAX, FLT_MAX, FLT_MAX); |
vec3_fill(&box->min, FLT_MAX, FLT_MAX, FLT_MAX); |
||||||
vec3_fill(&sphere->center, 0.f, 0.f, 0.f); |
vec3_fill(&sphere->center, 0.f, 0.f, 0.f); |
||||||
sphere->radius = 0.f; |
sphere->radius = 0.f; |
||||||
|
|
||||||
for(int i = 0; i < array_len(geometry->vertices); i++) |
for(int i = 0; i < array_len(geometry->vertices); i++) |
||||||
{ |
{ |
||||||
vec3* vertex = &geometry->vertices[i]; |
vec3* vertex = &geometry->vertices[i]; |
||||||
if(vertex->x > box->max.x) box->max.x = vertex->x; |
if(vertex->x > box->max.x) box->max.x = vertex->x; |
||||||
if(vertex->y > box->max.y) box->max.y = vertex->y; |
if(vertex->y > box->max.y) box->max.y = vertex->y; |
||||||
if(vertex->z > box->max.z) box->max.z = vertex->z; |
if(vertex->z > box->max.z) box->max.z = vertex->z; |
||||||
|
|
||||||
if(vertex->x < box->min.x) box->min.x = vertex->x; |
if(vertex->x < box->min.x) box->min.x = vertex->x; |
||||||
if(vertex->y < box->min.y) box->min.y = vertex->y; |
if(vertex->y < box->min.y) box->min.y = vertex->y; |
||||||
if(vertex->z < box->min.z) box->min.z = vertex->z; |
if(vertex->z < box->min.z) box->min.z = vertex->z; |
||||||
} |
} |
||||||
vec3_add(&sphere->center, &box->max, &box->min); |
vec3_add(&sphere->center, &box->max, &box->min); |
||||||
vec3_scale(&sphere->center, &sphere->center, 0.5f); |
vec3_scale(&sphere->center, &sphere->center, 0.5f); |
||||||
vec3 len_vec; |
vec3 len_vec; |
||||||
vec3_sub(&len_vec, &box->max, &sphere->center); |
vec3_sub(&len_vec, &box->max, &sphere->center); |
||||||
sphere->radius = fabsf(vec3_len(&len_vec)); |
sphere->radius = fabsf(vec3_len(&len_vec)); |
||||||
} |
} |
||||||
|
|
||||||
void geom_bounding_volume_generate_all(void) |
void geom_bounding_volume_generate_all(void) |
||||||
{ |
{ |
||||||
for(int i = 0; i < array_len(geometry_list); i++) |
for(int i = 0; i < array_len(geometry_list); i++) |
||||||
geom_bounding_volume_generate(i); |
geom_bounding_volume_generate(i); |
||||||
} |
} |
||||||
|
|
||||||
static struct Geometry* generate_new_index(int* out_new_index) |
static struct Geometry* generate_new_index(int* out_new_index) |
||||||
{ |
{ |
||||||
assert(out_new_index); |
assert(out_new_index); |
||||||
int empty_len = array_len(empty_indices); |
int empty_len = array_len(empty_indices); |
||||||
struct Geometry* new_geo = NULL; |
struct Geometry* new_geo = NULL; |
||||||
if(empty_len > 0) |
if(empty_len > 0) |
||||||
{ |
{ |
||||||
*out_new_index = empty_indices[empty_len - 1]; |
*out_new_index = empty_indices[empty_len - 1]; |
||||||
array_pop(empty_indices); |
array_pop(empty_indices); |
||||||
new_geo = &geometry_list[*out_new_index]; |
new_geo = &geometry_list[*out_new_index]; |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
new_geo = array_grow(geometry_list, struct Geometry); |
new_geo = array_grow(geometry_list, struct Geometry); |
||||||
*out_new_index = array_len(geometry_list) - 1; |
*out_new_index = array_len(geometry_list) - 1; |
||||||
} |
} |
||||||
return new_geo; |
return new_geo; |
||||||
} |
} |
||||||
|
|
||||||
int geom_create_from_file(const char* name) |
int geom_create_from_file(const char* name) |
||||||
{ |
{ |
||||||
assert(name); |
assert(name); |
||||||
// check if exists
|
// check if exists
|
||||||
int index = geom_find(name); |
int index = geom_find(name); |
||||||
if(index == -1) |
if(index == -1) |
||||||
{ |
{ |
||||||
/* add new geometry object or overwrite existing one */ |
/* add new geometry object or overwrite existing one */ |
||||||
struct Geometry* new_geo = NULL; |
struct Geometry* new_geo = NULL; |
||||||
new_geo = generate_new_index(&index); |
new_geo = generate_new_index(&index); |
||||||
assert(new_geo); |
assert(new_geo); |
||||||
|
|
||||||
if(load_from_file(new_geo, name)) |
if(load_from_file(new_geo, name)) |
||||||
{ |
{ |
||||||
create_vao(new_geo); |
create_vao(new_geo); |
||||||
geom_bounding_volume_generate(index); |
geom_bounding_volume_generate(index); |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
/* TODO: Some error here, find it and fix it */ |
/* TODO: Some error here, find it and fix it */ |
||||||
array_pop(geometry_list); |
array_pop(geometry_list); |
||||||
index = -1; |
index = -1; |
||||||
} |
} |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
geometry_list[index].ref_count++; |
geometry_list[index].ref_count++; |
||||||
} |
} |
||||||
return index; |
return index; |
||||||
} |
} |
||||||
|
|
||||||
int geom_create(const char* name, |
int geom_create(const char* name, |
||||||
vec3* vertices, |
vec3* vertices, |
||||||
vec2* uvs, |
vec2* uvs, |
||||||
vec3* normals, |
vec3* normals, |
||||||
uint* indices, |
uint* indices, |
||||||
vec3* vertex_colors) |
vec3* vertex_colors) |
||||||
{ |
{ |
||||||
assert(name && vertices && uvs && normals && indices); |
assert(name && vertices && uvs && normals && indices); |
||||||
int index = -1; |
int index = -1; |
||||||
/* add new geometry object or overwrite existing one */ |
/* add new geometry object or overwrite existing one */ |
||||||
struct Geometry* new_geo = NULL; |
struct Geometry* new_geo = NULL; |
||||||
new_geo = generate_new_index(&index); |
new_geo = generate_new_index(&index); |
||||||
assert(new_geo); |
assert(new_geo); |
||||||
new_geo->filename = str_new(name); |
new_geo->filename = str_new(name); |
||||||
new_geo->vertices = array_new_cap(vec3, array_len(vertices)); |
new_geo->vertices = array_new_cap(vec3, array_len(vertices)); |
||||||
array_copy(vertices, new_geo->vertices); |
array_copy(vertices, new_geo->vertices); |
||||||
new_geo->normals = array_new_cap(vec3, array_len(normals)); |
new_geo->normals = array_new_cap(vec3, array_len(normals)); |
||||||
array_copy(normals, new_geo->normals); |
array_copy(normals, new_geo->normals); |
||||||
new_geo->uvs = array_new_cap(vec2, array_len(uvs)); |
new_geo->uvs = array_new_cap(vec2, array_len(uvs)); |
||||||
array_copy(uvs, new_geo->uvs); |
array_copy(uvs, new_geo->uvs); |
||||||
new_geo->indices = array_new_cap(uint, array_len(indices)); |
new_geo->indices = array_new_cap(uint, array_len(indices)); |
||||||
array_copy(indices, new_geo->indices); |
array_copy(indices, new_geo->indices); |
||||||
if(vertex_colors) |
if(vertex_colors) |
||||||
{ |
{ |
||||||
new_geo->vertex_colors = array_new_cap(vec3, array_len(vertex_colors)); |
new_geo->vertex_colors = array_new_cap(vec3, array_len(vertex_colors)); |
||||||
array_copy(vertex_colors, new_geo->vertex_colors); |
array_copy(vertex_colors, new_geo->vertex_colors); |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
new_geo->vertex_colors = array_new(vec3); |
new_geo->vertex_colors = array_new(vec3); |
||||||
} |
} |
||||||
create_vao(new_geo); |
create_vao(new_geo); |
||||||
//generateBoundingBox(index);
|
//generateBoundingBox(index);
|
||||||
return index; |
return index; |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
void geom_remove(int index) |
void geom_remove(int index) |
||||||
{ |
{ |
||||||
if(index >= 0 && index < array_len(geometry_list)) |
if(index >= 0 && index < array_len(geometry_list)) |
||||||
{ |
{ |
||||||
struct Geometry* geometry = &geometry_list[index]; |
struct Geometry* geometry = &geometry_list[index]; |
||||||
if(geometry->ref_count >= 0) |
if(geometry->ref_count >= 0) |
||||||
{ |
{ |
||||||
geometry->ref_count--; |
geometry->ref_count--; |
||||||
if(geometry->ref_count < 0) |
if(geometry->ref_count < 0) |
||||||
{ |
{ |
||||||
if(geometry->indices) array_free(geometry->indices); |
if(geometry->indices) array_free(geometry->indices); |
||||||
if(geometry->vertices) array_free(geometry->vertices); |
if(geometry->vertices) array_free(geometry->vertices); |
||||||
if(geometry->uvs) array_free(geometry->uvs); |
if(geometry->uvs) array_free(geometry->uvs); |
||||||
if(geometry->normals) array_free(geometry->normals); |
if(geometry->normals) array_free(geometry->normals); |
||||||
if(geometry->vertex_colors) array_free(geometry->vertex_colors); |
if(geometry->vertex_colors) array_free(geometry->vertex_colors); |
||||||
if(geometry->filename) free(geometry->filename); |
if(geometry->filename) free(geometry->filename); |
||||||
geometry->indices = NULL; |
geometry->indices = NULL; |
||||||
geometry->vertices = NULL; |
geometry->vertices = NULL; |
||||||
geometry->uvs = NULL; |
geometry->uvs = NULL; |
||||||
geometry->normals = NULL; |
geometry->normals = NULL; |
||||||
geometry->vertex_colors = NULL; |
geometry->vertex_colors = NULL; |
||||||
geometry->filename = NULL; |
geometry->filename = NULL; |
||||||
|
|
||||||
glDeleteBuffers(1, &geometry->vertex_vbo); |
glDeleteBuffers(1, &geometry->vertex_vbo); |
||||||
glDeleteBuffers(1, &geometry->color_vbo); |
glDeleteBuffers(1, &geometry->color_vbo); |
||||||
glDeleteBuffers(1, &geometry->uv_vbo); |
glDeleteBuffers(1, &geometry->uv_vbo); |
||||||
glDeleteBuffers(1, &geometry->normal_vbo); |
glDeleteBuffers(1, &geometry->normal_vbo); |
||||||
glDeleteBuffers(1, &geometry->index_vbo); |
glDeleteBuffers(1, &geometry->index_vbo); |
||||||
glDeleteVertexArrays(1, &geometry->vao); |
glDeleteVertexArrays(1, &geometry->vao); |
||||||
|
|
||||||
geometry->vertex_vbo = 0; |
geometry->vertex_vbo = 0; |
||||||
geometry->color_vbo = 0; |
geometry->color_vbo = 0; |
||||||
geometry->uv_vbo = 0; |
geometry->uv_vbo = 0; |
||||||
geometry->normal_vbo = 0; |
geometry->normal_vbo = 0; |
||||||
geometry->index_vbo = 0; |
geometry->index_vbo = 0; |
||||||
geometry->vao = 0; |
geometry->vao = 0; |
||||||
|
|
||||||
array_push(empty_indices, index, int); |
array_push(empty_indices, index, int); |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
void geom_cleanup(void) |
void geom_cleanup(void) |
||||||
{ |
{ |
||||||
for(int i = 0; i < array_len(geometry_list); i++) |
for(int i = 0; i < array_len(geometry_list); i++) |
||||||
geom_remove(i); |
geom_remove(i); |
||||||
|
|
||||||
array_free(geometry_list); |
array_free(geometry_list); |
||||||
array_free(empty_indices); |
array_free(empty_indices); |
||||||
array_free(draw_modes); |
array_free(draw_modes); |
||||||
} |
} |
||||||
|
|
||||||
static int load_from_file(struct Geometry* geometry, const char* filename) |
static int load_from_file(struct Geometry* geometry, const char* filename) |
||||||
{ |
{ |
||||||
assert(filename); |
assert(filename); |
||||||
int success = 1; |
int success = 1; |
||||||
char* full_path = str_new("models/%s", filename); |
char* full_path = str_new("models/%s", filename); |
||||||
|
|
||||||
FILE* file = platform->file.open(DIRT_INSTALL, full_path, "rb"); |
FILE* file = platform->file.open(DIRT_INSTALL, full_path, "rb"); |
||||||
free(full_path); |
free(full_path); |
||||||
if(file) |
if(file) |
||||||
{
|
{
|
||||||
const uint32 INDEX_SIZE = sizeof(uint32); |
const uint32 INDEX_SIZE = sizeof(uint32); |
||||||
const uint32 VEC3_SIZE = sizeof(vec3); |
const uint32 VEC3_SIZE = sizeof(vec3); |
||||||
const uint32 VEC2_SIZE = sizeof(vec2); |
const uint32 VEC2_SIZE = sizeof(vec2); |
||||||
uint32 header[4]; |
uint32 header[4]; |
||||||
size_t bytes_read = 0; |
size_t bytes_read = 0; |
||||||
if((bytes_read = fread(header, INDEX_SIZE, 4, file)) <= 0) |
if((bytes_read = fread(header, INDEX_SIZE, 4, file)) <= 0) |
||||||
{ |
{ |
||||||
log_error("geometry:load_from_file", "Read failed"); |
log_error("geometry:load_from_file", "Read failed"); |
||||||
success = 0; |
success = 0; |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
uint32 indices_count = header[0]; |
uint32 indices_count = header[0]; |
||||||
uint32 vertices_count = header[1]; |
uint32 vertices_count = header[1]; |
||||||
uint32 normals_count = header[2]; |
uint32 normals_count = header[2]; |
||||||
uint32 uvs_count = header[3]; |
uint32 uvs_count = header[3]; |
||||||
// Indices
|
// Indices
|
||||||
geometry->indices = array_new_cap(uint, indices_count); |
geometry->indices = array_new_cap(uint, indices_count); |
||||||
fread(geometry->indices, INDEX_SIZE, indices_count, file); |
fread(geometry->indices, INDEX_SIZE, indices_count, file); |
||||||
array_match_len_cap(geometry->indices); |
array_match_len_cap(geometry->indices); |
||||||
// Vertices
|
// Vertices
|
||||||
geometry->vertices = array_new_cap(vec3, vertices_count); |
geometry->vertices = array_new_cap(vec3, vertices_count); |
||||||
fread(geometry->vertices, VEC3_SIZE, vertices_count, file); |
fread(geometry->vertices, VEC3_SIZE, vertices_count, file); |
||||||
array_match_len_cap(geometry->vertices); |
array_match_len_cap(geometry->vertices); |
||||||
// Normals
|
// Normals
|
||||||
geometry->normals = array_new_cap(vec3, normals_count); |
geometry->normals = array_new_cap(vec3, normals_count); |
||||||
fread(geometry->normals, VEC3_SIZE, normals_count, file); |
fread(geometry->normals, VEC3_SIZE, normals_count, file); |
||||||
array_match_len_cap(geometry->normals); |
array_match_len_cap(geometry->normals); |
||||||
// Uvs
|
// Uvs
|
||||||
geometry->uvs = array_new_cap(vec2, uvs_count); |
geometry->uvs = array_new_cap(vec2, uvs_count); |
||||||
fread(geometry->uvs, VEC2_SIZE, uvs_count, file); |
fread(geometry->uvs, VEC2_SIZE, uvs_count, file); |
||||||
array_match_len_cap(geometry->uvs); |
array_match_len_cap(geometry->uvs); |
||||||
|
|
||||||
geometry->vertex_colors = array_new(vec3); |
geometry->vertex_colors = array_new(vec3); |
||||||
} |
} |
||||||
fclose(file); |
fclose(file); |
||||||
geometry->filename = str_new(filename); |
geometry->filename = str_new(filename); |
||||||
geometry->draw_indexed = 1; |
geometry->draw_indexed = 1; |
||||||
geometry->ref_count++; |
geometry->ref_count++; |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
success = 0; |
success = 0; |
||||||
} |
} |
||||||
return success; |
return success; |
||||||
} |
} |
||||||
|
|
||||||
static void create_vao(struct Geometry* geometry) |
static void create_vao(struct Geometry* geometry) |
||||||
{ |
{ |
||||||
// TODO: Add support for different model formats and interleaving VBO
|
// TODO: Add support for different model formats and interleaving VBO
|
||||||
assert(geometry); |
assert(geometry); |
||||||
glGenVertexArrays(1, &geometry->vao); |
glGenVertexArrays(1, &geometry->vao); |
||||||
glBindVertexArray(geometry->vao); |
glBindVertexArray(geometry->vao); |
||||||
|
|
||||||
glGenBuffers(1, &geometry->vertex_vbo); |
glGenBuffers(1, &geometry->vertex_vbo); |
||||||
glBindBuffer(GL_ARRAY_BUFFER, geometry->vertex_vbo); |
glBindBuffer(GL_ARRAY_BUFFER, geometry->vertex_vbo); |
||||||
glBufferData(GL_ARRAY_BUFFER, |
glBufferData(GL_ARRAY_BUFFER, |
||||||
array_len(geometry->vertices) * sizeof(vec3), |
array_len(geometry->vertices) * sizeof(vec3), |
||||||
geometry->vertices, |
geometry->vertices, |
||||||
GL_STATIC_DRAW); |
GL_STATIC_DRAW); |
||||||
renderer_check_glerror("geometry:create_vbo:vertex"); |
renderer_check_glerror("geometry:create_vbo:vertex"); |
||||||
glEnableVertexAttribArray(0); |
glEnableVertexAttribArray(0); |
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); |
||||||
|
|
||||||
if(array_len(geometry->normals) > 0) |
if(array_len(geometry->normals) > 0) |
||||||
{ |
{ |
||||||
glGenBuffers(1, &geometry->normal_vbo); |
glGenBuffers(1, &geometry->normal_vbo); |
||||||
glBindBuffer(GL_ARRAY_BUFFER, geometry->normal_vbo); |
glBindBuffer(GL_ARRAY_BUFFER, geometry->normal_vbo); |
||||||
glBufferData(GL_ARRAY_BUFFER, |
glBufferData(GL_ARRAY_BUFFER, |
||||||
array_len(geometry->normals) * sizeof(vec3), |
array_len(geometry->normals) * sizeof(vec3), |
||||||
geometry->normals, |
geometry->normals, |
||||||
GL_STATIC_DRAW); |
GL_STATIC_DRAW); |
||||||
renderer_check_glerror("geometry:create_vbo:normal"); |
renderer_check_glerror("geometry:create_vbo:normal"); |
||||||
glEnableVertexAttribArray(1); |
glEnableVertexAttribArray(1); |
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, 0); |
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, 0); |
||||||
} |
} |
||||||
|
|
||||||
if(array_len(geometry->uvs) > 0) |
if(array_len(geometry->uvs) > 0) |
||||||
{ |
{ |
||||||
glGenBuffers(1, &geometry->uv_vbo); |
glGenBuffers(1, &geometry->uv_vbo); |
||||||
glBindBuffer(GL_ARRAY_BUFFER, geometry->uv_vbo); |
glBindBuffer(GL_ARRAY_BUFFER, geometry->uv_vbo); |
||||||
glBufferData(GL_ARRAY_BUFFER, |
glBufferData(GL_ARRAY_BUFFER, |
||||||
array_len(geometry->uvs) * sizeof(vec2), |
array_len(geometry->uvs) * sizeof(vec2), |
||||||
geometry->uvs, |
geometry->uvs, |
||||||
GL_STATIC_DRAW); |
GL_STATIC_DRAW); |
||||||
renderer_check_glerror("geometry:create_vbo:uv"); |
renderer_check_glerror("geometry:create_vbo:uv"); |
||||||
glEnableVertexAttribArray(2); |
glEnableVertexAttribArray(2); |
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0); |
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0); |
||||||
} |
} |
||||||
|
|
||||||
if(array_len(geometry->vertex_colors) > 0) |
if(array_len(geometry->vertex_colors) > 0) |
||||||
{ |
{ |
||||||
glGenBuffers(1, &geometry->color_vbo); |
glGenBuffers(1, &geometry->color_vbo); |
||||||
glBindBuffer(GL_ARRAY_BUFFER, geometry->color_vbo); |
glBindBuffer(GL_ARRAY_BUFFER, geometry->color_vbo); |
||||||
glBufferData(GL_ARRAY_BUFFER, |
glBufferData(GL_ARRAY_BUFFER, |
||||||
array_len(geometry->vertex_colors) * sizeof(vec3), |
array_len(geometry->vertex_colors) * sizeof(vec3), |
||||||
geometry->vertex_colors, |
geometry->vertex_colors, |
||||||
GL_STATIC_DRAW); |
GL_STATIC_DRAW); |
||||||
renderer_check_glerror("geometry:create_vbo:color"); |
renderer_check_glerror("geometry:create_vbo:color"); |
||||||
glEnableVertexAttribArray(3); |
glEnableVertexAttribArray(3); |
||||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0); |
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0); |
||||||
} |
} |
||||||
|
|
||||||
if(array_len(geometry->indices) > 0) |
if(array_len(geometry->indices) > 0) |
||||||
{ |
{ |
||||||
glGenBuffers(1, &geometry->index_vbo); |
glGenBuffers(1, &geometry->index_vbo); |
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->index_vbo); |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->index_vbo); |
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, |
||||||
array_len(geometry->indices) * sizeof(GLuint), |
array_len(geometry->indices) * sizeof(GLuint), |
||||||
geometry->indices, |
geometry->indices, |
||||||
GL_STATIC_DRAW); |
GL_STATIC_DRAW); |
||||||
geometry->draw_indexed = 1; |
geometry->draw_indexed = 1; |
||||||
} |
} |
||||||
glBindVertexArray(0); |
glBindVertexArray(0); |
||||||
} |
} |
||||||
|
|
||||||
void geom_render(int index, enum Geometry_Draw_Mode draw_mode) |
void geom_render(int index, enum Geometry_Draw_Mode draw_mode) |
||||||
{ |
{ |
||||||
assert((int)draw_mode > -1 && draw_mode < GDM_NUM_DRAWMODES); |
assert((int)draw_mode > -1 && draw_mode < GDM_NUM_DRAWMODES && index >= 0); |
||||||
struct Geometry* geo = &geometry_list[index]; |
struct Geometry* geo = &geometry_list[index]; |
||||||
glBindVertexArray(geo->vao); |
glBindVertexArray(geo->vao); |
||||||
if(geo->draw_indexed) |
if(geo->draw_indexed) |
||||||
glDrawElements(draw_modes[draw_mode], array_len(geo->indices), GL_UNSIGNED_INT, (void*)0); |
glDrawElements(draw_modes[draw_mode], array_len(geo->indices), GL_UNSIGNED_INT, (void*)0); |
||||||
else |
else |
||||||
glDrawArrays(draw_modes[draw_mode], 0, array_len(geo->vertices)); |
glDrawArrays(draw_modes[draw_mode], 0, array_len(geo->vertices)); |
||||||
glBindVertexArray(0); |
glBindVertexArray(0); |
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
int geom_render_in_frustum(int index, |
int geom_render_in_frustum(int index, |
||||||
vec4* frustum, |
vec4* frustum, |
||||||
struct Entity* entity, |
struct Entity* entity, |
||||||
enum Geometry_Draw_Mode draw_mode) |
enum Geometry_Draw_Mode draw_mode) |
||||||
{ |
{ |
||||||
struct Geometry* geometry = &geometry_list[index]; |
struct Geometry* geometry = &geometry_list[index]; |
||||||
int indices_rendered = 0; |
int indices_rendered = 0; |
||||||
int intersection = bv_intersect_frustum_sphere(frustum, &geometry->bounding_sphere, entity); |
int intersection = bv_intersect_frustum_sphere(frustum, &geometry->bounding_sphere, entity); |
||||||
if(intersection == IT_INTERSECT || intersection == IT_INSIDE) |
if(intersection == IT_INTERSECT || intersection == IT_INSIDE) |
||||||
{ |
{ |
||||||
geom_render(index, draw_mode); |
geom_render(index, draw_mode); |
||||||
indices_rendered = array_len(geometry->indices); |
indices_rendered = array_len(geometry->indices); |
||||||
/* intersection = bv_intersect_frustum_box(frustum, &geometry->bounding_box, entity); */ |
/* intersection = bv_intersect_frustum_box(frustum, &geometry->bounding_box, entity); */ |
||||||
/* if(intersection == IT_INTERSECT || intersection == IT_INSIDE) */ |
/* if(intersection == IT_INTERSECT || intersection == IT_INSIDE) */ |
||||||
/* { */ |
/* { */ |
||||||
/* geom_render(index, draw_mode); */ |
/* geom_render(index, draw_mode); */ |
||||||
/* rendered = array_len(geometry->indices); */ |
/* rendered = array_len(geometry->indices); */ |
||||||
/* } */ |
/* } */ |
||||||
} |
} |
||||||
return indices_rendered; |
return indices_rendered; |
||||||
} |
} |
||||||
|
|
||||||
struct Geometry* geom_get(int index) |
struct Geometry* geom_get(int index) |
||||||
{ |
{ |
||||||
assert(index > -1 && index < array_len(geometry_list)); |
assert(index > -1 && index < array_len(geometry_list)); |
||||||
return &geometry_list[index]; |
return &geometry_list[index]; |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue