void PLYObject::draw() { // setup default material glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess); glColor3fv(diffuse); // set lighting if enabled // Otherwise, compute colors if (light) { glEnable(GL_LIGHTING); } else { glDisable(GL_LIGHTING); for (int v=0; v<nv; v++) { // Instead of this, use the Phong illumination equation to find the color // Phong equation with attenuation factor att // If = (As*Am) + ((Al*Am) + Id + Is) * att // Get ModelView float M[16]; Matrix4f modelViewMatrix; glGetFloatv(GL_MODELVIEW_MATRIX, M); for (int i = 0; i < 3; i++) { modelViewMatrix[i][3] = 0.0; modelViewMatrix[3][i] = 0.0; for (int j = 0; j < 3; j++) { modelViewMatrix[i][j] = M[i*4+j]; } } modelViewMatrix[3][3] = 1.0; // ModelView is already here in a Matrix4f for operations Vector3f vVertex; multVector(vVertex, modelViewMatrix, vertices[v]); Vector4f lightSource; copy(lightSource, light_pos); //glGetLightfv(GL_LIGHT0, GL_POSITION, lightSource); Vector3f lightDir; sub(lightDir, lightSource, vVertex); float d = length(lightDir); // Get parameters for the ambient part float Al[4] = {0.0f, 0.0f, 0.0f, 0.0f }; glGetLightfv( GL_LIGHT0, GL_AMBIENT, Al ); Vector4f As = {0.0f, 0.0f, 0.0f, 0.0f }; glGetFloatv( GL_LIGHT_MODEL_AMBIENT, As ); float Dl[4] = {0.0f, 0.0f, 0.0f, 0.0f }; glGetLightfv( GL_LIGHT0, GL_DIFFUSE, Dl ); float Sl[4] = {0.0f, 0.0f, 0.0f, 0.0f }; glGetLightfv( GL_LIGHT0, GL_SPECULAR, Sl ); Vector4f Am = {0.0f, 0.0f, 0.0f, 0.0f }; copy(Am, ambient); float Dm[4] = {0.0f, 0.0f, 0.0f, 0.0f }; copy(Dm, diffuse); float Sm[4] = {0.0f, 0.0f, 0.0f, 0.0f }; copy(Sm, specular); float f = shininess[0]; // copy shininess float constantAttenuation = 0.0f; glGetLightfv( GL_LIGHT0, GL_CONSTANT_ATTENUATION, &constantAttenuation); float linearAttenuation = 0.0f; glGetLightfv( GL_LIGHT0, GL_LINEAR_ATTENUATION , &linearAttenuation ); float quadraticAttenuation = 0.0f; glGetLightfv( GL_LIGHT0, GL_QUADRATIC_ATTENUATION , &quadraticAttenuation); float att = (constantAttenuation + (linearAttenuation*d) + (quadraticAttenuation*d*d) ); // Start the phong equation with the ambient component Vector4f temp1; multVectors4(temp1, As, Am); Vector4f temp2; multVectors4(temp2, Al, Am); scale4(temp2, att); Vector4f final_color; //final_color = (As * Am) + (Al * Am)*att; add(final_color, temp1, temp2); // Calculate lambertTerm Vector3f N; normalizeVector(N, normals[v]); Vector3f L; normalizeVector(L, lightDir); float lambertTerm = dotProd(N,L); if (lambertTerm > 0.0){ // diffuse component multVectors4(temp1,Dl,Dm); scale4(temp1,lambertTerm); add(final_color, final_color, temp1); // specular component Vector3f E; normalizeVector(E,viewer_pos); Vector3f R; scale4(temp1,lambertTerm*2,N); sub(R, temp1, L); // reflect(-L,N) float dotProduct = dotProd(R,E); float specular_factor; if(dotProduct > 0.0){ specular_factor = pow(dotProduct, f); } else { specular_factor = 0; // pow(0.0, f); } multVectors4(temp1, Sl, Sm); scale4(temp1, specular_factor*att, temp1); add(final_color, final_color, temp1); // printf("DM are %f , %f and %f", final_color[0], final_color[1], final_color[2]); } //Colors [v][i] should take the colors of final_color, how? colors[v][0] = final_color[0]*255; colors[v][1] = final_color[1]*255; colors[v][2] = final_color[2]*255; } } // Now do the actual drawing of the model glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_TRIANGLES); for (int i = 0; i < nf; i++) { for (int j = 0; j < 3; j++) { glColor3ubv((GLubyte*)colors[faces[i][j]]); glNormal3fv(normals[faces[i][j]]); // vertex normal glVertex3fv(vertices[faces[i][j]]); // vertex coordinates } } glEnd(); glDisable(GL_POLYGON_OFFSET_FILL); if (hascolor) glDisable(GL_COLOR_MATERIAL); }
void ExportRegions() { int counter = 0; int dim_x = g_mapInfo.width / g_mapInfo.visTableWidth; int dim_y = g_mapInfo.height / g_mapInfo.visTableWidth; Msg("World size:\n [%dx%d] vis cells\n [%dx%d] regions\n", g_mapInfo.width, g_mapInfo.height, dim_x, dim_y); // print region map to console for(int i = 0; i < g_numRegionOffsets; i++, counter++) { // Debug information: Print the map to the console. Msg(g_regionOffsets[i] == REGION_EMPTY ? "." : "O"); if(counter == dim_x) { Msg("\n"); counter = 0; } } Msg("\n"); int numCellObjectsRead = 0; IFile* objFile = NULL; IFile* levModelFile = NULL; objFile = GetFileSystem()->Open(varargs("%s_CELLPOS_MAP.obj", g_levname.c_str()), "wb", SP_ROOT); levModelFile = GetFileSystem()->Open(varargs("%s_LEVELMODEL.obj", g_levname.c_str()), "wb", SP_ROOT); levModelFile->Print("mtllib %s_LEVELMODEL.mtl\r\n", g_levname.c_str()); int lobj_first_v = 0; int lobj_first_t = 0; // 2d region map // easy seeking for(int y = 0; y < dim_y; y++) { for(int x = 0; x < dim_x; x++) { int sPosIdx = y*dim_x + x; if(g_regionOffsets[sPosIdx] == REGION_EMPTY) continue; // determine region position int region_pos_x = x * 65536; int region_pos_z = y * 65536; // region at offset Spool* spool = (Spool*)((ubyte*)g_regionSpool + g_regionOffsets[sPosIdx]); Msg("---------\nSpool %d %d (offset: %d)\n", x, y, g_regionOffsets[sPosIdx]); Msg("offset: %d\n",spool->offset); Msg("connected areas offset: %d\n",spool->connected_areas); Msg("connected areas count: %d\n",spool->num_connected_areas); Msg("pvs block size: %d\n",spool->pvs_size); //Msg("padding: %d %d\n",spool->_padding,spool->_padding2); Msg("cell data size: %d\n",spool->cell_data_size); Msg("super regions: %d\n",spool->super_region); Msg("roadm size: %d\n",spool->roadm_size); Msg("roadh size: %d\n",spool->roadh_size); int cellsOffset = g_levInfo.spooldata_offset + 2048 * (spool->offset + spool->pvs_size + spool->cell_data_size); if(g_region_format.GetInt() == 2) // driver 2 demo { cellsOffset = g_levInfo.spooldata_offset + 2048 * (spool->offset + spool->pvs_size + spool->cell_data_size + spool->roadm_size ); } else if(g_region_format.GetInt() == 1) // driver 1 { ASSERT(!"diferrent packed cells used?\n"); } Msg("cell objects ofs: %d\n", cellsOffset); RegionModels_t* regModels = NULL; // if region data is available, load models and textures if(spool->super_region != SUPERREGION_NONE) { regModels = &g_regionModels[spool->super_region]; bool isNew = (regModels->modelRefs.numElem() == 0); LoadRegionData(g_levStream, regModels, &g_regionDataDescs[spool->super_region], &g_regionPages[spool->super_region]); if( g_export_models.GetBool() && isNew ) { // export region models for(int i = 0; i < regModels->modelRefs.numElem(); i++) { int mod_indxex = regModels->modelRefs[i].index; EqString modelFileName = varargs("%s/ZREG%d_MOD_%d", g_levname_moddir.c_str(), spool->super_region, mod_indxex); if(g_model_names[mod_indxex].GetLength()) modelFileName = varargs("%s/ZREG%d_%d_%s", g_levname_moddir.c_str(), spool->super_region, i, g_model_names[mod_indxex]); // export model ExportDMODELToOBJ(regModels->modelRefs[i].model, modelFileName.c_str(), regModels->modelRefs[i].index); } } } // seek to cells g_levStream->Seek(cellsOffset, VS_SEEK_SET); int cell_count = 0; objFile->Print("#--------\r\n# region %d %d (ofs=%d)\r\n", x, y, cellsOffset); objFile->Print("g cell_%d\r\n", sPosIdx); PACKED_CELL_OBJECT object; do { g_levStream->Read(&object, 1, sizeof(PACKED_CELL_OBJECT)); // bad hack, need to parse visibility data for it if( (0x4544 == object.pos_x && 0x2153 == object.addidx_pos_y) || (0x4809 == object.pos_x && 0x4809 == object.addidx_pos_y) || (0xA608 == object.pos_x && 0xA608 == object.addidx_pos_y) ||cell_count >= 8192) break; // unpack cell CELL_OBJECT cell; UnpackCellObject(object, cell); if(objFile) { objFile->Print("# m %d r %d\r\n", cell.modelindex, cell.rotation); objFile->Print("v %g %g %g\r\n", (region_pos_x+cell.x)*-0.00015f, cell.y*-0.00015f, (region_pos_z+cell.z)*0.00015f); } if(cell.modelindex >= g_levelModels.numElem()) { Msg("cell model index invalid: %d\n", cell.modelindex); cell_count++; continue; } MODEL* model = FindModelByIndex(cell.modelindex, regModels); if(!model) break; // transform objects and save Matrix4x4 transform = translate(Vector3D((region_pos_x+cell.x)*-0.00015f, cell.y*-0.00015f, (region_pos_z+cell.z)*0.00015f)); transform = transform * rotateY4(cell.rotation / 64.0f*PI_F*2.0f) * scale4(1.0f,1.0f,1.0f); WriteMODELToObjStream(levModelFile, model, cell.modelindex, false, transform, &lobj_first_v, &lobj_first_t, regModels); cell_count++; }while(true); MsgInfo("cell_count = %d\n", cell_count); if(objFile) { objFile->Print("# total region cells %d\r\n", cell_count); } numCellObjectsRead += cell_count; } } GetFileSystem()->Close(objFile); GetFileSystem()->Close(levModelFile); int numCellsObjectsFile = g_mapInfo.numAllObjects - g_mapInfo.numStraddlers; if(numCellObjectsRead != numCellsObjectsFile) MsgError("numAllObjects mismatch: in file: %d, read %d\n", numCellsObjectsFile, numCellObjectsRead); }