[ Pobierz caÅ‚ość w formacie PDF ] .7 Enabling the Lighting Pipeline// Enable Direct3D lighting.lpDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE);If you are using vertex buffers in your application, enabling the lightingpipeline is slightly different.When you call theIDirect3DVertexBuffer7::ProcessVertices() orIDirect3DVertexBuffer7::ProcessVerticesStrided() function, you mustinclude the D3DVOP_LIGHT flag.In some cases, you might find that you only want to enable or disable one of the lights inyour application.The 1, 2, and 3 keys toggle the individual lights in the sample applica-tion on or off.To enable or disable a certain light, you must call theIDirect3DVertexBuffer7::LightEnable() function.Listing 14.8 shows the samplecode to toggle a specific light on or off.LISTING 14.8 Toggling a Specific Light1: void toggle_light( int light_number )2: {3: BOOL on;4:5: // Is the light enabled/on ?6: lpDevice->GetLightEnable(light_number, &on);7:8: // If it is, disable it, otherwise turn it on9: if (on)10: lpDevice->LightEnable(light_number, FALSE);11: else12: lpDevice->LightEnable(light_number, TRUE);13: }Animating Lights in the SceneTo animate the lights in your scene, you simply need to update their position and/ordirection and then re-render the scene.The sample application moves the lights in a cir-cular pattern above the texture-mapped buildings.In the case of the directional light, thesample application changes the directional light s direction vector.In addition, there is atimer to make sure that the lights aren t moving too fast.Listing 14.9 shows the codeused by the application to update light position and direction.20 1634xCH14 11/13/99 11:03 AM Page 279Adding Realism Through Lighting 279LISTING 14.9 Animating the Lights in the Scene1: void move_lights()2: {3: ////////////////////////////////////////4: // constants for the function5: //6: // radius of the circular path the light follows7: const D3DVALUE radius = 150.0f;8: // change in angle in radians per second ( approx.PI/4 -> 1/8 turn )9: const D3DVALUE rads_sec = 3.14f /4.0f;10:11: // current angle in radians for light0 (base at 0 radians)12: static D3DVALUE angle0 = 0;13: // current angle in radians for light1 (base 1/3 of the¥'way 2/3*pi radians)14: static D3DVALUE angle1 = 2*3.14f /3.0f;15: // current angle in radians for light2 (base 2/3 of the¥'way 4/3*pi radians)16: static D3DVALUE angle2 = 4*3.14f /3.0f;17: static DWORD last_time = timeGetTime(); // last time¥'we moved light18:19: //20: // Calcluate angle change - (# of millisecs / 1000 ) * radians¥'per second = radians21: //22: DWORD current_time = timeGetTime();23: D3DVALUE angle_delta = ( (current_time - last_time) / 1000.0f )¥'*rads_sec;24:25: // Add angle for next frame for each of the light angles26: angle0 += angle_delta;27: angle1 += angle_delta;28: angle2 += angle_delta;29:30: D3DLIGHT7 light;31:32: //33: // Calculate new position based on polar (x , y ) = ( r*cos(theta),¥'r*sin(theta) )34: // Do it for each light - Equally space the lights around the circle35: //36: lpDevice->GetLight( 0, &light );37: light.dvPosition.x = radius * (D3DVALUE) cos( angle0 );38: light.dvPosition.z = radius * (D3DVALUE) sin( angle0 );1439: light.dvPosition.y = lightElevation;continues20 1634xCH14 11/13/99 11:03 AM Page 280280 Hour 14LISTING 14.9 continued40: lpDevice->SetLight( 0, &light ); // Set/Change the lights state41:42: lpDevice->GetLight( 1, &light );43: light.dvPosition.x = radius * (D3DVALUE) cos( angle1 );44: light.dvPosition.z = radius * (D3DVALUE) sin( angle1 );45: light.dvPosition.y = lightElevation;46: lpDevice->SetLight( 1, &light ); // Set/Change the lights state47:48: ////////////////////////////////////////49: // The direction vector is moved not the position vector for directional¥'lights50: lpDevice->GetLight( 2, &light );51:52: // Multiply by -1 to get the correct direction vector53: // - All 3 lights will be equally spaced around the circle54:55: light.dvDirection.x = -1 * (D3DVALUE) cos( angle2 );56: light.dvDirection.z = -1 * (D3DVALUE) sin( angle2 );57: light.dvDirection.y = 0; //Always aim through y=0 regardless of x and z58: lpDevice->SetLight(2, &light); // Set/Change the lights state59:60: last_time = current_time; // store the time for the next pass61: }Removing the LightsIf you want to turn the lighting pipeline off completely, you can callIDirect3DDevice7::SetRenderState(), passing D3DRENDERSTATE_LIGHTING as the firstparameter, and FALSE as the second parameter.As mentioned before, you can also disablea certain light by calling the IDirect3DVertexBuffer7::LightEnable() function.SummaryLighting is a great way to bring more realism to your application.In addition, as moreand more video cards implement the Direct3D lighting pipeline in hardware, it will beadvantageous to use Direct3D lighting.You now know the basics of materials, vertexnormals, and the different types of Direct3D lights, which will allow you to easily addlighting to your application.20 1634xCH14 11/13/99 11:03 AM Page 281Adding Realism Through Lighting 281Q&AQ Why don t I see any shadows in my scene when I use Direct3D lighting?A Because of performance concerns, shadows are not implemented in the Direct3Dlighting pipeline.Various techniques can be used to create shadows (such as thestencil buffer).For more information about implementing shadows into your appli-cation, you should first consult the Direct3D SDK documentation.Q Why do the three different types of light all perform differently?A Each type of light in Direct3D has been optimized for the special case it presents.Directional lighting is fastest because there are no calculations dealing with range,attenuation, or position and because the direction is constant.A positional light isslightly slower because it has to take into account the attenuation and range of thelight.Finally, the spotlight is slowest because it has to perform calculations withevery single element of the D3DLIGHT7 structure.WorkshopThe Workshop is designed to help you anticipate possible questions, review what you velearned, and get you thinking about how to put your knowledge into practice.Theanswers to the quiz are in Appendix A, Answers.Quiz1.What are the three types of lights implemented by the Direct3D lighting pipeline?2.How do you enable/disable the Direct3D lighting pipeline?3.How do you enable/disable a specific light in Direct3D?4.How do you create a light in Direct3D?5.What is ambient light?6.What is diffuse light?7.What is specular light?8.What is a vertex normal, and what is it used for?9.What do the theta and phi elements of the D3DLIGHT7 structure specify, and whatare their valid ranges?10
[ Pobierz całość w formacie PDF ] zanotowane.pldoc.pisz.plpdf.pisz.plmikr.xlx.pl
|