void TunnelPartDeinit(void) { int i; TunnelFxDeinit(); FreeScene(Scene); for(i=0; i<4; i++) { free(flares[i]); } free(flare_tex); free(tex); }
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) { FreeScene();// Clear old data // Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup. if(pScene == nullptr) return; mScene = pScene;// Copy pointer of new scene. // // Meshes // // Create helper objects for meshes. This allow to render meshes as OpenGL arrays. if(mScene->HasMeshes()) { // Create mesh helpers array. mHelper_Mesh_Quantity = mScene->mNumMeshes; mHelper_Mesh = new SHelper_Mesh*[mScene->mNumMeshes]; // Walk thru the meshes and extract needed data and, also calculate BBox. for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) { aiMesh& mesh_cur = *mScene->mMeshes[idx_mesh]; // // Calculate BBox // SBBox mesh_bbox; BBox_GetFromVertices(mesh_cur.mVertices, mesh_cur.mNumVertices, mesh_bbox); // // Create vertices indices arrays splited by primitive type. // size_t indcnt_p = 0;// points quantity size_t indcnt_l = 0;// lines quantity size_t indcnt_t = 0;// triangles quantity if(mesh_cur.HasFaces()) { // Usual way: all faces are triangles if(mesh_cur.mPrimitiveTypes == aiPrimitiveType_TRIANGLE) { indcnt_t = mesh_cur.mNumFaces; } else { // Calculate count of primitives by types. for(size_t idx_face = 0; idx_face < mesh_cur.mNumFaces; idx_face++) { if(mesh_cur.mFaces[idx_face].mNumIndices == 3) indcnt_t++; else if(mesh_cur.mFaces[idx_face].mNumIndices == 2) indcnt_l++; else if(mesh_cur.mFaces[idx_face].mNumIndices == 1) indcnt_p++; } }// if(mesh_cur.mPrimitiveTypes == aiPrimitiveType_TRIANGLE) else // Create helper mHelper_Mesh[idx_mesh] = new SHelper_Mesh(indcnt_p, indcnt_l, indcnt_t, mesh_bbox); // Fill indices arrays indcnt_p = 0, indcnt_l = 0, indcnt_t = 0;// Reuse variables as indices for(size_t idx_face = 0; idx_face < mesh_cur.mNumFaces; idx_face++) { if(mesh_cur.mFaces[idx_face].mNumIndices == 3) { mHelper_Mesh[idx_mesh]->Index_Triangle[indcnt_t++] = mesh_cur.mFaces[idx_face].mIndices[0]; mHelper_Mesh[idx_mesh]->Index_Triangle[indcnt_t++] = mesh_cur.mFaces[idx_face].mIndices[1]; mHelper_Mesh[idx_mesh]->Index_Triangle[indcnt_t++] = mesh_cur.mFaces[idx_face].mIndices[2]; } else if(mesh_cur.mFaces[idx_face].mNumIndices == 2) { mHelper_Mesh[idx_mesh]->Index_Line[indcnt_l++] = mesh_cur.mFaces[idx_face].mIndices[0]; mHelper_Mesh[idx_mesh]->Index_Line[indcnt_l++] = mesh_cur.mFaces[idx_face].mIndices[1]; } else if(mesh_cur.mFaces[idx_face].mNumIndices == 1) { mHelper_Mesh[idx_mesh]->Index_Point[indcnt_p++] = mesh_cur.mFaces[idx_face].mIndices[0]; } }// for(size_t idx_face = 0; idx_face < mesh_cur.mNumFaces; idx_face++) }// if(mesh_cur.HasFaces()) else { // If mesh has no faces then vertices can be just points set. indcnt_p = mesh_cur.mNumVertices; // Create helper mHelper_Mesh[idx_mesh] = new SHelper_Mesh(indcnt_p, 0, 0, mesh_bbox); // Fill indices arrays for(size_t idx = 0; idx < indcnt_p; idx++) mHelper_Mesh[idx_mesh]->Index_Point[idx] = idx; }// if(mesh_cur.HasFaces()) else }// for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) }// if(mScene->HasMeshes()) // // Scene BBox // // For calculating right BBox we must walk thru all nodes and apply transformation to meshes BBoxes if(mHelper_Mesh_Quantity > 0) { bool first_assign = true; aiMatrix4x4 mat_root; BBox_GetForNode(*mScene->mRootNode, mat_root, mScene_BBox, first_assign); mScene_Center = mScene_BBox.Maximum + mScene_BBox.Minimum; mScene_Center /= 2; } else { mScene_BBox = {{0, 0, 0}, {0, 0, 0}}; mScene_Center = {0, 0, 0}; }// if(mHelper_Mesh_Count > 0) else // // Textures // ImportTextures(pScenePath); // // Light sources // Lighting_Enable(); // If scene has no lights then enable default if(!mScene->HasLights()) { const GLfloat col_amb[4] = { 0.2, 0.2, 0.2, 1.0 }; SLightParameters lp; lp.Type = aiLightSource_POINT; lp.Ambient.r = col_amb[0], lp.Ambient.g = col_amb[1], lp.Ambient.b = col_amb[2], lp.Ambient.a = col_amb[3]; lp.Diffuse = { 1.0, 1.0, 1.0, 1.0 }; lp.Specular = lp.Diffuse; lp.For.Point.Position = mScene_Center; lp.For.Point.Attenuation_Constant = 1; lp.For.Point.Attenuation_Linear = 0; lp.For.Point.Attenuation_Quadratic = 0; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col_amb); Lighting_EditSource(0, lp); emit SceneObject_LightSource("_default");// Light source will be enabled in signal handler. } else { for(size_t idx_light = 0; idx_light < mScene->mNumLights; idx_light++) { SLightParameters lp; QString name; const aiLight& light_cur = *mScene->mLights[idx_light]; auto col3_to_col4 = [](const aiColor3D& pCol3) -> aiColor4D { return aiColor4D(pCol3.r, pCol3.g, pCol3.b, 1.0); }; ///TODO: find light source node and apply all transformations // General properties name = light_cur.mName.C_Str(); lp.Ambient = col3_to_col4(light_cur.mColorAmbient); lp.Diffuse = col3_to_col4(light_cur.mColorDiffuse); lp.Specular = col3_to_col4(light_cur.mColorSpecular); lp.Type = light_cur.mType; // Depend on type properties switch(light_cur.mType) { case aiLightSource_DIRECTIONAL: lp.For.Directional.Direction = light_cur.mDirection; break; case aiLightSource_POINT: lp.For.Point.Position = light_cur.mPosition; lp.For.Point.Attenuation_Constant = light_cur.mAttenuationConstant; lp.For.Point.Attenuation_Linear = light_cur.mAttenuationLinear; lp.For.Point.Attenuation_Quadratic = light_cur.mAttenuationQuadratic; break; case aiLightSource_SPOT: lp.For.Spot.Position = light_cur.mPosition; lp.For.Spot.Direction = light_cur.mDirection; lp.For.Spot.Attenuation_Constant = light_cur.mAttenuationConstant; lp.For.Spot.Attenuation_Linear = light_cur.mAttenuationLinear; lp.For.Spot.Attenuation_Quadratic = light_cur.mAttenuationQuadratic; lp.For.Spot.CutOff = light_cur.mAngleOuterCone; break; case aiLightSource_AMBIENT: lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0; name.append("_unsup_ambient"); break; case aiLightSource_AREA: lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0; name.append("_unsup_area"); break; case aiLightSource_UNDEFINED: lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0; name.append("_unsup_undefined"); break; default: lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0; name.append("_unsupported_invalid"); break; }// switch(light_cur.mType) // Add light source if(name.isEmpty()) name += QString("%1").arg(idx_light);// Use index if name is empty. Lighting_EditSource(idx_light, lp); emit SceneObject_LightSource(name);// Light source will be enabled in signal handler. }// for(size_t idx_light = 0; idx_light < mScene->mNumLights; idx_light++) }// if(!mScene->HasLights()) else // // Cameras // if(!mScene->HasCameras()) { mCamera_DefaultAdded = true; mHelper_CameraDefault.SetDefault(); // Calculate distance from camera to scene. Distance must be enoguh for that viewport contain whole scene. const GLfloat tg_angle = tan(mCamera_FOVY / 2); GLfloat val_x = ((mScene_BBox.Maximum.x - mScene_BBox.Minimum.x) / 2) / (mCamera_Viewport_AspectRatio * tg_angle); GLfloat val_y = ((mScene_BBox.Maximum.y - mScene_BBox.Minimum.y) / 2) / tg_angle; GLfloat val_step = val_x; AssignIfGreater(val_step, val_y); mHelper_CameraDefault.Translation_ToScene.Set(mScene_Center.x, mScene_Center.y, val_step + mScene_BBox.Maximum.z); emit SceneObject_Camera("_default"); } else { mCamera_DefaultAdded = false; for(size_t idx_cam = 0; idx_cam < mScene->mNumCameras; idx_cam++) { emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str()); } }// if(!mScene->HasCameras()) else }
CGLView::~CGLView() { FreeScene(); }