void GLMeshRenderer::DrawLightModel(int arraySize, float deltaSecond, Matrix4x4 perspectiveMatrix, Matrix4x4 viewMatrix, Matrix4x4 modelMatrix, Vector3 lPosition, Vector3 cameraPosition) { ////////////////////////////////////////////////////////////////////////// arraySize; static float totalTime = 0; totalTime += deltaSecond; glUseProgram(m_material.m_program.m_gProgram); GLCheckError(__FILE__, __LINE__); glBindVertexArray(m_VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_mesh.m_iboID); Vector3 cam_position = cameraPosition; Vector3 lightPosition = lPosition; float light_power = 10000.1f; Vector4 ambient_light(1.0f, 1.0f, 1.0f, 0.05f); Vector4 light_color(1.0f, 1.0f, 1.0f, light_power); GLint textureIndex = 0; GLuint m_gBuffer = m_material.m_program.m_gProgram; ProgramBindSamplerIndex(m_gBuffer, "gTexDiffuse", textureIndex); ProgramBindSamplerIndex(m_gBuffer, "gTexNormal", textureIndex + 1); ProgramBindSamplerIndex(m_gBuffer, "gTexSpecGlossEmit", textureIndex + 2); ProgramBindMatrix(m_gBuffer, "gProj", perspectiveMatrix); ProgramBindMatrix(m_gBuffer, "gView", viewMatrix); ProgramBindMatrix(m_gBuffer, "gModel", modelMatrix); ProgramBindVector4(m_gBuffer, "gAmbientLight", ambient_light); ProgramBindVector4(m_gBuffer, "gLightColor", light_color); ProgramBindVector3(m_gBuffer, "gLightPosition", lightPosition); ProgramBindVector3(m_gBuffer, "gCameraPosition", cam_position); if (m_material.m_sampler.gTexDiffuse == nullptr) { unsigned char defaultWhiteTexel[3] = { 255, 255, 255 }; m_material.m_sampler.gTexDiffuse = Texture::CreateMissingTexture("DefaultDiffuse", defaultWhiteTexel, Vector2(1.0f, 1.0f), 3); } ProgramBindTexture(textureIndex, m_material.m_sampler.gTexDiffuse->GetPlatformHandle()); textureIndex++; if (m_material.m_sampler.gTexNormal == nullptr) { unsigned char defaultBlueTexel[3] = { 127, 127, 255 }; m_material.m_sampler.gTexNormal = Texture::CreateMissingTexture("DefaultNormal", defaultBlueTexel, Vector2(1.0f, 1.0f), 3); } ProgramBindTexture(textureIndex, m_material.m_sampler.gTexNormal->GetPlatformHandle()); textureIndex++; if (m_material.m_sampler.gTexSpecGlossEmit == nullptr) { unsigned char defaultYellowTexel[3] = { 127, 127, 0 }; m_material.m_sampler.gTexSpecGlossEmit = Texture::CreateMissingTexture("DefaultSpecGlossEmit", defaultYellowTexel, Vector2(1.0f, 1.0f), 3); } ProgramBindTexture(textureIndex, m_material.m_sampler.gTexSpecGlossEmit->GetPlatformHandle()); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //glDrawArrays(GL_TRIANGLES, 0, m_mesh.m_vboNumBytes); glDrawElements(GL_TRIANGLES,m_mesh.m_iboNumIndexes , GL_UNSIGNED_INT,(void*)0 ); glBindVertexArray(NULL); glUseProgram(NULL); GLCheckError(__FILE__, __LINE__); }
static void color_light(Widget w, XtPointer data, XmAnyCallbackStruct *cbs) { extern Color *light_color(); /* in clights.c */ ui_config_colorpanel("Light Color", light_color(), LIGHTINDEX, DRAWER_LIGHTCOLOR, 0); ui_showpanel(P_COLOR, 1); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::LightVertex(const MLRVertexData& vertexData) { UnitVector3D light_z; GetInShapeDirection(light_z); const Scalar One_Over_255 = 1.f/255.0f; Point3D worldPoint; worldPoint.Multiply(*(vertexData.point), shapeToWorld); Scalar prep_x = mapZoneCountX*zoneSizeX - worldPoint.x + mapOrigin.x; Scalar prep_z = mapZoneCountZ*zoneSizeZ - worldPoint.z + mapOrigin.z; int map_x = Truncate_Float_To_Word(prep_x*one_Over_zoneSizeX); int map_z = Truncate_Float_To_Word(prep_z*one_Over_zoneSizeZ); Verify(map_x>=0 && map_x<mapZoneCountX); Verify(map_z>=0 && map_z<mapZoneCountZ); int off_x = Truncate_Float_To_Word((prep_x - map_x*zoneSizeX)*256.0f*one_Over_zoneSizeX); int off_z = Truncate_Float_To_Word((prep_z - map_z*zoneSizeZ)*256.0f*one_Over_zoneSizeZ); Verify(off_x>=0 && off_x < 256); Verify(off_z>=0 && off_z < 256); Scalar mapIntensity = maps[map_z*mapZoneCountX+map_x][(off_z<<8)+off_x]*One_Over_255; // //------------------------------------------------------------------- // Now we reduce the light level falling on the vertex based upon the // cosine of the angle between light and normal //------------------------------------------------------------------- // Scalar cosine = -(light_z * (*vertexData.normal))*mapIntensity*intensity; #if COLOR_AS_DWORD TO_DO; #else // COLOR_AS_DWORD RGBColor light_color(color); if (cosine > SMALL) { light_color.red *= cosine; light_color.green *= cosine; light_color.blue *= cosine; vertexData.color->red += light_color.red; vertexData.color->green += light_color.green; vertexData.color->blue += light_color.blue; } #endif // COLOR_AS_DWORD }
/** * Renders the AbstractAirspace on the canvas * @param as AbstractAirspace to render */ void Render(const AbstractAirspace& as) { int type = as.get_type(); if (type <= 0) return; // No intersections for this airspace if (m_intersections.empty()) return; // Select pens and brushes #ifdef ENABLE_SDL Color color = Graphics::GetAirspaceColour(settings.colours[type]); #ifdef ENABLE_OPENGL color = color.with_alpha(48); #endif Brush brush(color); #else const Brush &brush = Graphics::GetAirspaceBrushByClass(type, settings); canvas.set_text_color(light_color(Graphics::GetAirspaceColourByClass(type, settings))); #endif PixelRect rcd; // Calculate top and bottom coordinate rcd.top = chart.screenY(as.get_top_altitude(state)); if (as.is_base_terrain()) rcd.bottom = chart.screenY(fixed_zero); else rcd.bottom = chart.screenY(as.get_base_altitude(state)); // Iterate through the intersections for (AirspaceIntersectionVector::const_iterator it = m_intersections.begin(); it != m_intersections.end(); ++it) { const GeoPoint p_start = it->first; const GeoPoint p_end = it->second; const fixed distance_start = start.distance(p_start); const fixed distance_end = start.distance(p_end); // Determine left and right coordinate rcd.left = chart.screenX(distance_start); rcd.right = chart.screenX(distance_end); // only one edge found, next edge must be beyond screen if ((rcd.left == rcd.right) && (p_start == p_end)) { rcd.right = chart.screenX(chart.getXmax()); } // Draw the airspace RenderBox(rcd, brush, settings.black_outline, type); } }
void GLMeshRenderer::DrawLightShader(int arraySize, float deltaSecond, Matrix4x4 perspectiveMatrix, Matrix4x4 viewMatrix,Matrix4x4 modelMatrix,Vector3 lPosition,Vector3 cameraPosition) { ////////////////////////////////////////////////////////////////////////// arraySize; static float totalTime = 0; totalTime += deltaSecond; glUseProgram(m_material.m_program.m_gProgram); GLCheckError(__FILE__, __LINE__); glBindVertexArray(m_VAO); Vector3 cam_position = cameraPosition; Vector3 lightPosition = lPosition; float light_power = 2.1f; Vector4 ambient_light(1.0f, 1.0f, 1.0f, 0.05f); Vector4 light_color(1.0f, 1.0f, 1.0f, light_power); GLint textureIndex = 0; GLuint m_gBuffer = m_material.m_program.m_gProgram; ProgramBindSamplerIndex(m_gBuffer, "gTexDiffuse", textureIndex); ProgramBindSamplerIndex(m_gBuffer, "gTexNormal", textureIndex+1); ProgramBindSamplerIndex(m_gBuffer, "gTexSpecular", textureIndex + 2); ProgramBindSamplerIndex(m_gBuffer, "gTexEmissive", textureIndex + 3); ProgramBindMatrix(m_gBuffer, "gProj", perspectiveMatrix); ProgramBindMatrix(m_gBuffer, "gView", viewMatrix); ProgramBindMatrix(m_gBuffer, "gModel", modelMatrix); ProgramBindVector4(m_gBuffer, "gAmbientLight", ambient_light); ProgramBindVector4(m_gBuffer, "gLightColor", light_color); ProgramBindVector3(m_gBuffer, "gLightPosition", lightPosition); ProgramBindVector3(m_gBuffer, "gCameraPosition", cam_position); ProgramBindTexture(textureIndex, m_material.m_sampler.gTexDiffuse->GetPlatformHandle()); textureIndex++; ProgramBindTexture(textureIndex, m_material.m_sampler.gTexNormal->GetPlatformHandle()); textureIndex++; ProgramBindTexture(textureIndex, m_material.m_sampler.gTexSpecular->GetPlatformHandle()); textureIndex++; ProgramBindTexture(textureIndex, m_material.m_sampler.gTexEmissive->GetPlatformHandle()); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDrawArrays(GL_TRIANGLES, 0, m_mesh.m_vboNumBytes); glBindVertexArray(NULL); glUseProgram(NULL); GLCheckError(__FILE__, __LINE__); }
void Graphics::Initialise() { /// @todo enhancement: support red/green color blind pilots with adjusted colour scheme LogStartUp(_T("Initialise graphics")); LoadUnitSymbols(); hTerrainWarning.load_big(IDB_TERRAINWARNING, IDB_TERRAINWARNING_HD); hGPSStatus1.load_big(IDB_GPSSTATUS1, IDB_GPSSTATUS1_HD, false); hGPSStatus2.load_big(IDB_GPSSTATUS2, IDB_GPSSTATUS2_HD, false); hLogger.load_big(IDB_LOGGER, IDB_LOGGER_HD); hLoggerOff.load_big(IDB_LOGGEROFF, IDB_LOGGEROFF_HD); hCruise.load_big(IDB_CRUISE, IDB_CRUISE_HD, false); hClimb.load_big(IDB_CLIMB, IDB_CLIMB_HD, false); hFinalGlide.load_big(IDB_FINALGLIDE, IDB_FINALGLIDE_HD, false); hAbort.load_big(IDB_ABORT, IDB_ABORT_HD, false); #ifdef HAVE_HATCHED_BRUSH hAboveTerrainBitmap.load(IDB_ABOVETERRAIN); hAboveTerrainBrush.set(hAboveTerrainBitmap); #endif hpWind.set(Layout::Scale(1), dark_color(COLOR_GRAY)); hpWindTail.set(Pen::DASH, 1, COLOR_BLACK); hbWind.set(COLOR_GRAY); hBmpMapScaleLeft.load_big(IDB_MAPSCALE_LEFT, IDB_MAPSCALE_LEFT_HD, false); hBmpMapScaleRight.load_big(IDB_MAPSCALE_RIGHT, IDB_MAPSCALE_RIGHT_HD, false); hBmpTabTask.load((Layout::scale > 1) ? IDB_TASK_HD : IDB_TASK); hBmpTabWrench.load((Layout::scale > 1) ? IDB_WRENCH_HD : IDB_WRENCH); hBmpTabSettings.load((Layout::scale > 1) ? IDB_SETTINGS_HD : IDB_SETTINGS); hBmpTabCalculator.load((Layout::scale > 1) ? IDB_CALCULATOR_HD : IDB_CALCULATOR); hBmpTabFlight.load((Layout::scale > 1) ? IDB_GLOBE_HD : IDB_GLOBE); hBmpTabSystem.load((Layout::scale > 1) ? IDB_DEVICE_HD : IDB_DEVICE); hBmpTabRules.load((Layout::scale > 1) ? IDB_RULES_HD : IDB_RULES); hBmpTabTimes.load((Layout::scale > 1) ? IDB_CLOCK_HD : IDB_CLOCK); hBmpThermalSource.load_big(IDB_THERMALSOURCE, IDB_THERMALSOURCE_HD); hBmpTrafficSafe.load_big(IDB_TRAFFIC_SAFE, IDB_TRAFFIC_SAFE_HD, false); hBmpTrafficWarning.load_big(IDB_TRAFFIC_WARNING, IDB_TRAFFIC_WARNING_HD, false); hBmpTrafficAlarm.load_big(IDB_TRAFFIC_ALARM, IDB_TRAFFIC_ALARM_HD, false); hbCompass.set(Color(207, 207, 207)); hbFinalGlideBelow.set(COLOR_RED); hpFinalGlideBelow.set(Layout::Scale(1), dark_color(COLOR_RED)); hbFinalGlideBelowLandable.set(COLOR_ORANGE); hpFinalGlideBelowLandable.set(Layout::Scale(1), dark_color(COLOR_ORANGE)); hbFinalGlideAbove.set(COLOR_GREEN); hpFinalGlideAbove.set(Layout::Scale(1), dark_color(COLOR_GREEN)); hpCompass.set(Layout::Scale(1), COLOR_GRAY); hpMapScale.set(Layout::Scale(1), COLOR_BLACK); hpTerrainLine.set(Pen::DASH, Layout::Scale(1), clrSepia); hpTerrainLineThick.set(Pen::DASH, Layout::Scale(2), clrSepia); TracePen.set(2, Color(50, 243, 45)); ContestPen[0].set(Layout::Scale(1)+2, COLOR_RED); ContestPen[1].set(Layout::Scale(1)+1, COLOR_ORANGE); ContestPen[2].set(Layout::Scale(1), COLOR_BLUE); // used for landable rendering hbGreen.set(COLOR_GREEN); hbWhite.set(COLOR_WHITE); hbOrange.set(COLOR_ORANGE); hbLightGray.set(COLOR_LIGHT_GRAY); hbNotReachableTerrain.set(light_color(COLOR_RED)); hbGround.set(GroundColor); hpTrackBearingLine.set(3, COLOR_GRAY); }
virtual void updateTexturesAndMeshes(IGameDef *gamedef) { #ifndef SERVER infostream<<"ItemDefManager::updateTexturesAndMeshes(): Updating " <<"textures and meshes in item definitions"<<std::endl; ITextureSource *tsrc = gamedef->getTextureSource(); INodeDefManager *nodedef = gamedef->getNodeDefManager(); IrrlichtDevice *device = tsrc->getDevice(); video::IVideoDriver *driver = device->getVideoDriver(); for(std::map<std::string, ItemDefinition*>::iterator i = m_item_definitions.begin(); i != m_item_definitions.end(); i++) { ItemDefinition *def = i->second; bool need_node_mesh = false; // Create an inventory texture def->inventory_texture = NULL; if(def->inventory_image != "") { def->inventory_texture = tsrc->getTextureRaw(def->inventory_image); } else if(def->type == ITEM_NODE) { need_node_mesh = true; } // Create a wield mesh if(def->wield_mesh != NULL) { def->wield_mesh->drop(); def->wield_mesh = NULL; } if(def->type == ITEM_NODE && def->wield_image == "") { need_node_mesh = true; } else if(def->wield_image != "" || def->inventory_image != "") { // Extrude the wield image into a mesh std::string imagename; if(def->wield_image != "") imagename = def->wield_image; else imagename = def->inventory_image; def->wield_mesh = createExtrudedMesh( tsrc->getTextureRaw(imagename), driver, def->wield_scale * v3f(40.0, 40.0, 4.0)); if(def->wield_mesh == NULL) { infostream<<"ItemDefManager: WARNING: " <<"updateTexturesAndMeshes(): " <<"Unable to create extruded mesh for item " <<def->name<<std::endl; } } if(need_node_mesh) { /* Get node properties */ content_t id = nodedef->getId(def->name); const ContentFeatures &f = nodedef->get(id); u8 param1 = 0; if(f.param_type == CPT_LIGHT) param1 = 0xee; /* Make a mesh from the node */ MeshMakeData mesh_make_data(gamedef); MapNode mesh_make_node(id, param1, 0); mesh_make_data.fillSingleNode(&mesh_make_node); MapBlockMesh mapblock_mesh(&mesh_make_data); scene::IMesh *node_mesh = mapblock_mesh.getMesh(); assert(node_mesh); setMeshColor(node_mesh, video::SColor(255, 255, 255, 255)); /* Scale and translate the mesh so it's a unit cube centered on the origin */ scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); /* Draw node mesh into a render target texture */ if(def->inventory_texture == NULL) { core::dimension2d<u32> dim(64,64); std::string rtt_texture_name = "INVENTORY_" + def->name + "_RTT"; v3f camera_position(0, 1.0, -1.5); camera_position.rotateXZBy(45); v3f camera_lookat(0, 0, 0); core::CMatrix4<f32> camera_projection_matrix; // Set orthogonal projection camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); video::SColorf ambient_light(0.2,0.2,0.2); v3f light_position(10, 100, -50); video::SColorf light_color(0.5,0.5,0.5); f32 light_radius = 1000; def->inventory_texture = generateTextureFromMesh( node_mesh, device, dim, rtt_texture_name, camera_position, camera_lookat, camera_projection_matrix, ambient_light, light_position, light_color, light_radius); // render-to-target didn't work if(def->inventory_texture == NULL) { def->inventory_texture = tsrc->getTextureRaw(f.tname_tiles[0]); } } /* Use the node mesh as the wield mesh */ if(def->wield_mesh == NULL) { // Scale to proper wield mesh proportions scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0) * def->wield_scale); def->wield_mesh = node_mesh; def->wield_mesh->grab(); } // falling outside of here deletes node_mesh } } #endif }
bool generate_image(std::string part_of_name, video::IImage *& baseimg, IrrlichtDevice *device, SourceImageCache *sourcecache) { video::IVideoDriver* driver = device->getVideoDriver(); assert(driver); // Stuff starting with [ are special commands if(part_of_name.size() == 0 || part_of_name[0] != '[') { video::IImage *image = sourcecache->getOrLoad(part_of_name, device); if(image == NULL) { if(part_of_name != ""){ errorstream<<"generate_image(): Could not load image \"" <<part_of_name<<"\""<<" while building texture"<<std::endl; errorstream<<"generate_image(): Creating a dummy" <<" image for \""<<part_of_name<<"\""<<std::endl; } // Just create a dummy image //core::dimension2d<u32> dim(2,2); core::dimension2d<u32> dim(1,1); image = driver->createImage(video::ECF_A8R8G8B8, dim); assert(image); /*image->setPixel(0,0, video::SColor(255,255,0,0)); image->setPixel(1,0, video::SColor(255,0,255,0)); image->setPixel(0,1, video::SColor(255,0,0,255)); image->setPixel(1,1, video::SColor(255,255,0,255));*/ image->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); /*image->setPixel(1,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(0,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(1,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256));*/ } // If base image is NULL, load as base. if(baseimg == NULL) { //infostream<<"Setting "<<part_of_name<<" as base"<<std::endl; /* Copy it this way to get an alpha channel. Otherwise images with alpha cannot be blitted on images that don't have alpha in the original file. */ core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); image->copyTo(baseimg); image->drop(); } // Else blit on base. else { //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl; // Size of the copied area core::dimension2d<u32> dim = image->getDimension(); //core::dimension2d<u32> dim(16,16); // Position to copy the blitted to in the base image core::position2d<s32> pos_to(0,0); // Position to copy the blitted from in the blitted image core::position2d<s32> pos_from(0,0); // Blit image->copyToWithAlpha(baseimg, pos_to, core::rect<s32>(pos_from, dim), video::SColor(255,255,255,255), NULL); // Drop image image->drop(); } } else { // A special texture modification /*infostream<<"generate_image(): generating special " <<"modification \""<<part_of_name<<"\"" <<std::endl;*/ /* This is the simplest of all; it just adds stuff to the name so that a separate texture is created. It is used to make textures for stuff that doesn't want to implement getting the texture from a bigger texture atlas. */ if(part_of_name == "[forcesingle") { // If base image is NULL, create a random color if(baseimg == NULL) { core::dimension2d<u32> dim(1,1); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); assert(baseimg); baseimg->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); } } /* [crackN Adds a cracking texture */ else if(part_of_name.substr(0,6) == "[crack") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } // Crack image number and overlay option s32 progression = 0; bool use_overlay = false; if(part_of_name.substr(6,1) == "o") { progression = stoi(part_of_name.substr(7)); use_overlay = true; } else { progression = stoi(part_of_name.substr(6)); use_overlay = false; } // Size of the base image core::dimension2d<u32> dim_base = baseimg->getDimension(); /* Load crack image. It is an image with a number of cracking stages horizontally tiled. */ video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device); if(img_crack && progression >= 0) { // Dimension of original image core::dimension2d<u32> dim_crack = img_crack->getDimension(); // Count of crack stages s32 crack_count = dim_crack.Height / dim_crack.Width; // Limit progression if(progression > crack_count-1) progression = crack_count-1; // Dimension of a single crack stage core::dimension2d<u32> dim_crack_cropped( dim_crack.Width, dim_crack.Width ); // Create cropped and scaled crack images video::IImage *img_crack_cropped = driver->createImage( video::ECF_A8R8G8B8, dim_crack_cropped); video::IImage *img_crack_scaled = driver->createImage( video::ECF_A8R8G8B8, dim_base); if(img_crack_cropped && img_crack_scaled) { // Crop crack image v2s32 pos_crack(0, progression*dim_crack.Width); img_crack->copyTo(img_crack_cropped, v2s32(0,0), core::rect<s32>(pos_crack, dim_crack_cropped)); // Scale crack image by copying img_crack_cropped->copyToScaling(img_crack_scaled); // Copy or overlay crack image if(use_overlay) { overlay(baseimg, img_crack_scaled); } else { img_crack_scaled->copyToWithAlpha( baseimg, v2s32(0,0), core::rect<s32>(v2s32(0,0), dim_base), video::SColor(255,255,255,255)); } } if(img_crack_scaled) img_crack_scaled->drop(); if(img_crack_cropped) img_crack_cropped->drop(); img_crack->drop(); } } /* [combine:WxH:X,Y=filename:X,Y=filename2 Creates a bigger texture from an amount of smaller ones */ else if(part_of_name.substr(0,8) == "[combine") { Strfnd sf(part_of_name); sf.next(":"); u32 w0 = stoi(sf.next("x")); u32 h0 = stoi(sf.next(":")); infostream<<"combined w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); while(sf.atend() == false) { u32 x = stoi(sf.next(",")); u32 y = stoi(sf.next("=")); std::string filename = sf.next(":"); infostream<<"Adding \""<<filename <<"\" to combined ("<<x<<","<<y<<")" <<std::endl; video::IImage *img = sourcecache->getOrLoad(filename, device); if(img) { core::dimension2d<u32> dim = img->getDimension(); infostream<<"Size "<<dim.Width <<"x"<<dim.Height<<std::endl; core::position2d<s32> pos_base(x, y); video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, dim); img->copyTo(img2); img->drop(); img2->copyToWithAlpha(baseimg, pos_base, core::rect<s32>(v2s32(0,0), dim), video::SColor(255,255,255,255), NULL); img2->drop(); } else { infostream<<"img==NULL"<<std::endl; } } } /* "[brighten" */ else if(part_of_name.substr(0,9) == "[brighten") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } brighten(baseimg); } /* "[noalpha" Make image completely opaque. Used for the leaves texture when in old leaves mode, so that the transparent parts don't look completely black when simple alpha channel is used for rendering. */ else if(part_of_name.substr(0,8) == "[noalpha") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } core::dimension2d<u32> dim = baseimg->getDimension(); // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = baseimg->getPixel(x,y); c.setAlpha(255); baseimg->setPixel(x,y,c); } } /* "[makealpha:R,G,B" Convert one color to transparent. */ else if(part_of_name.substr(0,11) == "[makealpha:") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(11)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next("")); std::string filename = sf.next(""); core::dimension2d<u32> dim = baseimg->getDimension(); /*video::IImage *oldbaseimg = baseimg; baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); oldbaseimg->copyTo(baseimg); oldbaseimg->drop();*/ // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = baseimg->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1)) continue; c.setAlpha(0); baseimg->setPixel(x,y,c); } } /* [inventorycube{topimage{leftimage{rightimage In every subimage, replace ^ with &. Create an "inventory cube". NOTE: This should be used only on its own. Example (a grass block (not actually used in game): "[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png" */ else if(part_of_name.substr(0,14) == "[inventorycube") { if(baseimg != NULL) { errorstream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } str_replace_char(part_of_name, '&', '^'); Strfnd sf(part_of_name); sf.next("{"); std::string imagename_top = sf.next("{"); std::string imagename_left = sf.next("{"); std::string imagename_right = sf.next("{"); // Generate images for the faces of the cube video::IImage *img_top = generate_image_from_scratch( imagename_top, device, sourcecache); video::IImage *img_left = generate_image_from_scratch( imagename_left, device, sourcecache); video::IImage *img_right = generate_image_from_scratch( imagename_right, device, sourcecache); assert(img_top && img_left && img_right); // Create textures from images video::ITexture *texture_top = driver->addTexture( (imagename_top + "__temp__").c_str(), img_top); video::ITexture *texture_left = driver->addTexture( (imagename_left + "__temp__").c_str(), img_left); video::ITexture *texture_right = driver->addTexture( (imagename_right + "__temp__").c_str(), img_right); assert(texture_top && texture_left && texture_right); // Drop images img_top->drop(); img_left->drop(); img_right->drop(); /* Draw a cube mesh into a render target texture */ scene::IMesh* cube = createCubeMesh(v3f(1, 1, 1)); setMeshColor(cube, video::SColor(255, 255, 255, 255)); cube->getMeshBuffer(0)->getMaterial().setTexture(0, texture_top); cube->getMeshBuffer(1)->getMaterial().setTexture(0, texture_top); cube->getMeshBuffer(2)->getMaterial().setTexture(0, texture_right); cube->getMeshBuffer(3)->getMaterial().setTexture(0, texture_right); cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left); cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left); core::dimension2d<u32> dim(64,64); std::string rtt_texture_name = part_of_name + "_RTT"; v3f camera_position(0, 1.0, -1.5); camera_position.rotateXZBy(45); v3f camera_lookat(0, 0, 0); core::CMatrix4<f32> camera_projection_matrix; // Set orthogonal projection camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); video::SColorf ambient_light(0.2,0.2,0.2); v3f light_position(10, 100, -50); video::SColorf light_color(0.5,0.5,0.5); f32 light_radius = 1000; video::ITexture *rtt = generateTextureFromMesh( cube, device, dim, rtt_texture_name, camera_position, camera_lookat, camera_projection_matrix, ambient_light, light_position, light_color, light_radius); // Drop mesh cube->drop(); // Free textures of images driver->removeTexture(texture_top); driver->removeTexture(texture_left); driver->removeTexture(texture_right); if(rtt == NULL) { baseimg = generate_image_from_scratch( imagename_top, device, sourcecache); return true; } // Create image of render target video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim); assert(image); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); if(image) { image->copyTo(baseimg); image->drop(); } } else { errorstream<<"generate_image(): Invalid " " modification: \""<<part_of_name<<"\""<<std::endl; } } return true; }
void MainWindow::render() { glViewport(0, 0, width(), height()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_program->bind(); // GLfloat colors[] = { // 1.0f, 0.0f, 0.0f, // 0.0f, 1.0f, 0.0f, // 0.0f, 0.0f, 1.0f // }; now = clock(); m_frame = m_frame + speed*difftime(now, lastTime); lastTime = now; // Planet Matrix scale.scale(4.0f); rotMatrix.rotate(m_frame * 0.2, 0, 1, 0); cg::Planet sonne("sonne", &myMesh->v[0], scale, rotMatrix, orbitMatrix, orbitRotMatrix); scale.setToIdentity(); orbitRotMatrix.setToIdentity(); orbitMatrix.setToIdentity(); rotMatrix.setToIdentity(); scale.scale(0.5f); orbitRotMatrix.rotate(m_frame, 0, 1, 0); orbitMatrix.translate(5.0f, 0, 0); rotMatrix.rotate(m_frame, 0, 1, 0); cg::Planet erde("erde", &myMesh->v[0], scale, rotMatrix, orbitMatrix, orbitRotMatrix); scale.setToIdentity(); orbitRotMatrix.setToIdentity(); orbitMatrix.setToIdentity(); rotMatrix.setToIdentity(); scale.scale(0.3f); orbitRotMatrix.rotate(m_frame, 0, 1, 0); orbitMatrix.translate(1.0f, 0, 0); rotMatrix.rotate(m_frame, 0, 1, 0); cg::Planet mond("mond", &myMesh->v[0], scale, rotMatrix, orbitMatrix, orbitRotMatrix); scale.setToIdentity(); orbitRotMatrix.setToIdentity(); orbitMatrix.setToIdentity(); rotMatrix.setToIdentity(); scale.scale(0.5f); orbitRotMatrix.rotate(0.5 * m_frame + 15, 0, 1, 0); orbitMatrix.translate(10.0f, 0, 0); rotMatrix.rotate(m_frame, 0, 1, 0); cg::Planet mars("mars", &myMesh->v[0], scale, rotMatrix, orbitMatrix, orbitRotMatrix); scale.setToIdentity(); orbitRotMatrix.setToIdentity(); orbitMatrix.setToIdentity(); rotMatrix.setToIdentity(); scale.scale(0.3f); orbitRotMatrix.rotate(m_frame, 0, 1, 0); orbitMatrix.translate(1.0f, 0, 0); rotMatrix.rotate(m_frame, 0, 1, 0); cg::Planet deimos("deimos", &myMesh->v[0], scale, rotMatrix, orbitMatrix, orbitRotMatrix); scale.setToIdentity(); orbitRotMatrix.setToIdentity(); orbitMatrix.setToIdentity(); rotMatrix.setToIdentity(); scale.scale(0.15f); orbitRotMatrix.rotate(m_frame *15, 0, 1, 0); orbitMatrix.translate(1.0f, 0, 0); rotMatrix.rotate(m_frame, 0, 1, 0); cg::Planet phobos("phobos", &myMesh->v[0], scale, rotMatrix, orbitMatrix, orbitRotMatrix); std::vector<cg::Planet*> vecPlanet {&sonne, &erde, &mond, &mars, &deimos, &phobos}; cg::Sunsystem sys; sys.addChild(&sonne)->addChild(&erde)->addChild(&mond); sys.addChild(&mars)->addChild(&deimos); sys.getChild(1)->addChild(&phobos); sys.run(); projMatrix.setToIdentity(); //projMatrix.perspective(60.f, 4.0f/3.0f, 0.1f, 100.0f); projMatrix.perspective(60.f, width()/height(), 0.1f, 100.0f); viewMatrix.setToIdentity(); viewMatrix.translate(0, 0, -15); viewMatrix.rotate(45, 1, 0, 0); QVector3D ambient(0.2, 0.2, 0.2); QVector3D diffuse_albedo(1.0, 0.88, 0.25); QVector3D specular_albedo(1.0, 1.0, 1.0); GLfloat specular_power = 128.0; QVector3D light_color(0.2, 0.7, 0.2); for(cg::Planet* n : vecPlanet) { m_program->setUniformValue(m_mv_matrix, n->resultmatrix); m_program->setUniformValue(m_view_matrix, viewMatrix); m_program->setUniformValue(m_proj_matrix, projMatrix); m_program->setUniformValue(m_ambient, ambient); m_program->setUniformValue(m_diffuse_albedo, diffuse_albedo); m_program->setUniformValue(m_specular_albedo, specular_albedo); m_program->setUniformValue(m_specular_power, specular_power); for(std::vector<GLfloat>& light : lightPositions) { // Because of QT QVector4D lightPosition (light[0], light[1], light[2], light[3]); m_program->setUniformValue(m_light, lightPosition); m_program->setUniformValue(m_light_color, light_color); glDrawElements(GL_TRIANGLES, myMesh->v_f.size(), GL_UNSIGNED_INT, 0); } } m_program->release(); //Clear Matrices scale.setToIdentity(); orbitRotMatrix.setToIdentity(); orbitMatrix.setToIdentity(); rotMatrix.setToIdentity(); }
ClientCached* createClientCachedDirect(const std::string &name, IGameDef *gamedef) const { infostream<<"Lazily creating item texture and mesh for \"" <<name<<"\""<<std::endl; // This is not thread-safe assert(get_current_thread_id() == m_main_thread); // Skip if already in cache ClientCached *cc = NULL; m_clientcached.get(name, &cc); if(cc) return cc; ITextureSource *tsrc = gamedef->getTextureSource(); INodeDefManager *nodedef = gamedef->getNodeDefManager(); IrrlichtDevice *device = tsrc->getDevice(); video::IVideoDriver *driver = device->getVideoDriver(); const ItemDefinition *def = &get(name); // Create new ClientCached cc = new ClientCached(); bool need_node_mesh = false; // Create an inventory texture cc->inventory_texture = NULL; if(def->inventory_image != "") { cc->inventory_texture = tsrc->getTextureRaw(def->inventory_image); } else if(def->type == ITEM_NODE) { need_node_mesh = true; } // Create a wield mesh assert(cc->wield_mesh == NULL); if(def->type == ITEM_NODE && def->wield_image == "") { need_node_mesh = true; } else if(def->wield_image != "" || def->inventory_image != "") { // Extrude the wield image into a mesh std::string imagename; if(def->wield_image != "") imagename = def->wield_image; else imagename = def->inventory_image; cc->wield_mesh = createExtrudedMesh( tsrc->getTextureRaw(imagename), driver, def->wield_scale * v3f(40.0, 40.0, 4.0)); if(cc->wield_mesh == NULL) { infostream<<"ItemDefManager: WARNING: " <<"updateTexturesAndMeshes(): " <<"Unable to create extruded mesh for item " <<def->name<<std::endl; } } if(need_node_mesh) { /* Get node properties */ content_t id = nodedef->getId(def->name); const ContentFeatures &f = nodedef->get(id); u8 param1 = 0; if(f.param_type == CPT_LIGHT) param1 = 0xee; /* Make a mesh from the node */ MeshMakeData mesh_make_data(gamedef); MapNode mesh_make_node(id, param1, 0); mesh_make_data.fillSingleNode(&mesh_make_node); MapBlockMesh mapblock_mesh(&mesh_make_data); scene::IMesh *node_mesh = mapblock_mesh.getMesh(); assert(node_mesh); video::SColor c(255, 255, 255, 255); if(g_settings->getS32("enable_shaders") != 0) c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source)); setMeshColor(node_mesh, c); /* Scale and translate the mesh so it's a unit cube centered on the origin */ scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); /* Draw node mesh into a render target texture */ if(cc->inventory_texture == NULL) { core::dimension2d<u32> dim(64,64); std::string rtt_texture_name = "INVENTORY_" + def->name + "_RTT"; v3f camera_position(0, 1.0, -1.5); camera_position.rotateXZBy(45); v3f camera_lookat(0, 0, 0); core::CMatrix4<f32> camera_projection_matrix; // Set orthogonal projection camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); video::SColorf ambient_light(0.2,0.2,0.2); v3f light_position(10, 100, -50); video::SColorf light_color(0.5,0.5,0.5); f32 light_radius = 1000; cc->inventory_texture = generateTextureFromMesh( node_mesh, device, dim, rtt_texture_name, camera_position, camera_lookat, camera_projection_matrix, ambient_light, light_position, light_color, light_radius); // render-to-target didn't work if(cc->inventory_texture == NULL) { cc->inventory_texture = tsrc->getTextureRaw(f.tiledef[0].name); } } else { if (m_driver == 0) m_driver = driver; m_extruded_textures.push_back(cc->inventory_texture); } /* Use the node mesh as the wield mesh */ // Scale to proper wield mesh proportions scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0) * def->wield_scale); cc->wield_mesh = node_mesh; cc->wield_mesh->grab(); //no way reference count can be smaller than 2 in this place! assert(cc->wield_mesh->getReferenceCount() >= 2); } // Put in cache m_clientcached.set(name, cc); return cc; }
color_t Shape::phong(const point3d_t p, const point2d_t tc, const point3d_t n, const ray_t *ray) const { const World *world = this->world(); color_t texture = material.texture == 0 ? material.color : material.texture(tc); if(!world) return texture; boost::numeric::ublas::vector<double> color = vector3d(0.0, 0.0, 0.0); boost::numeric::ublas::vector<double> vn = vector3d(n.x, n.y, n.z); boost::numeric::ublas::vector<double> vv = vector3d(-ray->d.x, -ray->d.y, -ray->d.z); double dvn = dot_prod(vv, vn); double nit = 1.0 / material.n; if (dvn < 0.0) { nit = material.n / 1.0; vn = -vn; dvn = dot_prod(vv, vn); } boost::numeric::ublas::vector<double> texture_color = vector3d(texture.r, texture.g, texture.b); boost::numeric::ublas::vector<double> specular_color = vector3d(material.specular.r, material.specular.g, material.specular.b); boost::numeric::ublas::vector<double> ambient_color = vector3d(world->ambient.r, world->ambient.g, world->ambient.b); // ambient color += material.ka * vector3d(ambient_color(0) * texture_color(0), ambient_color(1) * texture_color(1), ambient_color(2) * texture_color(2)); double kr = material.kr; // transmission if(ray->ttl > 0 && material.kt > 0.0 && material.n > 0.0) { double l = 1.0 + nit*nit*(dvn*dvn - 1.0); if(l >= 0.0) { boost::numeric::ublas::vector<double> d = -nit * vv; d += (nit*dvn - sqrt(l)) * vn; d = normalize(d); ray_t transmission_ray; transmission_ray.p = p; transmission_ray.d = POINT3D(d(0), d(1), d(2)); transmission_ray.near = 0.000000001; transmission_ray.far = DOUBLE_INF; transmission_ray.ttl = ray->ttl-1; color_t transmission_color = world->trace(&transmission_ray); color += material.kt * vector3d(transmission_color.r, transmission_color.g, transmission_color.b); } else kr += material.kt; } // reflection if(ray->ttl > 0 && kr > 0.0) { boost::numeric::ublas::vector<double> vr = 2.0 * dot_prod(vv, vn) * vn - vv; ray_t reflection_ray; reflection_ray.p = p; reflection_ray.d = POINT3D(vr(0), vr(1), vr(2)); reflection_ray.near = 0.000001; reflection_ray.far = DOUBLE_INF; reflection_ray.ttl = ray->ttl-1; color_t reflection_color = world->trace(&reflection_ray); color += kr * vector3d(reflection_color.r, reflection_color.g, reflection_color.b); } // lights for(std::vector<Light*>::const_iterator i = world->lights.begin(); i != world->lights.end(); i++) { // shadow ray point3d_t s = (*i)->getSource(); boost::numeric::ublas::vector<double> vs = vector3d(s.x - p.x, s.y - p.y, s.z - p.z); double light_distance = sqrt(dot_prod(vs, vs)); vs = normalize(vs); ray_t shadow_ray; shadow_ray.p = p; shadow_ray.d = POINT3D(vs(0), vs(1), vs(2)); shadow_ray.near = 0.00000001; shadow_ray.far = DOUBLE_INF; shadow_ray.ttl = 1; if(world->hit(&shadow_ray).t < light_distance) continue; light_t light = (*i)->getLight(); boost::numeric::ublas::vector<double> light_color = vector3d(light.color.r, light.color.g, light.color.b); // diffuse color += material.kd * dot_prod(vs, vn) * vector3d(light_color(0) * texture_color(0), light_color(1) * texture_color(1), light_color(2) * texture_color(2)); // specular boost::numeric::ublas::vector<double> vr = 2.0 * dot_prod(vs, vn) * vn - vs; double vra = dot_prod(vr, vv); if(vra >= 0.0) color += material.ks * pow(vra, material.ke) * vector3d(light_color(0) * specular_color(0), light_color(1) * specular_color(1), light_color(2) * specular_color(2)); } // keep color in range if(color(0) > 1.0) color(0) = 1.0; if(color(0) < 0.0) color(0) = 0.0; if(color(1) > 1.0) color(1) = 1.0; if(color(1) < 0.0) color(1) = 0.0; if(color(2) > 1.0) color(2) = 1.0; if(color(2) < 0.0) color(2) = 0.0; return COLOR(color(0), color(1), color(2)); }