void MyWeapon::HLSL(){ device->getVideoDriver(); c8* vsFileName = 0; // filename for the vertex shader c8* psFileName = 0; // filename for the pixel shader video::E_DRIVER_TYPE driverType ; driverType=drv->getDriverType(); switch(driverType) { case video::EDT_DIRECT3D9: psFileName = "hlsleffect/xbjWeapon.hlsl"; vsFileName = psFileName; // both shaders are in the same file break; default: return; break; } //检查硬件是否支持着色 if (!drv->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && !drv->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)) { device->getLogger()->log("WARNING: Pixel shaders disabled "\ "because of missing driver/hardware support."); psFileName = 0; } if (!drv->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && !drv->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) { device->getLogger()->log("WARNING: Vertex shaders disabled "\ "because of missing driver/hardware support."); vsFileName = 0; } // create materials video::IGPUProgrammingServices* gpu = drv->getGPUProgrammingServices(); if (gpu) { MyShaderCallBack* mc = new MyShaderCallBack(); newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles( getWeaponXBJHLSLFile(device->getFileSystem()), "vertexMain", video::EVST_VS_1_1, getWeaponXBJHLSLFile(device->getFileSystem()), "pixelMain", video::EPST_PS_1_1, mc, video::EMT_TRANSPARENT_ADD_COLOR);//EMT_TRANSPARENT_ADD_COLOR EMT_SOLID mc->drop(); } //给武器加上材质 weaponNode->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); }
void CTerrain::ActivateSplattingTextures(scene::ISceneManager* smgr,f32 Height,f32 Fog,video::SColorf FogColor) { video::IVideoDriver* driver = smgr->getVideoDriver(); s32 newMaterialType1 = 0; video::IGPUProgrammingServices* gpu = smgr->getVideoDriver()->getGPUProgrammingServices(); if (driver->getDriverType() != video::EDT_OPENGL) { //Merci à DeusXL pour son shader :D c8 ShaderFileName[] = "float4x4 mWorldViewProj;\n" \ "float4x4 mWorld;\n" \ "float3 cameraPos;\n" \ "float TerrainHeight;\n" \ "float FogDistance;\n" \ "struct VS_OUTPUT\n" \ "{\n" \ "float4 Position : POSITION;\n" \ "float4 Diffuse : COLOR0;\n" \ "float2 TexCoord1 : TEXCOORD1;\n" \ "};\n" \ "VS_OUTPUT vertexMain( in float4 vPosition : POSITION,in float3 vNormal : NORMAL,float2 texCoord1 : TEXCOORD1)\n" \ "{\n" \ "VS_OUTPUT Output;\n" \ "Output.Position = mul(vPosition, mWorldViewProj);\n" \ "float4 position = mul(vPosition, mWorld);\n" \ "float dist = sqrt ( pow(position.x - cameraPos.x, 2.0f) +\n" \ "pow(position.y - cameraPos.y, 2.0f) +\n" \ "pow(position.z - cameraPos.z, 2.0f));\n" \ "Output.Diffuse = float4(vPosition.y / TerrainHeight, dist / FogDistance, 0.0f, 0.0f);\n" \ "Output.TexCoord1 = texCoord1;\n" \ "return Output;\n" \ "}\n" \ "struct PS_OUTPUT\n" \ "{\n" \ "float4 RGBColor : COLOR0;\n" \ "};\n" \ "sampler2D tex[4];\n" \ "float4 fog;\n" \ "PS_OUTPUT pixelMain( float2 TexCoord1 : TEXCOORD1,float4 Position : POSITION,float4 Diffuse : COLOR0 )\n" \ "{\n" \ "PS_OUTPUT Output;\n" \ "float heightpercent = Diffuse.x;\n" \ "float dist = Diffuse.y;\n" \ "float4 grasscolor = tex2D(tex[0], TexCoord1 * 5.0f) * pow((1.0f - heightpercent), 4.0f);\n" \ "float4 rockcolor = tex2D(tex[1], TexCoord1 * 5.0f) * pow((1.0f - abs(0.5f - heightpercent)), 4.0f);\n" \ "float4 snowcolor = tex2D(tex[2], TexCoord1 * 5.0f) * pow(heightpercent,4.0f);\n" \ "float4 detailcolor = tex2D(tex[3], TexCoord1 * 5.0f) * pow((1.0f - abs(0.7f - heightpercent)), 4.0f);\n" \ "Output.RGBColor = (grasscolor + rockcolor + snowcolor + detailcolor);\n" \ "if (dist >= 0.5f)\n" \ "{\n" \ "Output.RGBColor *= (1.0f - (dist-0.5f));\n" \ "Output.RGBColor += (fog * (dist-0.5f));\n" \ "}\n" \ "return Output;\n" \ "}\n"; if (gpu) { MyShaderCallBack* mc = new MyShaderCallBack(); mc->setSplatScene(smgr,Height,Fog,FogColor); newMaterialType1 = gpu->addHighLevelShaderMaterial( ShaderFileName, "vertexMain", video::EVST_VS_2_0, ShaderFileName, "pixelMain", video::EPST_PS_2_0, mc, video::EMT_SOLID,0); mc->drop(); } } else { c8 ShaderFragment[] = "//\n" \ "// Structure definitions\n" \ "//\n" \ "struct VS_OUTPUT {\n" \ "vec4 Position;\n" \ "vec4 Diffuse;\n" \ "vec2 TexCoord1;\n" \ "};\n" \ "struct PS_OUTPUT {\n" \ "vec4 RGBColor;\n" \ "};\n" \ "//\n" \ "// Global variable definitions\n" \ "//\n" \ "uniform vec4 fog;\n" \ "uniform sampler2D texgrass,texrock,texsnow,texdetail;\n" \ "//\n" \ "// Function declarations\n" \ "//\n" \ "PS_OUTPUT pixelMain( in vec2 TexCoord1, in vec4 Position, in vec4 Diffuse );\n" \ "//\n" \ "// Function definitions\n" \ "//\n" \ "PS_OUTPUT pixelMain( in vec2 TexCoord1, in vec4 Position, in vec4 Diffuse ) {\n" \ "float heightpercent;\n" \ "float dist;\n" \ "vec4 grasscolor;\n" \ "vec4 rockcolor;\n" \ "vec4 snowcolor;\n" \ "vec4 detailcolor;\n" \ "PS_OUTPUT Output;\n" \ "heightpercent = Diffuse.x ;\n" \ "dist = Diffuse.y ;\n" \ "grasscolor = (texture2D( texgrass, (TexCoord1 * 5.00000)) * pow( (1.00000 - heightpercent), 4.00000));\n" \ "rockcolor = (texture2D( texrock, (TexCoord1 * 5.00000)) * pow( (1.00000 - abs( (0.500000 - heightpercent) )), 4.00000));\n" \ "snowcolor = (texture2D( texsnow, (TexCoord1 * 5.00000)) * pow( heightpercent, 4.00000));\n" \ "detailcolor = (texture2D( texdetail, (TexCoord1 * 5.00000)) * pow( (1.00000 - abs( (0.700000 - heightpercent) )), 4.00000));\n" \ "Output.RGBColor = (((grasscolor + rockcolor) + snowcolor) + detailcolor);\n" \ "if ( (dist >= 0.500000) ){\n" \ "Output.RGBColor *= (1.00000 - (dist - 0.500000));\n" \ "Output.RGBColor += (fog * (dist - 0.500000));\n" \ "}\n" \ "return Output;\n" \ "}\n" \ "//\n" \ "// Translator's entry point\n" \ "//\n" \ "void main() {\n" \ "PS_OUTPUT xlat_retVal;\n" \ "xlat_retVal = pixelMain( vec2(gl_TexCoord[1]), vec4(gl_FragCoord), vec4(gl_Color));\n" \ "gl_FragData[0] = vec4( xlat_retVal.RGBColor);\n" \ "}\n"; c8 ShaderVertex[]= "//\n" \ "// Structure definitions\n" \ "//\n" \ "struct VS_OUTPUT {\n" \ "vec4 Position;\n" \ "vec4 Diffuse;\n" \ "vec2 TexCoord1;\n" \ "};\n" \ "struct PS_OUTPUT {\n" \ "vec4 RGBColor;\n" \ "};\n" \ "//\n" \ "// Global variable definitions\n" \ "//\n" \ "uniform float FogDistance;\n" \ "uniform float TerrainHeight;\n" \ "uniform vec3 cameraPos;\n" \ "uniform mat4 mWorld;\n" \ "uniform mat4 mWorldViewProj;\n" \ "//\n" \ "// Function declarations\n" \ "//\n" \ "VS_OUTPUT vertexMain( in vec4 vPosition, in vec3 vNormal, in vec2 texCoord1 );\n" \ "//\n" \ "// Function definitions\n" \ "//\n" \ "VS_OUTPUT vertexMain( in vec4 vPosition, in vec3 vNormal, in vec2 texCoord1 ) {\n" \ "VS_OUTPUT Output;\n" \ "vec4 position;\n" \ "float dist;\n" \ "Output.Position = ( vPosition * mWorldViewProj );\n" \ "position = ( vPosition * mWorld );\n" \ "dist = sqrt( ((pow( (position.x - cameraPos.x ), 2.00000) + pow( (position.y - cameraPos.y ), 2.00000)) + pow( (position.z - cameraPos.z ), 2.00000)) );\n" \ "Output.Diffuse = vec4( (vPosition.y / TerrainHeight), (dist / FogDistance), 0.000000, 0.000000);\n" \ "Output.TexCoord1 = texCoord1;\n" \ "return Output;\n" \ "}\n" \ "//\n" \ "// Translator's entry point\n" \ "//\n" \ "void main() {\n" \ "VS_OUTPUT xlat_retVal;\n" \ "xlat_retVal = vertexMain( vec4(gl_Vertex), vec3(gl_Normal), vec2(gl_MultiTexCoord1));\n" \ "gl_Position = vec4( xlat_retVal.Position);\n" \ "gl_FrontColor = vec4( xlat_retVal.Diffuse);\n" \ "gl_TexCoord[1] = vec4( xlat_retVal.TexCoord1, 0.0, 0.0);\n" \ "}\n"; if (gpu) { MyShaderCallBack* mc = new MyShaderCallBack(); mc->setSplatScene(smgr,Height,Fog,FogColor); newMaterialType1 = gpu->addHighLevelShaderMaterial( ShaderVertex, "main", video::EVST_VS_1_1, ShaderFragment, "main", video::EPST_PS_1_1, mc, video::EMT_SOLID,0); mc->drop(); } } setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); }
int main() { // ask user for driver video::E_DRIVER_TYPE driverType= video::EDT_OPENGL;//driverChoiceConsole(); // create device device = createDevice(driverType, core::dimension2d<u32>(1024, 600)); if (device == 0) return 1; // could not create selected driver. video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); gui::IGUIEnvironment* gui = device->getGUIEnvironment(); io::path currentPath = device->getFileSystem()->getAbsolutePath(RESOURCE_PATH); device->getFileSystem()->changeWorkingDirectoryTo(currentPath); /* We only need the right filenames now. This is done in the following switch. Note, that it is not necessary to write the shaders into text files, like in this example. You can even write the shaders directly as strings into the cpp source file, and use later addShaderMaterial() instead of addShaderMaterialFromFiles(). */ io::path vsFileName; // filename for the vertex shader io::path psFileName; // filename for the pixel shader io::path psBloomFileName; // filename for the pixel shader switch(driverType) { case video::EDT_OPENGL: { psBloomFileName = "bloom.frag"; psFileName = "opengl.frag"; vsFileName = "opengl.vert"; } break; } /* In addition, we check if the hardware and the selected renderer is capable of executing the shaders we want. If not, we simply set the filename string to 0. This is not necessary, but useful in this example: For example, if the hardware is able to execute vertex shaders but not pixel shaders, we create a new material which only uses the vertex shader, and no pixel shader. Otherwise, if we would tell the engine to create this material and the engine sees that the hardware wouldn't be able to fullfill the request completely, it would not create any new material at all. So in this example you would see at least the vertex shader in action, without the pixel shader. */ if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && !driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)) { device->getLogger()->log("WARNING: Pixel shaders disabled "\ "because of missing driver/hardware support."); psFileName = ""; } if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) { device->getLogger()->log("WARNING: Vertex shaders disabled "\ "because of missing driver/hardware support."); vsFileName = ""; } /* Now lets create the new materials. As you maybe know from previous examples, a material type in the Irrlicht engine is set by simply changing the MaterialType value in the SMaterial struct. And this value is just a simple 32 bit value, like video::EMT_SOLID. So we only need the engine to create a new value for us which we can set there. To do this, we get a pointer to the IGPUProgrammingServices and call addShaderMaterialFromFiles(), which returns such a new 32 bit value. That's all. The parameters to this method are the following: First, the names of the files containing the code of the vertex and the pixel shader. If you would use addShaderMaterial() instead, you would not need file names, then you could write the code of the shader directly as string. The following parameter is a pointer to the IShaderConstantSetCallBack class we wrote at the beginning of this tutorial. If you don't want to set constants, set this to 0. The last paramter tells the engine which material it should use as base material. To demonstrate this, we create two materials with a different base material, one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR. */ // create materials video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices(); if (gpu) { MyShaderCallBack* mc = new MyShaderCallBack(); // create material from high level shaders (hlsl or glsl) newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", video::EVST_VS_1_1, psFileName, "pixelMain", video::EPST_PS_1_1, mc, video::EMT_SOLID); newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", video::EVST_VS_1_1, psFileName, "pixelMain", video::EPST_PS_1_1, mc, video::EMT_TRANSPARENT_ADD_COLOR); newMaterialBloomType = gpu->addHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", video::EVST_VS_1_1, psBloomFileName, "pixelMain", video::EPST_PS_1_1, mc, video::EMT_TRANSPARENT_ADD_COLOR); mc->drop(); } /* Now it's time for testing the materials. We create a test cube and set the material we created. In addition, we add a text scene node to the cube and a rotation animator to make it look more interesting and important. */ // create test scene node 1, with the new created material type 1 // scene::ISceneNode* node = smgr->addCubeSceneNode(50); // node->setPosition(core::vector3df(0,0,0)); // node->setMaterialTexture(0, driver->getTexture("wall.bmp")); // node->setMaterialFlag(video::EMF_LIGHTING, false); // node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); // // smgr->addTextSceneNode(gui->getBuiltInFont(), // L"PS & VS & EMT_SOLID", // video::SColor(255,255,255,255), node); // // scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator( // core::vector3df(0,0.3f,0)); // node->addAnimator(anim); // anim->drop(); /* Same for the second cube, but with the second material we created. */ // create test scene node 2, with the new created material type 2 // node = smgr->addCubeSceneNode(50); // node->setPosition(core::vector3df(0,-10,50)); // node->setMaterialTexture(0, driver->getTexture("wall.bmp")); // node->setMaterialFlag(video::EMF_LIGHTING, false); // node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2); // // smgr->addTextSceneNode(gui->getBuiltInFont(), // L"PS & VS & EMT_TRANSPARENT", // video::SColor(255,255,255,255), node); // // anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0)); // node->addAnimator(anim); // anim->drop(); /* Then we add a third cube without a shader on it, to be able to compare the cubes. */ // add a scene node with no shader // node = smgr->addCubeSceneNode(50); // node->setPosition(core::vector3df(0,50,25)); // node->setMaterialTexture(0, driver->getTexture("wall.bmp")); // node->setMaterialFlag(video::EMF_LIGHTING, false); // smgr->addTextSceneNode(gui->getBuiltInFont(), L"NO SHADER", // video::SColor(255,255,255,255), node); /* And last, we add a skybox and a user controlled camera to the scene. For the skybox textures, we disable mipmap generation, because we don't need mipmaps on it. */ // add a nice skybox // driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); // // smgr->addSkyBoxSceneNode( // driver->getTexture("irrlicht2_up.jpg"), // driver->getTexture("irrlicht2_dn.jpg"), // driver->getTexture("irrlicht2_lf.jpg"), // driver->getTexture("irrlicht2_rt.jpg"), // driver->getTexture("irrlicht2_ft.jpg"), // driver->getTexture("irrlicht2_bk.jpg")); // // driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true); // add a camera and disable the mouse cursor scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();// addCameraSceneNodeFPS(); cam->setPosition(core::vector3df(-100,0,100)); cam->setTarget(core::vector3df(0,0,0)); device->getCursorControl()->setVisible(false); scene::ISceneNode* bill = smgr->addBillboardSceneNode(0 , core::dimension2d<f32>(256, 150)); bill->setPosition(core::vector3df(-35,0,35)); // 1 , -0.5 , -1 bill->setMaterialFlag(video::EMF_LIGHTING, false); bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); bill->setMaterialTexture(0, driver->getTexture("cameraView.png")); Laser* LaserBeamLumiia = new Laser(0, smgr); device->setEventReceiver(LaserBeamLumiia); ////////////////////////////////////////////////////////////////////////// bill = smgr->addBillboardSceneNode(0 , core::dimension2d<f32>(512, 600)); bill->setPosition(core::vector3df(35,0,-35)); // 1 , -0.5 , -1 bill->setMaterialFlag(video::EMF_LIGHTING, true); bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); bill->setMaterialTexture(0, driver->getTexture("0.jpg")); ////////////////////////////////////////////////////////////////////////// /* Now draw everything. That's all. */ int lastFPS = -1; gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont(); while(device->run()) if (device->isWindowActive()) { driver->beginScene(true, true, video::SColor(255,0,0,0)); smgr->drawAll(); // draw some text if (font) { font->draw(L" Power:100W \n Bandwidht pulse: 5 ms \n Frequency: 1 Hz", core::rect<s32>(130,10,300,50), video::SColor(255,255,255,255)); } driver->endScene(); int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"Surg Sim - Vertex and pixel shader ["; str += driver->getName(); str += "] FPS:"; str += fps; device->setWindowCaption(str.c_str()); lastFPS = fps; } } device->drop(); return 0; }