public void Draw(DrawState state) { state.PushWorldMatrixMultiply(ref worldMatrix); //cull test the sphere if (sphereGeometry.CullTest(state)) { //NEW CODE //compute a scale value that follows a sin wave float scaleValue = (float)Math.Sin(state.TotalTimeSeconds) * 0.5f + 1.0f; //the shader class has been generated in the namespace 'Shader', because the filename is 'shader.fx'. //The only technique in the file is named 'Tutorial03Technique'. //The class that was generated is Shader.Tutorial03Technique: Shader.Tutorial03Technique shader = null; //It is recommended to use the draw state to get a shared static instance of the shader. //Getting shader instances in this way is highly recommended for most shaders, as it reduces //memory usage and live object count. This will boost performance in large projects. shader = state.GetShader <Shader.Tutorial03Technique>(); //Set the scale value (scale is declared in the shader source) shader.Scale = scaleValue; //Bind the custom shader instance //After the call to Bind(), the shader is in use. There is no Begin/End logic required for shaders shader.Bind(state); //draw the sphere geometry sphereGeometry.Draw(state); } state.PopWorldMatrix(); }
//draw the sphere private void DrawGeometry(DrawState state) { //animate the material alpha.. (in a sin wave btween 0 and 1) shader.Alpha = (float)Math.Sin(state.TotalTimeSeconds * 2) * 0.5f + 0.5f; //push the world matrix, multiplying by the current matrix if there is one state.PushWorldMatrixMultiply(ref this.worldMatrix); //cull test the sphere if (sphereGeometry.CullTest(state)) { //bind the shader shader.Bind(state); //draw the sphere geometry sphereGeometry.Draw(state); } //always pop the matrix afterwards state.PopWorldMatrix(); }
//draw the sphere (This is the method declared in the IDraw interface) public void Draw(DrawState state) { //the DrawState object controls current drawing state for the application. //The DrawState uses a number of stacks, it is important to understand how pushing/popping a stack works. //First, push the world matrix, multiplying by the current matrix (if there is one). //This is very similar to using openGL glPushMatrix() and then glMultMatrix(). //The DrawState object maintains the world matrix stack, pushing and popping this stack is very fast. state.PushWorldMatrixMultiply(ref this.worldMatrix); //The next line frustum cull tests the sphere //Culltest will return false if the test fails (in this case false would mean the sphere is off screen) //The CullTest method requirs an ICuller to be passed in. Here the state object is used because the //DrawState object implements the ICuller interface (DrawState's culler performs screen culling) //The cull test uses the current world matrix, so make sure you perform the CullTest after applying any //transformations. //The CullTest method is defined by the ICullable interface. Any IDraw object also implements ICullable. if (sphereGeometry.CullTest(state)) { //the sphere is on screen... //bind the shader. //Note that if the sphere was off screen, the shader would never be bound, //which would save valuable CPU time. (The sphere geometry class assumes a shader is bound) //This is why the CullTest() method is separate from the Draw() method. shader.Bind(state); //Once the call to Bind() has been made, the shaders will be active ('bound') //on the graphics card. There is no way to 'unbind' or 'end' the shader. //Once bound, that shader is in use - until the point a different shader is bound. //draw the sphere geometry sphereGeometry.Draw(state); } //always pop the world matrix afterwards state.PopWorldMatrix(); }