int setup(void) { GLuint major, minor; GLint success; GLuint model_id; srand( (unsigned)time( NULL ) ); // Make sure required functionality is available! if (!getGLversion( &major, &minor)) return -1; if (major < 2) { printf("<!> OpenGL 2.0 or higher is required\n"); return -1; } windowpos = IsExtSupported("GL_ARB_window_pos"); // Make sure required functionality is available! if (!(IsExtSupported("GL_ARB_vertex_program"))) { printf("<!> ARB vertex program extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_fragment_program"))) { printf("<!> ARB fragment program extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_vertex_shader"))) { printf("<!> ARB vertex shader extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_fragment_shader"))) { printf("<!> ARB fragment shader extension not supported\n"); return -1; } if (!(IsExtSupported("GL_EXT_framebuffer_object"))) { printf("<!> Framebuffer object extension not supported\n"); return -1; } //Define extension prointers glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glXGetProcAddressARB("glGenFramebuffersEXT"); glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glXGetProcAddressARB("glBindFramebufferEXT"); glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glXGetProcAddressARB("glFramebufferTexture2DEXT"); glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glXGetProcAddressARB("glGenRenderbuffersEXT"); glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glXGetProcAddressARB("glBindRenderbufferEXT"); glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glXGetProcAddressARB("glRenderbufferStorageEXT"); glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glXGetProcAddressARB("glFramebufferRenderbufferEXT"); glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glXGetProcAddressARB("glDeleteFramebuffersEXT"); glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glXGetProcAddressARB("glDeleteRenderbuffersEXT"); glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glXGetProcAddressARB("glCheckFramebufferStatusEXT"); if ( !glGenFramebuffersEXT || !glBindFramebufferEXT || !glFramebufferTexture2DEXT || !glGenRenderbuffersEXT || !glBindRenderbufferEXT || !glRenderbufferStorageEXT || !glFramebufferRenderbufferEXT || !glDeleteFramebuffersEXT || !glDeleteRenderbuffersEXT || !glCheckFramebufferStatusEXT ) { printf("<!> Required extension not supported\n"); return -1; } //Enable smooth shading glShadeModel(GL_SMOOTH); //Enable depth testing glEnable(GL_DEPTH_TEST); glPolygonOffset( scalePoly, biasPoly ); //Enable backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace( GL_CW ); //Background color (Ligth blue) glClearColor(0.0f, 0.4f, 0.8f, 1.0f); //Generate texture objects texture_id = (GLuint *)malloc( NUM_TEXTURES * sizeof(GLuint) ); glGenTextures( NUM_TEXTURES, texture_id ); // Enable Anisotropic filtering (for 2D textures only) if( enable_anisotropic ) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisoLevel); if( AnisoLevel > MaxAnisoLevel) AnisoLevel = MaxAnisoLevel; if( print_info ) printf("<-> %.0fX anisotropic filtering enabled\n", AnisoLevel); } else AnisoLevel = 0.0f; // Enable FSAA if (enable_fsaa) glEnable(GL_MULTISAMPLE); //Load MD2 models and textures for (model_id = 0; model_id < NUM_MODELS; ++model_id) { // Load the .md2 model if ( (md2_model[model_id] = (MD2_MODEL_PTR)malloc(sizeof(MD2_MODEL))) == NULL) { printf("<!> Unable to allocate memory for MD2 model in %s\n", filename[3*model_id]); return -1; } if ( !LoadMD2(md2_model[model_id], filename[3*model_id]) ) { printf("<!> Unable to load MD2 model from %s\n", filename[3*model_id]); return -1; } if( print_info ) printf("<-> Loaded MD2 model from \"%s\" for model #%d\n", filename[3*model_id], model_id); // Load texture from disk if ( !LoadImageFromDisk(md2_model[model_id]->skin, filename[3*model_id+1]) ) { printf("<!> Unable to load texture from %s \n", filename[3*model_id+1]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\" for model #%d\n", filename[3*model_id+1], model_id); //Set up model texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id]); 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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, md2_model[model_id]->skin->components, md2_model[model_id]->skin->width, md2_model[model_id]->skin->height, 0, md2_model[model_id]->skin->format, GL_UNSIGNED_BYTE, md2_model[model_id]->skin->data); // Load normal from disk if ( !LoadImageFromDisk(md2_model[model_id]->normal, filename[3*model_id+2]) ) { printf("<!> Unable to load texture from %s \n", filename[3*model_id+2]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\" for model #%d\n", filename[3*model_id+2], model_id); //Set up model texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id+1]); 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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, md2_model[model_id]->normal->components, md2_model[model_id]->normal->width, md2_model[model_id]->normal->height, 0, md2_model[model_id]->normal->format, GL_UNSIGNED_BYTE, md2_model[model_id]->normal->data); } // Load floor texture from disk floor_texture = (IMAGE_PTR)malloc(sizeof(IMAGE)); floor_texture->data = NULL; if ( !LoadImageFromDisk(floor_texture, filename[3*NUM_MODELS]) ) { printf("<!> Unable to load texture from %s\n", filename[3*NUM_MODELS]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\"\n", filename[3*NUM_MODELS]); //Set up floor texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (enable_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, AnisoLevel); glTexImage2D( GL_TEXTURE_2D, 0, floor_texture->components, floor_texture->width, floor_texture->height, 0, floor_texture->format, GL_UNSIGNED_BYTE, floor_texture->data); if (floor_texture->data) { free(floor_texture->data); floor_texture->data = NULL; } // Load floor normal map from disk floor_texture = (IMAGE_PTR)malloc(sizeof(IMAGE)); floor_texture->data = NULL; if ( !LoadImageFromDisk(floor_texture, filename[3*NUM_MODELS+1]) ) { printf("<!> Unable to load texture from %s\n", filename[3*NUM_MODELS+1]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\"\n", filename[3*NUM_MODELS+1]); //Set up floor texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (enable_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, AnisoLevel); glTexImage2D( GL_TEXTURE_2D, 0, floor_texture->components, floor_texture->width, floor_texture->height, 0, floor_texture->format, GL_UNSIGNED_BYTE, floor_texture->data); if (floor_texture->data) { free(floor_texture->data); floor_texture->data = NULL; } // Load and compile low-level shaders glGenProgramsARB(NUM_SHADERS, ids); if (!CompileShader(GL_VERTEX_PROGRAM_ARB, ids[0], DATA_DIR "data/shaders/light.vp")) return -1; if (!CompileShader(GL_FRAGMENT_PROGRAM_ARB, ids[1], DATA_DIR "data/shaders/lightMasked.fp")) return -1; // Create program object and compile GLSL shaders progObj = glCreateProgramObjectARB(); if (!CompileGLSLshaders(&progObj, DATA_DIR "data/shaders/bumpTBN_SH_VP.glsl", DATA_DIR "data/shaders/bumpTBN_SH_FP.glsl", GL_FALSE)) return -1; // Retrieve uniform and attributes locations glUseProgramObjectARB(progObj); colorMap = glGetUniformLocationARB(progObj, "colorMap"); bumpMap = glGetUniformLocationARB(progObj, "bumpMap"); shadowMap = glGetUniformLocationARB(progObj, "shadowMap"); tangent = glGetAttribLocation(progObj, "tangent"); binormal = glGetAttribLocation(progObj, "binormal"); for (model_id = 0; model_id < NUM_MODELS; ++model_id) { md2_model[model_id]->tangent = tangent; md2_model[model_id]->binormal = binormal; } // Set texture units glUniform1i( colorMap, 0 ); glUniform1i( bumpMap, 1 ); glUniform1i( shadowMap, 2 ); //Validate shaders glValidateProgramARB(progObj); glGetObjectParameterivARB(progObj, GL_OBJECT_VALIDATE_STATUS_ARB, &success); if (!success) { GLbyte infoLog[MAX_INFO_LOG_SIZE]; glGetInfoLogARB(progObj, MAX_INFO_LOG_SIZE, NULL, (char *)infoLog); printf("<!> Error in program validation\n"); printf("Info log: %s\n", infoLog); return -1; } //Disable GLSL and enable low-level shaders glUseProgramObjectARB(0); glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ids[0]); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ids[1]); // Create FrameBuffer if (!CreateFB( shadow_sz, &FBO, &shadow_tx )) return -1; //Prebuild the display lists FList = glGenLists(1); glNewList(FList, GL_COMPILE); DrawGround(); glEndList(); //Init animations and kinematic state md2_model[0]->anim_state = ANIMATION_RUN; md2_model[0]->anim_command = ANIMATION_START; md2_model[0]->delta_rate = 30.f; md2_model[0]->position.x = 85.f; md2_model[0]->position.z = 0.f; md2_model[0]->rotation = 90.f; md2_model[1]->anim_state = ANIMATION_RUN; md2_model[1]->anim_command = ANIMATION_START; md2_model[1]->delta_rate = 30.f; md2_model[1]->position.x = 85.f; md2_model[1]->position.z = 0.f; md2_model[1]->rotation = 90.f; md2_model[2]->anim_state = ANIMATION_STANDING_IDLE; md2_model[2]->anim_command = ANIMATION_START; // Set initial camera position and orientation xCam = 0.0f; yCam = 70.0f; zCam = 200.0f; eCam = -0.35f; aCam = 0.0f; lCam = 0.0f; vCam = 0.0f; dCam = 0.0f; //Set initial light aLit = 0.0f; eLit = 0.75f; // Initialise timer gettimeofday(&tv, NULL); t0 = (double)tv.tv_sec + tv.tv_usec / 1000000.0f; t1 = t0; t2 = t0; return 0; }
/* * Loads in a model for the given name */ model_t * Mod_ForName(char *name, qboolean crash) { model_t *mod; unsigned *buf; int i; if (!name[0]) { ri.Sys_Error(ERR_DROP, "Mod_ForName: NULL name"); } /* inline models are grabbed only from worldmodel */ if (name[0] == '*') { i = (int)strtol(name + 1, (char **)NULL, 10); if ((i < 1) || !r_worldmodel || (i >= r_worldmodel->numsubmodels)) { ri.Sys_Error(ERR_DROP, "bad inline model number"); } return &mod_inline[i]; } /* search the currently loaded models */ for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) { if (!mod->name[0]) { continue; } if (!strcmp(mod->name, name)) { return mod; } } /* find a free model slot spot */ for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) { if (!mod->name[0]) { break; /* free spot */ } } if (i == mod_numknown) { if (mod_numknown == MAX_MOD_KNOWN) { ri.Sys_Error(ERR_DROP, "mod_numknown == MAX_MOD_KNOWN"); } mod_numknown++; } strcpy(mod->name, name); /* load the file */ modfilelen = ri.FS_LoadFile(mod->name, (void **)&buf); if (!buf) { if (crash) { ri.Sys_Error(ERR_DROP, "Mod_NumForName: %s not found", mod->name); } memset(mod->name, 0, sizeof(mod->name)); return NULL; } loadmodel = mod; /* call the apropriate loader */ switch (LittleLong(*(unsigned *)buf)) { case IDALIASHEADER: loadmodel->extradata = Hunk_Begin(0x200000); LoadMD2(mod, buf); break; case IDSPRITEHEADER: loadmodel->extradata = Hunk_Begin(0x10000); LoadSP2(mod, buf); break; case IDBSPHEADER: loadmodel->extradata = Hunk_Begin(0x1000000); Mod_LoadBrushModel(mod, buf); break; default: ri.Sys_Error(ERR_DROP, "Mod_NumForName: unknown fileid for %s", mod->name); break; } loadmodel->extradatasize = Hunk_End(); ri.FS_FreeFile(buf); return mod; }