From 2a532836d765576e8b800326114227fb0a3ffd80 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sun, 14 May 2023 01:36:45 +0300 Subject: [PATCH] Add EtcObj rendering (Sphere only) --- src/CRE/draw_object.cpp | 95 +++++++++ src/CRE/render_context.cpp | 389 ++++++++++++++++++++++++++++++++++++- src/CRE/render_context.hpp | 36 +++- 3 files changed, 507 insertions(+), 13 deletions(-) diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index 1f7076f1..e63d9721 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -64,7 +64,102 @@ namespace mdl { } void draw_etc_obj(render_context* rctx, mdl::EtcObj* etc) { + switch (etc->type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + case mdl::ETC_OBJ_CAPSULE: // Added + break; + default: + return; + } + if (!etc->count) + return; + + GLuint vao = rctx->disp_manager.get_vertex_array(etc); + if (!vao) + return; + + vec4 g_material_state_diffuse = rctx->obj_batch.g_material_state_diffuse; + vec4 g_material_state_ambient = rctx->obj_batch.g_material_state_ambient; + vec4 g_material_state_specular = rctx->obj_batch.g_material_state_specular; + vec4 g_material_state_emission = rctx->obj_batch.g_material_state_emission; + vec4 g_material_state_shininess = rctx->obj_batch.g_material_state_shininess; + + vec4 ambient; + *(vec3*)&ambient = *(vec3*)&etc->color * 0.5f; + ambient.w = etc->color.w; + + rctx->obj_batch.g_material_state_diffuse = etc->color; + rctx->obj_batch.g_material_state_ambient = ambient; + rctx->obj_batch.g_material_state_specular = { 0.0f, 0.0f, 0.0f, 1.0f }; + rctx->obj_batch.g_material_state_emission = etc->constant ? 1.0f : vec4(0.0f, 0.0f, 0.0f, 1.0f); + rctx->obj_batch.g_material_state_shininess = { 0.0f, 0.0f, 0.0f, 1.0f }; + + rctx->obj_batch.g_blend_color = etc->color; + + gl_state_bind_vertex_array(vao); + rctx->obj_batch_ubo.WriteMapMemory(rctx->obj_batch); + + //shaders_ft.set(SHADER_FT_SIMPLE); + shaders_ft.set(etc->constant ? SHADER_FT_CONSTANT : SHADER_FT_SIMPLE); + switch (etc->type) { + case mdl::ETC_OBJ_TEAPOT: + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + break; + case mdl::ETC_OBJ_GRID: + shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + break; + case mdl::ETC_OBJ_CUBE: + if (etc->data.sphere.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, 0); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + break; + case mdl::ETC_OBJ_SPHERE: + if (etc->data.sphere.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, 0); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + break; + case mdl::ETC_OBJ_PLANE: + shaders_ft.draw_arrays(GL_TRIANGLES, 0, etc->count); + break; + case mdl::ETC_OBJ_CONE: + if (etc->data.cone.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, 0); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + break; + case mdl::ETC_OBJ_LINE: + shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + break; + case mdl::ETC_OBJ_CROSS: + shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + break; + case mdl::ETC_OBJ_CAPSULE: // Added + if (etc->data.capsule.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, 0); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + break; + } + shader::unbind(); + uniform_value_reset(); + + rctx->obj_batch.g_material_state_diffuse = g_material_state_diffuse; + rctx->obj_batch.g_material_state_ambient = g_material_state_ambient; + rctx->obj_batch.g_material_state_specular = g_material_state_specular; + rctx->obj_batch.g_material_state_emission = g_material_state_emission; + rctx->obj_batch.g_material_state_shininess = g_material_state_shininess; + + rctx->obj_batch.g_blend_color = 1.0f; } void draw_sub_mesh(render_context* rctx, const ObjSubMeshArgs* args, const mat4* model, diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 238da4db..660c9687 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -161,7 +161,8 @@ namespace mdl { void EtcObj::init(EtcObjType type) { this->type = type; color = 1.0f; - fog = false; + //fog = false; + constant = false; switch (type) { case ETC_OBJ_TEAPOT: data.teapot.size = 1.0f; @@ -176,13 +177,13 @@ namespace mdl { data.cube.size_x = 0.0f; data.cube.size_y = 0.0f; data.cube.size_z = 0.0f; - data.cube.wire = 0; + data.cube.wire = false; break; case ETC_OBJ_SPHERE: data.sphere.radius = 1.0f; data.sphere.slices = 8; data.sphere.stacks = 8; - data.sphere.wire = 0; + data.sphere.wire = false; break; case ETC_OBJ_PLANE: data.plane.w = 10; @@ -193,26 +194,40 @@ namespace mdl { data.cone.height = 1.0f; data.cone.slices = 8; data.cone.stacks = 8; - data.cone.wire = 0; + data.cone.wire = false; break; case ETC_OBJ_LINE: data.line.x0 = 0.0f; data.line.y0 = 0.0f; + data.line.z0 = 0.0f; + data.line.x0 = 0.0f; data.line.y1 = 0.0f; data.line.z1 = 1.0f; break; case ETC_OBJ_CROSS: data.cross.size = 0.1f; break; - default: - return; + case ETC_OBJ_CAPSULE: // Added + data.capsule.radius = 1.0f; + data.capsule.slices = 8; + data.capsule.stacks = 8; + data.capsule.wire = false; + data.capsule.x0 = 0.0f; + data.capsule.y0 = 0.0f; + data.capsule.z0 = 0.0f; + data.capsule.x1 = 0.0f; + data.capsule.y1 = 0.0f; + data.capsule.z1 = 1.0f; + break; } } - void ObjData::init_etc(const mat4* mat, mdl::EtcObj* etc) { + void ObjData::init_etc(DispManager* disp_manager, const mat4* mat, mdl::EtcObj* etc) { kind = mdl::OBJ_KIND_ETC; this->mat = *mat; args.etc = *etc; + + disp_manager->add_vertex_array(&args.etc); } void ObjData::init_sub_mesh(DispManager* disp_manager, const mat4* mat, @@ -415,10 +430,26 @@ namespace mdl { for (DispManager::vertex_array& i : vertex_array_cache) glDeleteVertexArrays(1, &i.vertex_array); vertex_array_cache.clear(); + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + glDeleteVertexArrays(1, &i.vertex_array); + + if (i.vertex_buffer) { + glDeleteBuffers(1, &i.vertex_buffer); + i.vertex_buffer = 0; + } + + if (i.index_buffer) { + glDeleteBuffers(1, &i.index_buffer); + i.index_buffer = 0; + } + } + etc_vertex_array_cache.clear(); + free_def(buff); } - void DispManager::add_vertex_array(const ObjSubMeshArgs* args) { + void DispManager::add_vertex_array(ObjSubMeshArgs* args) { const obj_mesh* mesh = args->mesh; const obj_sub_mesh* sub_mesh = args->sub_mesh; const obj_material_data* material = args->material; @@ -927,6 +958,261 @@ namespace mdl { gl_state_bind_element_array_buffer(0); } + static void gen_sphere_vertices(std::vector& data, + float_t radius, int32_t slices, int32_t stacks) { + float_t sector_step = (float_t)(M_PI * 2.0) / (float_t)slices; + float_t stack_step = (float_t)M_PI / (float_t)stacks; + + for (int32_t i = 0; i <= stacks; i++) { + float_t stack_angle = (float_t)(M_PI / 2.0) - (float_t)i * stack_step; + float_t xz = cosf(stack_angle); + float_t y = sinf(stack_angle); + + for (int32_t j = 0; j <= slices; ++j) { + float_t sector_angle = (float_t)j * sector_step; + + float_t x = xz * cosf(sector_angle); + float_t z = xz * sinf(sector_angle); + + data.reserve(sizeof(vec3) * 2); + + data.push_back(x * radius); + data.push_back(y * radius); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(y); + data.push_back(z); + } + } + } + + static void gen_sphere_indices(std::vector& indices, + float_t radius, int32_t slices, int32_t stacks, bool wire) { + if (!wire) + for (int32_t i = 0; i < stacks; ++i) { + int32_t k1 = i * (slices + 1); + int32_t k2 = k1 + slices + 1; + + for (int32_t j = 0; j < slices; j++, k1++, k2++) { + if (i != 0) { + indices.push_back(k1); + indices.push_back(k2); + indices.push_back(k1 + 1); + } + + if (i != stacks - 1) { + indices.push_back(k1 + 1); + indices.push_back(k2); + indices.push_back(k2 + 1); + } + } + } + else + for (int32_t i = 0; i < stacks; ++i) { + int32_t k1 = i * (slices + 1); + int32_t k2 = k1 + slices + 1; + + for (int32_t j = 0; j < slices; j++, k1++, k2++) { + if (i != 0) { + indices.push_back(k1); + indices.push_back(k1 + 1); + } + + indices.push_back(k1); + indices.push_back(k2); + } + } + } + + void DispManager::add_vertex_array(EtcObj* etc) { + EtcObjType type = etc->type; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + case mdl::ETC_OBJ_CAPSULE: // Added + break; + default: + return; + } + + DispManager::etc_vertex_array* etc_vertex_array = 0; + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + if (i.alive_time <= 0 || i.type != type || !i.vertex_buffer) + continue; + + if (type == mdl::ETC_OBJ_TEAPOT + && !memcmp(&i.data.teapot, &etc->data.teapot, sizeof(EtcObjTeapot)) + || type == mdl::ETC_OBJ_GRID + && !memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid)) + || type == mdl::ETC_OBJ_CUBE + && !memcmp(&i.data.cube, &etc->data.cube, sizeof(EtcObjCube)) + || type == mdl::ETC_OBJ_SPHERE + && !memcmp(&i.data.sphere, &etc->data.sphere, sizeof(EtcObjSphere)) + || type == mdl::ETC_OBJ_PLANE + && !memcmp(&i.data.plane, &etc->data.plane, sizeof(EtcObjPlane)) + || type == mdl::ETC_OBJ_CONE + && !memcmp(&i.data.cone, &etc->data.cone, sizeof(EtcObjCone)) + || type == mdl::ETC_OBJ_LINE + && !memcmp(&i.data.line, &etc->data.line, sizeof(EtcObjLine)) + || type == mdl::ETC_OBJ_CROSS + && !memcmp(&i.data.cross, &etc->data.cross, sizeof(EtcObjCross)) + || type == mdl::ETC_OBJ_CAPSULE // Added + && !memcmp(&i.data.capsule, &etc->data.capsule, sizeof(EtcObjCapsule))) + if (i.vertex_array) { + i.alive_time = 2; + etc->count = i.count; + return; + } + else { + etc_vertex_array = &i; + break; + } + } + + if (!etc_vertex_array) + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) + if (i.alive_time <= 0) { + etc_vertex_array = &i; + break; + } + + if (!etc_vertex_array) { + etc_vertex_array_cache.push_back({}); + etc_vertex_array = &etc_vertex_array_cache.back(); + } + + if (!etc_vertex_array->vertex_array) { + glGenVertexArrays(1, &etc_vertex_array->vertex_array); + + gl_state_bind_vertex_array(etc_vertex_array->vertex_array); + glVertexAttrib4f( POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( BONE_WEIGHT_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + glVertexAttrib4f( NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( BONE_INDEX_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + } + + etc_vertex_array->alive_time = 2; + etc_vertex_array->data = etc->data; + etc_vertex_array->type = type; + + std::vector vtx_data; + std::vector vtx_indices; + bool indexed = false; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: { + EtcObjTeapot& teapot = etc->data.teapot; + + indexed = true; + } break; + case mdl::ETC_OBJ_GRID: { + EtcObjGrid& grid = etc->data.grid; + + } break; + case mdl::ETC_OBJ_CUBE: { + EtcObjCube& cube = etc->data.cube; + + indexed = true; + } break; + case mdl::ETC_OBJ_SPHERE: { + EtcObjSphere& sphere = etc->data.sphere; + + gen_sphere_vertices(vtx_data, sphere.radius, sphere.slices, sphere.stacks); + gen_sphere_indices(vtx_indices, sphere.radius, sphere.slices, sphere.stacks, sphere.wire); + indexed = true; + } break; + case mdl::ETC_OBJ_PLANE: { + EtcObjPlane& plane = etc->data.plane; + + } break; + case mdl::ETC_OBJ_CONE: { + EtcObjCone& cone = etc->data.cone; + + indexed = true; + } break; + case mdl::ETC_OBJ_LINE: { + EtcObjLine& line = etc->data.line; + + } break; + case mdl::ETC_OBJ_CROSS: { + EtcObjCross& cross = etc->data.cross; + + } break; + case mdl::ETC_OBJ_CAPSULE: { // Added + EtcObjCapsule& capsule = etc->data.capsule; + + indexed = true; + } break; + } + + uint32_t count; + if (indexed) + count = (GLuint)vtx_indices.size(); + else + count = (GLuint)(vtx_data.size() / 6); + + etc_vertex_array->count = count; + etc->count = count; + + if (!count) + return; + + GLsizei size_vertex = sizeof(vec3) * 2; + + gl_state_bind_vertex_array(etc_vertex_array->vertex_array); + + glGenBuffers(1, &etc_vertex_array->vertex_buffer); + gl_state_bind_array_buffer(etc_vertex_array->vertex_buffer); + if (GLAD_GL_VERSION_4_4) + glBufferStorage(GL_ARRAY_BUFFER, sizeof(float_t) + * vtx_data.size(), vtx_data.data(), 0); + else + glBufferData(GL_ARRAY_BUFFER, sizeof(float_t) + * vtx_data.size(), vtx_data.data(), GL_STATIC_DRAW); + + if (indexed) { + glGenBuffers(1, &etc_vertex_array->index_buffer); + gl_state_bind_element_array_buffer(etc_vertex_array->index_buffer); + if (GLAD_GL_VERSION_4_4) + glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) + * vtx_indices.size(), vtx_indices.data(), 0); + else + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) + * vtx_indices.size(), vtx_indices.data(), GL_STATIC_DRAW); + } + + glEnableVertexAttribArray(POSITION_INDEX); + glVertexAttribPointer(POSITION_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)0); + + glEnableVertexAttribArray(NORMAL_INDEX); + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)sizeof(vec3)); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + if (indexed) + gl_state_bind_element_array_buffer(0); + } + ObjData* DispManager::alloc_data(ObjKind kind) { if (!buff) return 0; @@ -984,6 +1270,26 @@ namespace mdl { i.vertex_buffer = 0; i.morph_vertex_buffer = 0; } + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) + if (i.alive_time > 0 && --i.alive_time <= 0) { + gl_state_bind_vertex_array(i.vertex_array); + glDisableVertexAttribArray(POSITION_INDEX); + glDisableVertexAttribArray( NORMAL_INDEX); + gl_state_bind_array_buffer(0, true); + gl_state_bind_element_array_buffer(0, true); + gl_state_bind_vertex_array(0); + + if (i.vertex_buffer) { + glDeleteBuffers(1, &i.vertex_buffer); + i.vertex_buffer = 0; + } + + if (i.index_buffer) { + glDeleteBuffers(1, &i.index_buffer); + i.index_buffer = 0; + } + } } void DispManager::draw(ObjType type, int32_t depth_mask, bool a4) { @@ -1133,6 +1439,7 @@ namespace mdl { } uniform_value_reset(); + gl_state_bind_vertex_array(0); shader::unbind(); gl_state_set_blend_func(GL_ONE, GL_ZERO); for (int32_t i = 0; i < 5; i++) @@ -1838,7 +2145,7 @@ namespace mdl { if (!data) return; - data->init_etc(mat, etc); + data->init_etc(this, mat, etc); if (etc->color.w == 1.0f) { if ((obj_flags & OBJ_SHADOW) != 0) mdl::DispManager::entry_list((mdl::ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); @@ -1894,7 +2201,6 @@ namespace mdl { GLsizei size_vertex = (GLsizei)mesh->size_vertex; obj_vertex_format vertex_format = mesh->vertex_format; - DispManager::vertex_array* vertex_array = 0; for (DispManager::vertex_array& i : vertex_array_cache) if (i.alive_time > 0 && i.vertex_buffer == vertex_buffer && i.morph_vertex_buffer == morph_vertex_buffer @@ -1911,6 +2217,69 @@ namespace mdl { return 0; } + GLuint DispManager::get_vertex_array(const EtcObj* etc) { + EtcObjType type = etc->type; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + case mdl::ETC_OBJ_CAPSULE: // Added + break; + default: + return 0; + } + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + if (i.alive_time <= 0 || i.type != type) + continue; + + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + if (!memcmp(&i.data.teapot, &etc->data.teapot, sizeof(EtcObjTeapot))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_GRID: + if (!memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CUBE: + if (!memcmp(&i.data.cube, &etc->data.cube, sizeof(EtcObjCube))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_SPHERE: + if (!memcmp(&i.data.sphere, &etc->data.sphere, sizeof(EtcObjSphere))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_PLANE: + if (!memcmp(&i.data.plane, &etc->data.plane, sizeof(EtcObjPlane))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CONE: + if (!memcmp(&i.data.cone, &etc->data.cone, sizeof(EtcObjCone))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_LINE: + if (!memcmp(&i.data.line, &etc->data.line, sizeof(EtcObjLine))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CROSS: + if (!memcmp(&i.data.cross, &etc->data.cross, sizeof(EtcObjCross))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CAPSULE: // Added + if (!memcmp(&i.data.capsule, &etc->data.capsule, sizeof(EtcObjCapsule))) + return i.vertex_array; + break; + } + } + return 0; + } + bool DispManager::get_chara_color() { return chara_color; } diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index f76024cf..e3d03c7d 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -59,6 +59,7 @@ namespace mdl { ETC_OBJ_CONE, ETC_OBJ_LINE, ETC_OBJ_CROSS, + ETC_OBJ_CAPSULE, // Added ETC_OBJ_MAX, }; @@ -345,6 +346,19 @@ namespace mdl { float_t size; }; + struct EtcObjCapsule { // Added + float_t radius; + int32_t slices; + int32_t stacks; + bool wire; + float_t x0; + float_t y0; + float_t z0; + float_t x1; + float_t y1; + float_t z1; + }; + struct EtcObj { union Data { EtcObjTeapot teapot; @@ -355,12 +369,15 @@ namespace mdl { EtcObjCone cone; EtcObjLine line; EtcObjCross cross; + EtcObjCapsule capsule; // Added }; EtcObjType type; vec4 color; - bool fog; + //bool fog; + bool constant; // Added Data data; + GLsizei count; // Added void init(EtcObjType type); }; @@ -391,7 +408,7 @@ namespace mdl { float_t radius; Args args; - void init_etc(const mat4* mat, mdl::EtcObj* etc); + void init_etc(DispManager* disp_manager, const mat4* mat, mdl::EtcObj* etc); void init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, @@ -475,6 +492,16 @@ namespace mdl { int32_t texcoord_array[2]; }; + struct etc_vertex_array { + GLuint vertex_buffer; + GLuint index_buffer; + int32_t alive_time; + GLuint vertex_array; + EtcObj::Data data; + EtcObjType type; + GLsizei count; + }; + mdl::ObjFlags obj_flags; shadow_type_enum shadow_type; int32_t field_8; @@ -505,11 +532,13 @@ namespace mdl { int32_t material_list_count; material_list_struct material_list_array[MATERIAL_LIST_COUNT]; std::vector vertex_array_cache; + std::vector etc_vertex_array_cache; DispManager(); ~DispManager(); - void add_vertex_array(const ObjSubMeshArgs* args); + void add_vertex_array(ObjSubMeshArgs* args); + void add_vertex_array(EtcObj* etc); ObjData* alloc_data(ObjKind kind); mat4* alloc_data(int32_t count); void buffer_reset(); @@ -541,6 +570,7 @@ namespace mdl { void entry_obj_etc(const mat4* mat, EtcObj* etc); void entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type); GLuint get_vertex_array(const ObjSubMeshArgs* args); + GLuint get_vertex_array(const EtcObj* etc); bool get_chara_color(); ObjFlags get_obj_flags(); void get_material_list(int32_t& count, material_list_struct*& value);