void opengl_bind_vertex_array(const vertex_layout& layout) { auto iter = Stored_vertex_arrays.find(layout); if (iter != Stored_vertex_arrays.end()) { // Found existing vertex array! GL_state.BindVertexArray(iter->second); return; } GR_DEBUG_SCOPE("Create Vertex array"); GLuint vao; glGenVertexArrays(1, &vao); GL_state.BindVertexArray(vao); for (size_t i = 0; i < layout.get_num_vertex_components(); ++i) { auto component = layout.get_vertex_component(i); auto& bind_info = GL_array_binding_data[component->format_type]; auto& attrib_info = GL_vertex_attrib_info[bind_info.attribute_id]; auto attribIndex = attrib_info.attribute_id; glEnableVertexAttribArray(attribIndex); glVertexAttribFormat(attribIndex, bind_info.size, bind_info.data_type, bind_info.normalized, static_cast<GLuint>(component->offset)); // Currently, all vertex data comes from one buffer. glVertexAttribBinding(attribIndex, 0); } Stored_vertex_arrays.insert(std::make_pair(layout, vao)); }
size_t opengl_get_shader_idx(shader_type shader_t, unsigned int flags) { auto found = GL_shader_map.find(shader_descriptor_t(shader_t, flags)); if (found != GL_shader_map.end()) { return found->second; } return GL_shader.size(); }
void obj_collide_retime_cached_pairs(int checkdly) { SCP_unordered_map<uint, collider_pair>::iterator it; for ( it = Collision_cached_pairs.begin(); it != Collision_cached_pairs.end(); ++it ) { it->second.next_check_time = timestamp(checkdly); } }
void opengl_delete_shader(int sdr_handle) { Assert(sdr_handle >= 0); Assert(sdr_handle < (int)GL_shader.size()); opengl_shader_t &victim = GL_shader[sdr_handle]; GL_shader_map.erase(shader_descriptor_t(victim.shader, victim.flags)); GL_shader[sdr_handle].program.reset(); GL_shader[sdr_handle].flags = 0; GL_shader[sdr_handle].flags2 = 0; GL_shader[sdr_handle].shader = NUM_SHADER_TYPES; }
void opengl_tnl_shutdown() { for (auto& vao_entry : Stored_vertex_arrays) { glDeleteVertexArrays(1, &vao_entry.second); } Stored_vertex_arrays.clear(); gr_opengl_deferred_shutdown(); if ( Shadow_map_depth_texture ) { glDeleteTextures(1, &Shadow_map_depth_texture); Shadow_map_depth_texture = 0; } if ( Shadow_map_texture ) { glDeleteTextures(1, &Shadow_map_texture); Shadow_map_texture = 0; } opengl_destroy_all_buffers(); }
/** * Initializes the shader system. Creates a 1x1 texture that can be used as a fallback texture when framebuffer support is missing. * Also compiles the shaders used for particle rendering. */ void opengl_shader_init() { glGenTextures(1,&Framebuffer_fallback_texture_id); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Framebuffer_fallback_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); GLuint pixels[4] = {0,0,0,0}; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &pixels); GL_shader.clear(); GL_shader_map.clear(); // Reserve 32 shader slots. This should cover most use cases in real life. GL_shader.reserve(32); opengl_purge_old_shader_cache(); // compile effect shaders gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, 0); gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, SDR_FLAG_PARTICLE_POINT_GEN); gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_DISTORTION, 0); gr_opengl_maybe_create_shader(SDR_TYPE_SHIELD_DECAL, 0); // compile deferred lighting shaders gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_LIGHTING, 0); gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_CLEAR, 0); // compile passthrough shader mprintf(("Compiling passthrough shader...\n")); gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0); mprintf(("\n")); }
/** * Go through GL_shader and call glDeleteObject() for all created shaders, then clear GL_shader */ void opengl_shader_shutdown() { GL_shader.clear(); GL_shader_map.clear(); }
void obj_reset_colliders() { Collision_sort_list.clear(); Collision_cached_pairs.clear(); }
int collide_remove_weapons( ) { obj_pair *opp; int i, num_deleted, oldest_index, j, loop_count; float oldest_time; // setup remove_weapon array. assume we can remove it. for (i = 0; i < MAX_WEAPONS; i++ ) { if ( Weapons[i].objnum == -1 ) crw_status[i] = CRW_NO_OBJECT; else crw_status[i] = CRW_NO_PAIR; } // first pass is to see if any of the weapons don't have collision pairs. if ( Cmdline_old_collision_sys ) { opp = &pair_used_list; opp = opp->next; while( opp != NULL ) { // for each collide pair, if the two objects can still collide, then set the remove_weapon // parameter for the weapon to 0. need to check both parameters if ( opp->a->type == OBJ_WEAPON ) crw_check_weapon( opp->a->instance, opp->next_check_time ); if ( opp->b->type == OBJ_WEAPON ) crw_check_weapon( opp->b->instance, opp->next_check_time ); opp = opp->next; } } else { SCP_unordered_map<uint, collider_pair>::iterator it; collider_pair *pair_obj; for ( it = Collision_cached_pairs.begin(); it != Collision_cached_pairs.end(); ++it ) { pair_obj = &it->second; if ( !pair_obj->initialized ) { continue; } if ( pair_obj->a->type == OBJ_WEAPON && pair_obj->signature_a == pair_obj->a->signature ) { crw_check_weapon(pair_obj->a->instance, pair_obj->next_check_time); if ( crw_status[pair_obj->a->instance] == CRW_CAN_DELETE ) { pair_obj->initialized = false; } } if ( pair_obj->b->type == OBJ_WEAPON && pair_obj->signature_b == pair_obj->b->signature ) { crw_check_weapon(pair_obj->b->instance, pair_obj->next_check_time); if ( crw_status[pair_obj->b->instance] == CRW_CAN_DELETE ) { pair_obj->initialized = false; } } } } // for each weapon which could be removed, delete the object num_deleted = 0; for ( i = 0; i < MAX_WEAPONS; i++ ) { if ( crw_status[i] == CRW_CAN_DELETE ) { Assert( Weapons[i].objnum != -1 ); obj_delete( Weapons[i].objnum ); num_deleted++; } } if ( num_deleted ) return num_deleted; // if we didn't remove any weapons, try to the N oldest weapons. first checking for pairs, then // checking for oldest weapons in general. We will go through the loop a max of 2 times. first time // through, we check oldest weapons with pairs, next time through, for oldest weapons. loop_count = 0; do { for ( j = 0; j < CRW_MAX_TO_DELETE; j++ ) { oldest_time = 1000.0f; oldest_index = -1; for (i = 0; i < MAX_WEAPONS; i++ ) { if ( Weapons[i].objnum == -1 ) // shouldn't happen, but this is the safe thing to do. continue; if ( ((loop_count || crw_status[i] == CRW_NO_PAIR)) && (Weapons[i].lifeleft < oldest_time) ) { oldest_time = Weapons[i].lifeleft; oldest_index = i; } } if ( oldest_index != -1 ) { obj_delete(Weapons[oldest_index].objnum); num_deleted++; } } // if we deleted some weapons, then we can break if ( num_deleted ) break; loop_count++; } while ( loop_count < 2); return num_deleted; }