/
Zamar_Terrier
/
TigorEngine
Обзор
Документация
Войти
/
Zamar_Terrier
/
TigorEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/Objects/gameObject3D.c
831 строка
28 KB
Zamar_Terrier
Офигенное обновление движка
31 июл 2026, 21:03
Верифицирован
31 июл 2026, 21:03
1682686
Код
Авторство
О чём код?
#include "Objects/gameObject3D.h" #include <vulkan/vulkan.h> #include "wManager/window_manager.h" #include "Core/e_memory.h" #include "Core/e_device.h" #include "Core/e_camera.h" #include "Core/pipeline.h" #include "Core/e_buffer.h" #include "Core/e_texture.h" #include "Objects/render_texture.h" #include "Objects/light_object.h" #include "Tools/e_math.h" #include "Tools/e_tools.h" #include "Tools/e_shaders.h" #include "Tools/shader_builder.h" #include "Data/e_resource_data.h" #include "Data/e_resource_engine.h" #include <tigor.h> #define VERTEX_BUFFER_BIND_ID 0 #define INSTANCE_BUFFER_BIND_ID 1 extern TEngine engine; void GameObject3DDescriptorModelUpdate(GameObject3D* go, void *data) { RenderTexture *render = (RenderTexture *)go->graphObj.render_point; Camera3D* cam = (Camera3D*) &render->cam3D; TransformBuffer mbo = {0}; vec3 cameraUp = {0.0f, 1.0f, 0.0f}; mbo.model = m4_transform(go->transform.position, go->transform.scale, go->transform.rotation); mbo.view = m4_look_at(cam->position, v3_add(cam->position, cam->rotation), cameraUp); mbo.proj = m4_perspective(render->width, render->height, cam->view_angle, cam->view_near, cam->view_distance); mbo.proj.m[1][1] *= -1; memcpy(data, (char *)&mbo, sizeof(mbo)); } void GameObject3DDescriptorLightUpdate(GameObject3D* go, void *data) { LightBuffer lbo = {0}; LightObjectSetLights(lbo.lights); lbo.num_lights = engine.lights.size; lbo.light_enable = go->self.flags & TIGOR_GAME_OBJECT_FLAG_LIGHT; memcpy(data, (char *)&lbo, sizeof(lbo)); } void GameObject3DDefaultUpdate(GameObject3D* go) { for(int i=0; i < go->graphObj.gItems.num_shader_packs;i++) { BluePrintPack *pack = &go->graphObj.BluePrints.blue_print_packs[i]; if(go->graphObj.render_point == engine.current_render) { for(int j=0;j < pack->num_descriptors;j++) { BluePrintDescriptor *descriptor = &pack->descriptors[j]; if(descriptor->descrType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { if(descriptor->uniform.count == 0 || descriptor->update == NULL) continue; void *point; vkMapMemory(engine.device.e_device, descriptor->uniform.buffers[engine.imageIndex].memory, 0, descriptor->buffsize, 0, &point); UpdateDescriptor update = descriptor->update; update(go, point); vkUnmapMemory(engine.device.e_device, descriptor->uniform.buffers[engine.imageIndex].memory); } } } } } void GameObject3DDefaultDraw(GameObject3D* go){ VkCommandBuffer command = engine.device.commandBuffers[engine.imageIndex]; for(int i=0; i < go->graphObj.gItems.num_shader_packs;i++) { BluePrintPack *blue_pack = &go->graphObj.BluePrints.blue_print_packs[i]; if(go->graphObj.render_point == engine.current_render) { RenderTexture *render = engine.current_render; ShaderPack *pack = &go->graphObj.gItems.shader_packs[i]; /*if(render->type == TIGOR_RENDER_TYPE_CUBEMAP){ mat4 res = MakeLookRender(render->currFrame, blue_pack->descriptors[j].indx_layer); vkCmdPushConstants( command, pack->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(mat4), &res); }*/ PipelineSetting *settings = &blue_pack->setting; uint32_t num_instances = 1; uint32_t num_verts = go->graphObj.shapes[settings->vert_indx].vParam.num_verts; if(num_verts == 0) continue; vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipeline)pack->pipeline.pipeline); if(settings->flags & TIGOR_PIPELINE_FLAG_DYNAMIC_VIEW){ vkCmdSetViewport(command, 0, 1, (const VkViewport *)&settings->viewport); vkCmdSetScissor(command, 0, 1, (const VkRect2D *)&settings->scissor); } vkCmdBindDescriptorSets(command, VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipelineLayout)pack->pipeline.layout, 0, 1, (const VkDescriptorSet *)&pack->descriptor.descr_sets[engine.imageIndex], 0, NULL); if(num_verts > 0) { VkBuffer vertexBuffers[] = {go->graphObj.shapes[settings->vert_indx].vParam.buffer.buffer}; VkDeviceSize offsets[] = {0}; // Binding point 0 : Mesh vertex buffer vkCmdBindVertexBuffers(command, VERTEX_BUFFER_BIND_ID, 1, vertexBuffers, offsets); if(go->num_instances > 0){ // Binding point 1 : Instance data buffer vkCmdBindVertexBuffers(command, INSTANCE_BUFFER_BIND_ID, 1, (const VkBuffer *)&go->buffer.buffer, offsets); num_instances = go->num_instances; } } if(num_instances == 0) continue; if(settings->flags & TIGOR_PIPELINE_FLAG_DRAW_INDEXED && go->graphObj.shapes[settings->vert_indx].iParam.indexesSize > 0){ vkCmdBindIndexBuffer(command, go->graphObj.shapes[settings->vert_indx].iParam.buffer.buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdDrawIndexed(command, go->graphObj.shapes[settings->vert_indx].iParam.indexesSize, num_instances, 0, 0, 0); }else vkCmdDraw(command, go->graphObj.shapes[settings->vert_indx].vParam.num_verts, num_instances, 0, 0); } } } void GameObject3DAddDescriptor(GameObject3D* go, uint32_t shader_indx, uint32_t size, uint32_t stage_bit, UpdateDescriptor Updater, uint32_t layer_indx){ BluePrintAddUniformObject(&go->graphObj.BluePrints, shader_indx, size, stage_bit, Updater, layer_indx); } void GameObject3DAddDescriptorTexture(GameObject3D* go, uint32_t shader_indx, uint32_t stage_bit, GameObjectImage *image){ BluePrintAddTextureImage(&go->graphObj.BluePrints, shader_indx, image, stage_bit); } void GameObject3DSetDescriptorUpdate(GameObject3D* go, uint32_t shader_indx, uint32_t bind_index, UpdateDescriptor Updater){ BluePrintAddSomeUpdater(&go->graphObj.BluePrints, shader_indx, bind_index, Updater); } void GameObject3DSetDescriptorTexture(GameObject3D* go, uint32_t shader_indx, uint32_t bind_index, Texture2D *texture){ BluePrintSetTextureImage(&go->graphObj.BluePrints, shader_indx, texture, bind_index); } void *GameObject3DSetDescriptorTextureCreate(GameObject3D* go, uint32_t shader_indx, uint32_t bind_index, GameObjectImage *image){ return BluePrintSetTextureImageCreate(&go->graphObj.BluePrints, shader_indx, image, bind_index); } void GameObject3DSetDescriptorTextureArrayCreate(GameObject3D* go, uint32_t shader_indx, uint32_t bind_index, GameObjectImage *image, uint32_t size){ BluePrintAddTextureImageArrayCreate(&go->graphObj.BluePrints, shader_indx, image, size, bind_index); } void GameObject3DSetShader(GameObject3D *go, char *vert_path, char *frag_path){ char *currPath = DirectGetCurrentFilePath(); int len = strlen(currPath); currPath[len] = '\\'; char *full_path_vert = ToolsMakeString(currPath, vert_path); if(!DirectIsFileExist(full_path_vert)){ FreeMemory(full_path_vert); FreeMemory(currPath); return; } char *full_path_frag = ToolsMakeString(currPath, frag_path); if(!DirectIsFileExist(full_path_vert)){ FreeMemory(full_path_vert); FreeMemory(full_path_frag); FreeMemory(currPath); return; } uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderObject vert_code = ReadSPIRVFile(full_path_vert); vert_code.flags |= TIGOR_SHADER_OBJECT_READED; ShaderObject frag_code = ReadSPIRVFile(full_path_frag); frag_code.flags |= TIGOR_SHADER_OBJECT_READED; GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_code, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_code, num_pack); FreeMemory(currPath); FreeMemory(full_path_vert); FreeMemory(full_path_frag); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; } uint32_t GameObject3DSetShaderSimple(GameObject3D *go, char *vert_path, char *frag_path){ if(go->self.flags & TIGOR_GAME_OBJECT_FLAG_SHADED) return 0; char *currPath = DirectGetCurrentFilePath(); int len = strlen(currPath); char *full_path_vert = ToolsMakePath(currPath, vert_path); if(!DirectIsFileExist(full_path_vert)){ FreeMemory(full_path_vert); FreeMemory(currPath); return 0; } char *full_path_frag = ToolsMakePath(currPath, frag_path); if(!DirectIsFileExist(full_path_vert)){ FreeMemory(full_path_vert); FreeMemory(full_path_frag); FreeMemory(currPath); return 0; } uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderObject vert_code = ReadSPIRVFile(full_path_vert); vert_code.flags |= TIGOR_SHADER_OBJECT_READED; ShaderObject frag_code = ReadSPIRVFile(full_path_frag); frag_code.flags |= TIGOR_SHADER_OBJECT_READED; GraphicsObjectSetShader(&go->graphObj, &vert_code, num_pack, VK_SHADER_STAGE_VERTEX_BIT); GraphicsObjectSetShader(&go->graphObj, &frag_code, num_pack, VK_SHADER_STAGE_FRAGMENT_BIT); FreeMemory(currPath); FreeMemory(full_path_vert); FreeMemory(full_path_frag); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; return num_pack; } void GameObject3DSetGLSLShaderForMemory(GameObject3D *go, char *nameOfCache, char *vert_code, char *frag_code){ ShaderBuilder *variable = NULL; ShaderCache *cache = ShadersFind(nameOfCache, NULL, 0); if(cache == NULL){ cache = ShadersMakeLiteNewShader(nameOfCache); uint32_t res = ShadersMakeThatShaderBuilderFromMemory(vert_code, cache->vertShader, SHADER_TYPE_VERTEX); if(res) return; res = ShadersMakeThatShaderBuilderFromMemory(frag_code, cache->fragShader, SHADER_TYPE_FRAGMENT); if(res) return; cache = ShadersFind(nameOfCache, NULL, 0); } uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderObject vert_shader = {0}; variable = cache->vertShader; vert_shader.code = (char *)variable->code; vert_shader.size = variable->size * sizeof(uint32_t); ShaderObject frag_shader = {0}; variable = cache->fragShader; frag_shader.code = (char *)variable->code; frag_shader.size = variable->size * sizeof(uint32_t); GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_shader, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_shader, num_pack); GameObject3DSetDescriptorUpdate(go, num_pack, 0, (UpdateDescriptor)GameObject3DDescriptorModelUpdate); if(go->num_diffuses > 0) GameObject3DSetDescriptorTextureCreate(go, num_pack, 1, go->diffuses); else GameObject3DSetDescriptorTextureCreate(go, num_pack, 1, NULL); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; } uint32_t GameObject3DSetGLSLShaderForMemorySimple(GameObject3D *go, char *nameOfCache, char *vert_code, char *frag_code){ ShaderBuilder *variable = NULL; ShaderCache *cache = ShadersFind(nameOfCache, NULL, 0); if(cache == NULL){ cache = ShadersMakeLiteNewShader(nameOfCache); uint32_t res = ShadersMakeThatShaderBuilderFromMemory(vert_code, cache->vertShader, SHADER_TYPE_VERTEX); if(res) return 0xFFFFFFFF; res = ShadersMakeThatShaderBuilderFromMemory(frag_code, cache->fragShader, SHADER_TYPE_FRAGMENT); if(res) return 0xFFFFFFFF; cache = ShadersFind(nameOfCache, NULL, 0); } uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderObject vert_shader = {0}; variable = cache->vertShader; vert_shader.code = (char *)variable->code; vert_shader.size = variable->size * sizeof(uint32_t); ShaderObject frag_shader = {0}; variable = cache->fragShader; frag_shader.code = (char *)variable->code; frag_shader.size = variable->size * sizeof(uint32_t); GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_shader, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_shader, num_pack); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; return num_pack; } void GameObject3DSetGLSLShader(GameObject3D *go, char *nameOfCache, char *vert_path, char *frag_path){ char *currPath = DirectGetCurrentFilePath(); char *full_path_vert = ToolsMakePath(currPath, vert_path); if(!full_path_vert || !DirectIsFileExist(full_path_vert)){ if(full_path_vert) FreeMemory(full_path_vert); if(currPath) FreeMemory(currPath); return; } char *full_path_frag = ToolsMakePath(currPath, frag_path); if(!full_path_frag || !DirectIsFileExist(full_path_frag)){ if(full_path_vert) FreeMemory(full_path_vert); if(full_path_frag) FreeMemory(full_path_frag); if(currPath) FreeMemory(currPath); return; } ShaderBuilder *variable = NULL; ShaderCache *cache = ShadersFind(nameOfCache, NULL, 0); if(cache == NULL){ cache = ShadersMakeLiteNewShader(nameOfCache); uint32_t res = ShadersMakeThatShaderBuilder(full_path_vert, cache->vertShader, SHADER_TYPE_VERTEX); if(res) return; res = ShadersMakeThatShaderBuilder(full_path_frag, cache->fragShader, SHADER_TYPE_FRAGMENT); if(res) return; cache = ShadersFind(nameOfCache, NULL, 0); } uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderObject vert_code = {0}; variable = cache->vertShader; vert_code.code = (char *)variable->code; vert_code.size = variable->size * sizeof(uint32_t); ShaderObject frag_code = {0}; variable = cache->fragShader; frag_code.code = (char *)variable->code; frag_code.size = variable->size * sizeof(uint32_t); GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_code, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_code, num_pack); GameObject3DSetDescriptorUpdate(go, num_pack, 0, (UpdateDescriptor)GameObject3DDescriptorModelUpdate); if(go->num_diffuses > 0) GameObject3DSetDescriptorTextureCreate(go, num_pack, 1, go->diffuses); else GameObject3DSetDescriptorTextureCreate(go, num_pack, 1, NULL); FreeMemory(currPath); FreeMemory(full_path_vert); FreeMemory(full_path_frag); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; } uint32_t GameObject3DSetGLSLShaderSimple(GameObject3D *go, char *nameOfCache, char *vert_path, char *frag_path){ char *currPath = DirectGetCurrentFilePath(); char *full_path_vert = ToolsMakePath(currPath, vert_path); if(!full_path_vert || !DirectIsFileExist(full_path_vert)){ if(full_path_vert) FreeMemory(full_path_vert); if(currPath) FreeMemory(currPath); return 0xFFFFFFFF; } char *full_path_frag = ToolsMakePath(currPath, frag_path); if(!full_path_frag || !DirectIsFileExist(full_path_frag)){ if(full_path_vert) FreeMemory(full_path_vert); if(full_path_frag) FreeMemory(full_path_frag); if(currPath) FreeMemory(currPath); return 0xFFFFFFFF; } ShaderBuilder *variable = NULL; ShaderCache *cache = ShadersFind(nameOfCache, NULL, 0); if(cache == NULL){ cache = ShadersMakeLiteNewShader(nameOfCache); uint32_t res = ShadersMakeThatShaderBuilder(full_path_vert, cache->vertShader, SHADER_TYPE_VERTEX); if(res) return 0xFFFFFFFF; res = ShadersMakeThatShaderBuilder(full_path_frag, cache->fragShader, SHADER_TYPE_FRAGMENT); if(res) return 0xFFFFFFFF; cache = ShadersFind(nameOfCache, NULL, 0); } uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderObject vert_code = {0}; variable = cache->vertShader; vert_code.code = (char *)variable->code; vert_code.size = variable->size * sizeof(uint32_t); ShaderObject frag_code = {0}; variable = cache->fragShader; frag_code.code = (char *)variable->code; frag_code.size = variable->size * sizeof(uint32_t); GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_code, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_code, num_pack); FreeMemory(currPath); FreeMemory(full_path_vert); FreeMemory(full_path_frag); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; return num_pack; } void GameObject3DInitDefaultShader(GameObject3D *go){ if(go->self.flags & TIGOR_GAME_OBJECT_FLAG_SHADED) return; uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderCache *shader = ShadersFind("3DDefault", (uint32_t []){ ERROR_TEXTURE_ENABLE ? true : go->num_diffuses > 0 }, 1); if(shader == NULL){ ShadersMakeDefault3DShader(ERROR_TEXTURE_ENABLE ? true : go->num_diffuses > 0); shader = ShadersFind("3DDefault", (uint32_t []){ ERROR_TEXTURE_ENABLE ? true : go->num_diffuses > 0 }, 1); } ShaderBuilder *vert = (ShaderBuilder *)shader->vertShader; ShaderBuilder *frag = (ShaderBuilder *)shader->fragShader; ShaderObject vert_shader, frag_shader; memset(&vert_shader, 0, sizeof(ShaderObject)); memset(&frag_shader, 0, sizeof(ShaderObject)); vert_shader.code = (char *)vert->code; vert_shader.size = vert->size * sizeof(uint32_t); frag_shader.code = (char *)frag->code; frag_shader.size = frag->size * sizeof(uint32_t); GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_shader, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_shader, num_pack); GameObject3DSetDescriptorUpdate(go, num_pack, 0, (UpdateDescriptor)GameObject3DDescriptorModelUpdate); if(go->num_diffuses > 0) GameObject3DSetDescriptorTextureCreate(go, num_pack, 1, go->diffuses); else GameObject3DSetDescriptorTextureCreate(go, num_pack, 1, NULL); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; } void GameObject3DInitDefaultLightShader(GameObject3D *go){ if(go->self.flags & TIGOR_GAME_OBJECT_FLAG_SHADED) return; uint32_t num_pack = BluePrintInit(&go->graphObj.BluePrints); ShaderCache *shader = ShadersFind("3DDefaultLight", (uint32_t []){ ERROR_TEXTURE_ENABLE ? true : go->num_diffuses > 0, go->num_normals > 0, go->num_speculars > 0 }, 3); if(shader == NULL){ ShadersMakeDefault3DShaderWithLight(ERROR_TEXTURE_ENABLE ? true : go->num_diffuses > 0, go->num_normals > 0, go->num_speculars > 0); shader = ShadersFind("3DDefaultLight", (uint32_t []){ ERROR_TEXTURE_ENABLE ? true : go->num_diffuses > 0, go->num_normals > 0, go->num_speculars > 0 }, 3); } ShaderBuilder *vert = (ShaderBuilder *)shader->vertShader; ShaderBuilder *frag = (ShaderBuilder *)shader->fragShader; ShaderObject vert_shader, frag_shader; memset(&vert_shader, 0, sizeof(ShaderObject)); memset(&frag_shader, 0, sizeof(ShaderObject)); vert_shader.code = (char *)vert->code; vert_shader.size = vert->size * sizeof(uint32_t); frag_shader.code = (char *)frag->code; frag_shader.size = frag->size * sizeof(uint32_t); GraphicsObjectSetShaderWithUniform(&go->graphObj, &vert_shader, num_pack); GraphicsObjectSetShaderWithUniform(&go->graphObj, &frag_shader, num_pack); GameObject3DSetDescriptorUpdate(go, num_pack, 0, (UpdateDescriptor)GameObject3DDescriptorModelUpdate); GameObject3DSetDescriptorUpdate(go, num_pack, 1, (UpdateDescriptor)GameObject3DDescriptorLightUpdate); if(go->num_diffuses > 0) GameObject3DSetDescriptorTextureCreate(go, num_pack, 2, go->diffuses); else GameObject3DSetDescriptorTextureCreate(go, num_pack, 2, NULL); if(go->num_normals > 0) GameObject3DSetDescriptorTextureCreate(go, num_pack, 3, go->normals); if(go->num_speculars > 0) GameObject3DSetDescriptorTextureCreate(go, num_pack, 4, go->speculars); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_SHADED; } void GameObject3DInitDraw(GameObject3D *go){ if(!(go->self.flags & TIGOR_GAME_OBJECT_FLAG_SHADED)) return; if(go->self.flags & TIGOR_GAME_OBJECT_FLAG_INIT) return; GraphicsObjectCreateDrawItems(&go->graphObj); PipelineCreateGraphics(&go->graphObj); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_INIT; } void GameObject3DInitDefault(GameObject3D *go){ if(go->self.flags & TIGOR_GAME_OBJECT_FLAG_INIT) return; GameObjectShaderInit((GameObject *)go); GameObject3DInitDraw(go); } void GameObject3DClean(GameObject3D* go){ GraphicsObjectClean(&go->graphObj); } void GameObject3DRecreate(GameObject3D* go){ for(int i=0; i < go->graphObj.gItems.num_shader_packs;i++) { BluePrintPack *pack = &go->graphObj.BluePrints.blue_print_packs[i]; PipelineSetting *settings = &pack->setting; settings->scissor.offset.x = 0; settings->scissor.offset.y = 0; settings->scissor.extent.height = engine.height; settings->scissor.extent.width = engine.width; settings->viewport.x = 0; settings->viewport.y = 0; settings->viewport.height = engine.height; settings->viewport.width = engine.width; } BuffersRecreateUniform((BluePrints *)&go->graphObj.BluePrints); GraphicsObjectCreateDrawItems(&go->graphObj); PipelineCreateGraphics(&go->graphObj); } void GameObject3DDestroy(GameObject3D* go){ if(go->self.flags & TIGOR_GAME_OBJECT_FLAG_DESTROYED) return; GraphicsObjectDestroy(&go->graphObj); if(go->num_diffuses > 0){ for(int i=0;i < go->num_diffuses;i++) { if(go->diffuses[i].size > 0) FreeMemory(go->diffuses[i].buffer); } FreeMemory(go->diffuses); } if(go->num_normals > 0){ for(int i=0;i < go->num_normals;i++) { if(go->normals[i].size > 0) FreeMemory(go->normals[i].buffer); } FreeMemory(go->normals); } if(go->num_speculars > 0){ for(int i=0;i < go->num_speculars;i++) { if(go->speculars[i].size > 0) FreeMemory(go->speculars[i].buffer); } FreeMemory(go->speculars); } if(go->num_instances > 0) BuffersDestroyer(&go->buffer); tigor_mutex_destroy(go->self.mutex); FreeMemory(go->instances); go->self.flags = TIGOR_GAME_OBJECT_FLAG_DESTROYED; } int GameObject3DInitTextures(GameObject3D *go, DrawParam *dParam) { if(dParam == NULL) return 0; char *currPath = DirectGetCurrentFilePath(); int len = strlen(currPath); if(dParam->diffuse != NULL){ if(strlen(dParam->diffuse) != 0) { char *full_path = ToolsMakePath(currPath, dParam->diffuse); if(!DirectIsFileExist(full_path)){ FreeMemory(full_path); FreeMemory(currPath); return 0; } go->diffuses = AllocateMemory(1, sizeof(GameObjectImage)); strcpy(go->diffuses[0].path, full_path); //go->image->buffer = ToolsLoadImageFromFile(&go->image->size, dParam.filePath); go->num_diffuses ++; FreeMemory(full_path); } } if(dParam->normal != NULL){ if(strlen(dParam->normal) != 0) { char *full_path = ToolsMakePath(currPath, dParam->normal); if(!DirectIsFileExist(full_path)){ FreeMemory(full_path); FreeMemory(currPath); go->self.flags |= TIGOR_GAME_OBJECT_FLAG_ERROR_IMAGE; return 0; } go->normals = AllocateMemory(1, sizeof(GameObjectImage)); strcpy(go->normals[0].path, full_path); //go->image->buffer = ToolsLoadImageFromFile(&go->image->size, dParam.filePath); go->num_normals ++; FreeMemory(full_path); } } if(dParam->specular != NULL){ if(strlen(dParam->specular) != 0) { char *full_path = ToolsMakePath(currPath, dParam->normal); if(!DirectIsFileExist(full_path)){ FreeMemory(full_path); FreeMemory(currPath); return 0; } go->speculars = AllocateMemory(1, sizeof(GameObjectImage)); strcpy(go->speculars[0].path, full_path); //go->image->buffer = ToolsLoadImageFromFile(&go->image->size, dParam.filePath); go->num_speculars ++; FreeMemory(full_path); } } FreeMemory(currPath); return 1; } void GameObject3DTextureFromRender(GameObject3D *go, void *render){ BluePrintAddRenderImage(&go->graphObj.BluePrints, 0, render, 2); } void GameObject3DInit(GameObject3D *go, GameObjectType type){ memset(go, 0, sizeof(GameObject3D)); tigor_mutex_init((tigor_mutex_t **)&go->self.mutex, 0, NULL); GameObjectSetInitFunc((GameObject *)go, (void *)GameObject3DInitDefault); GameObjectSetUpdateFunc((GameObject *)go, (void *)GameObject3DDefaultUpdate); GameObjectSetDrawFunc((GameObject *)go, (void *)GameObject3DDefaultDraw); GameObjectSetCleanFunc((GameObject *)go, (void *)GameObject3DClean); GameObjectSetRecreateFunc((GameObject *)go, (void *)GameObject3DRecreate); GameObjectSetDestroyFunc((GameObject *)go, (void *)GameObject3DDestroy); GameObjectSetShaderInitFunc((GameObject *)go, (void *)GameObject3DInitDefaultLightShader); go->self.obj_type = type; go->self.flags = 0; Transform3DInit(&go->transform); go->num_instances = 0; switch(type){ case TIGOR_GAME_OBJECT_TYPE_3D: GraphicsObjectInit(&go->graphObj, TIGOR_VERTEX_TYPE_3D_OBJECT); break; case TIGOR_GAME_OBJECT_TYPE_PARTICLE_3D: GraphicsObjectInit(&go->graphObj, TIGOR_VERTEX_TYPE_3D_PARTICLE); break; case TIGOR_GAME_OBJECT_TYPE_MODEL: GraphicsObjectInit(&go->graphObj, TIGOR_VERTEX_TYPE_MODEL_OBJECT); break; } go->graphObj.gItems.perspective = true; go->self.flags = 0; } void GameObject3DSetRender(GameObject3D *go, void *render){ go->graphObj.render_point = render; } void GameObject3DAddInstance(GameObject3D *go, VertexInstance3D vertex){ if(go->num_instances + 1 >= MAX_INSTANCES){ printf("Слишком много инстансов!\n"); return; } go->instances[go->num_instances] = vertex; go->num_instances ++; } void GameObject3DSetInstance(GameObject3D *go, uint32_t indx, VertexInstance3D vertex){ go->instances[indx] = vertex; } void GameObject3DRemoveInstance(GameObject3D *go, uint32_t indx){ if(go->num_instances <= indx) return; VertexInstance3D instances[MAX_INSTANCES]; memcpy(instances, go->instances, sizeof(VertexInstance3D) * MAX_INSTANCES); memset(go->instances, 0, sizeof(VertexInstance3D) * MAX_INSTANCES); go->num_instances --; uint32_t iter = 0; for(int i=0;i < go->num_instances;i++) { if(i != indx){ go->instances[iter] = instances[i]; iter++; } } } void GameObject3DInitInstances(GameObject3D *go){ VkDeviceSize bufferSize; uint16_t num_verts = go->graphObj.shapes[0].vParam.num_verts; GraphicsObjectInit(&go->graphObj, TIGOR_VERTEX_TYPE_3D_INSTANCE); num_verts = go->graphObj.shapes[0].vParam.num_verts; go->instances = AllocateMemory(MAX_INSTANCES, sizeof(VertexInstance3D)); bufferSize = sizeof(VertexInstance3D) * MAX_INSTANCES; BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &go->buffer, TIGOR_BUFFER_ALLOCATE_VERTEX); } void GameObject3DUpdateInstances(GameObject3D *go){ BufferObject stagingBuffer; VkDeviceSize bufferSize; bufferSize = sizeof(VertexInstance3D) * MAX_INSTANCES; BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffer, TIGOR_BUFFER_ALLOCATE_STAGING); //Изменение памяти void* data; vkMapMemory(engine.device.e_device, stagingBuffer.memory, 0, bufferSize, 0, &data); memset(data, 0, bufferSize); memcpy(data, go->instances, (size_t) go->num_instances * sizeof(VertexInstance3D)); vkUnmapMemory(engine.device.e_device, stagingBuffer.memory); //------------- BuffersCopy(&stagingBuffer, &go->buffer, bufferSize); BuffersDestroyer(&stagingBuffer); } void GameObject3DEnableLight(GameObject3D *go, bool enable) { if(enable) go->self.flags |= TIGOR_GAME_OBJECT_FLAG_LIGHT; else go->self.flags &= ~(TIGOR_GAME_OBJECT_FLAG_LIGHT); }