void draw_3d_object_detail(object3d * object_id, Uint32 material_index, Uint32 use_lightning, Uint32 use_textures, Uint32 use_extra_textures) { e3d_vertex_data* vertex_layout; Uint8 * data_ptr; // check for having to load the arrays load_e3d_detail_if_needed(object_id->e3d_data); CHECK_GL_ERRORS(); //also, update the last time this object was used object_id->last_acessed_time = cur_time; //debug if (object_id->self_lit && (!is_day || dungeon) && use_lightning) { glColor3fv(object_id->color); } CHECK_GL_ERRORS(); glPushMatrix();//we don't want to affect the rest of the scene glMultMatrixf(object_id->matrix); CHECK_GL_ERRORS(); if (!dungeon && (clouds_shadows || use_shadow_mapping) && use_extra_textures) { VECTOR4 plane; ELglActiveTextureARB(detail_unit); memcpy(plane, object_id->clouds_planes[0], sizeof(VECTOR4)); plane[3] += clouds_movement_u; glTexGenfv(GL_S, GL_EYE_PLANE, plane); memcpy(plane, object_id->clouds_planes[1], sizeof(VECTOR4)); plane[3] += clouds_movement_v; glTexGenfv(GL_T, GL_EYE_PLANE, plane); ELglActiveTextureARB(base_unit); } // watch for a change if (object_id->e3d_data != cur_e3d) { if ((cur_e3d != NULL) && (use_compiled_vertex_array)) { ELglUnlockArraysEXT(); } if (use_vertex_buffers) { ELglBindBufferARB(GL_ARRAY_BUFFER_ARB, object_id->e3d_data->vertex_vbo); data_ptr = 0; } else { data_ptr = object_id->e3d_data->vertex_data; } vertex_layout = object_id->e3d_data->vertex_layout; if ((vertex_layout->normal_count > 0) && use_lightning) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(vertex_layout->normal_type, vertex_layout->size, data_ptr + vertex_layout->normal_offset); } else { glDisableClientState(GL_NORMAL_ARRAY); glNormal3f(0.0f, 0.0f, 1.0f); } if (use_textures) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(vertex_layout->texture_count, vertex_layout->texture_type, vertex_layout->size, data_ptr + vertex_layout->texture_offset); } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } glVertexPointer(vertex_layout->position_count, vertex_layout->position_type, vertex_layout->size, data_ptr + vertex_layout->position_offset); if (use_vertex_buffers) { ELglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object_id->e3d_data->indices_vbo); } // lock this new one if (use_compiled_vertex_array) { ELglLockArraysEXT(0, object_id->e3d_data->vertex_no); } // gather statistics if (object_id->e3d_data != cur_e3d) { #ifdef DEBUG if ((cur_e3d_count > 0) && (cur_e3d != NULL)) { e3d_count++; e3d_total += cur_e3d_count; } cur_e3d_count = 0; #endif //DEBUG cur_e3d = object_id->e3d_data; } } #ifdef DEBUG cur_e3d_count++; #endif //DEBUG if (use_textures) { glEnable(GL_TEXTURE_2D); #ifdef NEW_TEXTURES bind_texture(object_id->e3d_data->materials[material_index].texture); #else /* NEW_TEXTURES */ get_and_set_texture_id(object_id->e3d_data->materials[material_index].texture); #endif /* NEW_TEXTURES */ } else { glDisable(GL_TEXTURE_2D); } if (use_draw_range_elements && ELglDrawRangeElementsEXT) ELglDrawRangeElementsEXT(GL_TRIANGLES, object_id->e3d_data->materials[material_index].triangles_indices_min, object_id->e3d_data->materials[material_index].triangles_indices_max, object_id->e3d_data->materials[material_index].triangles_indices_count, object_id->e3d_data->index_type, object_id->e3d_data->materials[material_index].triangles_indices_index); else glDrawElements(GL_TRIANGLES, object_id->e3d_data->materials[material_index].triangles_indices_count, object_id->e3d_data->index_type, object_id->e3d_data->materials[material_index].triangles_indices_index); glPopMatrix();//restore the scene CHECK_GL_ERRORS(); //OK, let's check if our mouse is over... #ifdef MAP_EDITOR2 if (selected_3d_object == -1 && read_mouse_now && mouse_in_sphere(object_id->x_pos, object_id->y_pos, object_id->z_pos, object_id->e3d_data->radius)) anything_under_the_mouse(object_id->id, UNDER_MOUSE_3D_OBJ); #endif }
void display_2d_objects() { unsigned int i, l, start, stop; #ifdef SIMPLE_LOD int dist; int x, y; #endif //SIMPLE_LOD #ifdef CLUSTER_INSIDES_OLD short cluster = get_actor_cluster (); #endif #ifdef SIMPLE_LOD x= -camera_x; y= -camera_y; #endif //SIMPLE_LOD //First draw everyone with the same alpha test #ifdef FSAA if (fsaa > 1) { glEnable(GL_MULTISAMPLE); } #endif /* FSAA */ glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.18f); if (!dungeon && !(!clouds_shadows && !use_shadow_mapping)) { if(clouds_shadows) { //bind the detail texture ELglActiveTextureARB(detail_unit); glEnable(GL_TEXTURE_2D); //glBindTexture(GL_TEXTURE_2D, texture_cache[ground_detail_text].texture_id); bind_texture_unbuffered(ground_detail_text); } ELglActiveTextureARB(base_unit); glEnable(GL_TEXTURE_2D); } get_intersect_start_stop(main_bbox_tree, TYPE_2D_NO_ALPHA_OBJECT, &start, &stop); for (i = start; i < stop; i++) { l = get_intersect_item_ID(main_bbox_tree, i); #ifdef CLUSTER_INSIDES_OLD if (obj_2d_list[l]->cluster && obj_2d_list[l]->cluster != cluster) // Object is on a different cluster as our actor, don't show it continue; #endif #ifdef SIMPLE_LOD // simple size/distance culling dist= (x-obj_2d_list[l]->x_pos)*(x-obj_2d_list[l]->x_pos) + (y-obj_2d_list[l]->y_pos)*(y-obj_2d_list[l]->y_pos); if(/*dist > 10*10 &&*/ 1000*max2f(obj_2d_list[l]->obj_pointer->x_size, obj_2d_list[l]->obj_pointer->y_size)/(dist) < 5) continue; #endif //SIMPLE_LOD draw_2d_object(obj_2d_list[l]); } //Then draw all that needs a change get_intersect_start_stop(main_bbox_tree, TYPE_2D_ALPHA_OBJECT, &start, &stop); for (i = start; i < stop; i++) { l = get_intersect_item_ID(main_bbox_tree, i); #ifdef SIMPLE_LOD // simple size/distance culling dist= (x-obj_2d_list[l]->x_pos)*(x-obj_2d_list[l]->x_pos) + (y-obj_2d_list[l]->y_pos)*(y-obj_2d_list[l]->y_pos); if(/*dist > 10*10 &&*/ 1000*max2f(obj_2d_list[l]->obj_pointer->x_size, obj_2d_list[l]->obj_pointer->y_size)/(dist) < 5) continue; #endif //SIMPLE_LOD glAlphaFunc(GL_GREATER, obj_2d_list[l]->obj_pointer->alpha_test); draw_2d_object(obj_2d_list[l]); } if (!dungeon && !(!clouds_shadows && !use_shadow_mapping)) { //disable the multitexturing ELglActiveTextureARB(detail_unit); glDisable(GL_TEXTURE_2D); ELglActiveTextureARB(base_unit); } #ifdef FSAA if (fsaa > 1) { glDisable(GL_MULTISAMPLE); } #endif /* FSAA */ glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE }
void cal_render_actor(actor *act, Uint32 use_lightning, Uint32 use_textures, Uint32 use_glow) { struct CalRenderer *pCalRenderer; int meshCount,meshId,submeshCount/*,submeshId, vertexCount*/; float points[1024][3]; static float meshVertices[30000][3]; static float meshNormals[30000][3]; static float meshTextureCoordinates[30000][2]; static CalIndex meshFaces[50000][3]; struct CalSkeleton *skel; struct CalMesh *_mesh; struct CalCoreMesh *_coremesh; struct CalCoreMesh *_weaponmesh; struct CalCoreMesh *_shieldmesh; //int boneid=-1; float reverse_scale; //int glow=-1; if(act->calmodel==NULL) { return;//Wtf!? } skel=CalModel_GetSkeleton(act->calmodel); glPushMatrix(); // actor model rescaling if(actors_defs[act->actor_type].actor_scale != 1.0){ glScalef(actors_defs[act->actor_type].actor_scale, actors_defs[act->actor_type].actor_scale, actors_defs[act->actor_type].actor_scale); } // the dynamic scaling if(act->scale != 1.0f){ glScalef(act->scale,act->scale,act->scale); } #ifdef DYNAMIC_ANIMATIONS if(act->last_anim_update < cur_time) if(act->cur_anim.duration_scale > 0.0f) CalModel_Update(act->calmodel, (((cur_time-act->last_anim_update)*act->cur_anim.duration_scale)/1000.0)); build_actor_bounding_box(act); missiles_rotate_actor_bones(act); if (use_animation_program) { set_transformation_buffers(act); } act->last_anim_update= cur_time; #endif //DYNAMIC_ANIMATIONS // get the renderer of the model #ifdef DEBUG if (render_mesh) { #endif pCalRenderer = CalModel_GetRenderer(act->calmodel); // begin the rendering loop if(CalRenderer_BeginRendering(pCalRenderer)){ // set global OpenGL states if(!act->ghost && act->has_alpha){ glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER,0.06f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //glDisable(GL_CULL_FACE); } // will use vertex arrays, so enable them glEnableClientState(GL_VERTEX_ARRAY); // get the number of meshes meshCount = CalRenderer_GetMeshCount(pCalRenderer); // check for weapons or shields being worn if (act->is_enhanced_model) { if(actors_defs[act->actor_type].weapon[act->cur_weapon].mesh_index!=-1) _weaponmesh=CalCoreModel_GetCoreMesh(actors_defs[act->actor_type].coremodel,actors_defs[act->actor_type].weapon[act->cur_weapon].mesh_index); else _weaponmesh=NULL; if(act->body_parts->shield_meshindex!=-1) _shieldmesh=CalCoreModel_GetCoreMesh(actors_defs[act->actor_type].coremodel,act->body_parts->shield_meshindex); else _shieldmesh=NULL; } else { // non-enhanced never have weapon or shields _weaponmesh=NULL; _shieldmesh=NULL; } // render all meshes of the model for(meshId = 0; meshId < meshCount; meshId++){ // get the number of submeshes submeshCount = CalRenderer_GetSubmeshCount(pCalRenderer,meshId); _mesh=CalModel_GetAttachedMesh(act->calmodel,meshId);//Get current rendered mesh _coremesh=CalMesh_GetCoreMesh(_mesh);//Get the coremesh if(act->is_enhanced_model && (_weaponmesh || _shieldmesh)) { //Special treatment for weapons and shields only for enhanced models int glow=-1; int boneid=-1; if (_coremesh==_weaponmesh) boneid=26;//If it's a weapon snap to WeaponR bone else if (_coremesh==_shieldmesh) boneid=21;//If it's a shield snap to WeaponL bone if (boneid!=-1) { glPushMatrix(); reverse_scale= 1.0/actors_defs[act->actor_type].skel_scale; CalSkeleton_GetBonePoints(skel,&points[0][0]); glTranslatef(points[boneid][0],points[boneid][1],points[boneid][2]); glScalef(reverse_scale,reverse_scale,reverse_scale); glTranslatef(-points[boneid][0],-points[boneid][1],-points[boneid][2]); // find the proper place to bind this object to switch(boneid){ case 26: if(actors_defs[act->actor_type].weapon[act->cur_weapon].glow>0){ glow=actors_defs[act->actor_type].weapon[act->cur_weapon].glow; } break; case 21: if(actors_defs[act->actor_type].shield[act->cur_shield].glow>0){ glow=actors_defs[act->actor_type].shield[act->cur_shield].glow; } default: break; } } // now check for a glowing weapon if(glow>0 && use_glow){ glEnable(GL_COLOR_MATERIAL); glBlendFunc(GL_ONE,GL_SRC_ALPHA); if(!act->ghost && !(act->buffs & BUFF_INVISIBILITY)) { glEnable(GL_BLEND); glDisable(GL_LIGHTING); } if(use_shadow_mapping){ glPushAttrib(GL_TEXTURE_BIT|GL_ENABLE_BIT); ELglActiveTextureARB(shadow_unit); glDisable(depth_texture_target); disable_texgen(); ELglActiveTextureARB(GL_TEXTURE0); } glColor4f(glow_colors[glow].r, glow_colors[glow].g, glow_colors[glow].b, 0.5f); glPushMatrix(); glScalef(0.99f, 0.99f, 0.99f); render_submesh(meshId, submeshCount, pCalRenderer, meshVertices, meshNormals, meshTextureCoordinates, meshFaces, 0, use_textures); glPopMatrix(); glColor4f(glow_colors[glow].r, glow_colors[glow].g, glow_colors[glow].b, 0.85f); render_submesh(meshId, submeshCount, pCalRenderer, meshVertices, meshNormals, meshTextureCoordinates, meshFaces, 0, use_textures); glColor4f(glow_colors[glow].r, glow_colors[glow].g, glow_colors[glow].b, 0.99f); glPushMatrix(); glScalef(1.01f, 1.01f, 1.01f); render_submesh(meshId, submeshCount, pCalRenderer, meshVertices, meshNormals, meshTextureCoordinates, meshFaces, 0, use_textures); glPopMatrix(); if(use_shadow_mapping){ glPopAttrib(); } glColor3f(1.0f, 1.0f, 1.0f); glDisable(GL_COLOR_MATERIAL); if(!act->ghost && !(act->buffs & BUFF_INVISIBILITY)) { glDisable(GL_BLEND); glEnable(GL_LIGHTING); } else { glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); if((act->buffs & BUFF_INVISIBILITY)) { glColor4f(1.0f, 1.0f, 1.0f, 0.25f); } } } else { // enhanced actors without glowing items render_submesh(meshId, submeshCount, pCalRenderer, meshVertices, meshNormals, meshTextureCoordinates, meshFaces, use_lightning, use_textures); } if(boneid >= 0){ //if this was a weapon or shield, restore the transformation matrix glPopMatrix(); } } else { // non-enhanced actors, or enhanced without attached meshes render_submesh(meshId, submeshCount, pCalRenderer, meshVertices, meshNormals, meshTextureCoordinates, meshFaces, use_lightning, use_textures); } } // clear vertex array state glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); if(!act->ghost && act->has_alpha){ glDisable(GL_ALPHA_TEST); //glEnable(GL_CULL_FACE); glDisable(GL_BLEND); } // end the rendering CalRenderer_EndRendering(pCalRenderer); } #ifdef DEBUG } #endif glColor3f(1,1,1); #ifdef DEBUG if(render_skeleton) { glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); cal_render_bones(act); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); } #endif glPopMatrix(); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE }