1 Cube & Sphere Chapter 5. 2 Draw Cube Cube has 8 vertices as the picture shows. Each vertex has color of Red, Blue, Green or Yellow. We need to draw.

Slides:



Advertisements
Similar presentations
ArrayLists The lazy mans array. Whats the matter here? int[] list = new int[10]; list[0] = 5; list[2] = hey; list[3] = 15; list[4] = 23;
Advertisements

2D Graphics Drawing Things. Graphics In your GUI, you might want to draw graphics E.g. draw lines, circles, shapes, draw strings etc The Graphics class.
1 2D Graphics CIS 487/587 Bruce R. Maxim UM-Dearborn.
Nov 2005 MSc Slide 1 - Another Example of a Structural Pattern Alternative way of adding Functionality to an existing class (alternative to a derived class)
1 3D Vector & Matrix Chapter 2. 2 Vector Definition: Vector is a line segment that has the direction. The length of the line segment is called the magnitude.
Chapter 14 Graph class design John Keyser’s Modifications of Slides by Bjarne Stroustrup
What is an isometric drawing?
Understanding the graphics pipeline Lecture 2 Original Slides by: Suresh Venkatasubramanian Updates by Joseph Kider.
Status – Week 257 Victor Moya. Summary GPU interface. GPU interface. GPU state. GPU state. API/Driver State. API/Driver State. Driver/CPU Proxy. Driver/CPU.
OPENGL Return of the Survival Guide. Buffers (0,0) OpenGL holds the buffers in a coordinate system such that the origin is the lower left corner.
Data Structure (Part I) Stacks and Queues. Introduction to Stack An stack is a ordered list in which insertion and deletions are made at one end. –The.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 18: Stacks And Queues.
Translation and Rotation in 2D and 3D David Meredith Aalborg University.
CS 4731: Computer Graphics Lecture 18: Hidden Surface Removal Emmanuel Agu.
, Fall 2006IAT 800 Lab 2: Polygons, Transformations, and Arrays.
Triangles, Translations Game Design Experience Professor Jim Whitehead March 2, 2009 Creative Commons Attribution 3.0 (Except copyrighted images) creativecommons.org/licenses/by/3.0.
1 CMSC 132: Object-Oriented Programming II Java Constructs Department of Computer Science University of Maryland, College Park.
Syracuse University 3D Framework using GDI+.Net Carmen Vaca Ruiz Independent Study Fall 2004 Instructor: Dr. Jim Fawcett.
Introduction to 3D Graphics John E. Laird. Basic Issues u Given a internal model of a 3D world, with textures and light sources how do you project it.
1 High Level Shader Language (HLSL) Chapter What is HLSL? The previous vertex and pixel shader programming is to use assembly language to write.
1 Texture Chapter 6. 2 What is Texture? Texture is a D3D interface that can map a partial of a picture to a 3D space by using Texture coordinates. The.
1 X file & Mesh Chapter 8. 2 What is X file? 1.X file is a file that is used to store D3D program's data. 2.Any X file has extension *.x. 3.X file could.
1 Ring, Circle, Cone Chapter 4. 2 Triangle rotating We have a triangle in the following position We want to rotate it around line y =  2. For this purpose,
CSE 381 – Advanced Game Programming Basic 3D Graphics
Java: Chapter 1 Computer Systems Computer Programming II.
Tree. Basic characteristic Top node = root Left and right subtree Node 1 is a parent of node 2,5,6. –Node 2 is a parent of node.
Graphics and Multimedia Part #2
2002 by Jim X. Chen George Mason University Transformation and Viewing.1. Plane Example: J2_0_2DTransform.
2D Graphics: Rendering Details
Buffers Textures and more Rendering Paul Taylor & Barry La Trobe University 2009.
CS 4363/6353 TEXTURE MAPPING PART II. WHAT WE KNOW We can open image files for reading We can load them into texture buffers We can link that texture.
User Input and Collisions COSC 315 Fall 2014 Bridget M. Blodgett.
Image Synthesis Rabie A. Ramadan, PhD D Images.
Acute angle An angle with a measure less than 90 degrees.
MATH 306 Chapter 1.
Copyright © 2012 Pearson Education, Inc. Chapter 18: Stacks And Queues.
Introduction to XNA Graphics Programming Asst. Prof. Rujchai Ung-arunyawee COE, KKU.
1 Viewing & Projective Window Chapter 3. 2 D3D virtual viewpoint Definition: virtual viewpoint is like a camera that was positioned in some where and.
Rules Two Teams Questions worth 1-3 points – Entire team can confer to answer the question – Max of 2 minutes per question – You can use a computer on.
11 Adding Tomato Targets Session Session Overview  We now have a game which lets a player bounce a piece of cheese on a bread bat  Now we have.
2008/9/24 Kim, HyungSeok. HyungSeok Kim, Konkuk University Part I: Framework – 1. Windows creation – 2. Renderer – 3. Lights and Objects/Model loading.
1 Manage Mesh Data Chapter 8. 2 How to manage Mesh data The most important two objects of mesh are VertexBuffer and IndexBuffer, which can obtained by.
J2ME: M3G/11 Intro to J2ME. Prog. v Objectives: –to continue talking about "M3G Chapter 2. An Animated Model" u explain animation and the floor.
Control flow for interactive applications CSE 3541 Matt Boggus.
RUN-Time Organization Compiler phase— Before writing a code generator, we must decide how to marshal the resources of the target machine (instructions,
1 Graphic Device Interface (GDI). 2 Class Form A Form is a representation of any window displayed in your application. The Form class can be used to create.
Space Figures & Cross-Sections
12/5/2015 EEC492/693/793 - iPhone Application Development 1 EEC-693/793 Applied Computer Vision with Depth Cameras Lecture 4 Wenbing Zhao
Computation as an Expressive Medium Lab 2: Polygons, Transformations, and Arrays Evan.
Chapters 5 2 March Classical & Computer Viewing Same elements –objects –viewer –projectors –projection plane.
2009 GRAPHICS : PROJECT 1 BASED ON DX9 BASICS. Documented by Dongjoon Kim SNU CS Ph.D Course Student Contact : NOTE.
1 OGRE Programming Intermediate Tutorial: Volume Selection.
Geometric Objects and Transformations. Graphics Pipeline How can we render a triangle? High-level description: – Represent the 3D geometry – Transform.
CS COMPUTER GRAPHICS LABORATORY. LIST OF EXPERIMENTS 1.Implementation of Bresenhams Algorithm – Line, Circle, Ellipse. 2.Implementation of Line,
1 Arrays of Arrays An array can represent a collection of any type of object - including other arrays! The world is filled with examples Monthly magazine:
 Learn some important functions and process in OpenGL ES  Draw some triangles on the screen  Do some transformation on each triangle in each frame.
Improving the appearance of 3D OpenGL scenes
What are shaders? In the field of computer graphics, a shader is a computer program that runs on the graphics processing unit(GPU) and is used to do shading.
2/16/2016 EEC492/693/793 - iPhone Application Development 1 EEC-693/793 Applied Computer Vision with Depth Cameras Lecture 4 Wenbing Zhao
Computer Science I Animations. Bouncing ball. The if statement. Classwork/homework: bouncing something. Compress and upload work to Moodle.
Computer Graphics (Fall 2003) COMS 4160, Lecture 5: OpenGL 1 Ravi Ramamoorthi Many slides courtesy Greg Humphreys.
CSCE 441 Computer Graphics 3-D Viewing
Texture Mapping Part II
CS451Real-time Rendering Pipeline
Surface Area.
Surface Area of Rectangle Prisms
Presentation transcript:

1 Cube & Sphere Chapter 5

2 Draw Cube Cube has 8 vertices as the picture shows. Each vertex has color of Red, Blue, Green or Yellow. We need to draw 6 faces. However, we want to draw the front faces only and remove all the back faces. How to control that? There are two methods to do so (i)Use the triangle direction control; (ii) Use the z-buffer.

3 Decide the draw order Top face, 0123 is clock wise. Bottom face, 4657 is counter-clock wise. Front face, 4062 is clock wise Right face, 6273 is clock wise Back face 7351 is counter-clock wise Left face 5140 is counter-clock wise. This is one possible order to draw all those faces. When the back face turns to the front, the order will change to the clock wise.

4 Set Cube Vertex void SetVertex() { CustomVertex.PositionColored [] verts = new CustomVertex.PositionColored[8]; // make eight vertices first verts[0].X=-4.0f; verts[0].Z=-4.0f; verts[0].Y= 4.0f; verts[0].Color = Color.Yellow.ToArgb(); verts[1].X=-4.0f; verts[1].Z= 4.0f; verts[1].Y= 4.0f; verts[1].Color = Color.Red.ToArgb(); verts[2].X= 4.0f; verts[2].Z=-4.0f; verts[2].Y= 4.0f; verts[2].Color = Color.Green.ToArgb();

5 verts[3].X= 4.0f; verts[3].Z= 4.0f; verts[3].Y= 4.0f; verts[3].Color = Color.Blue.ToArgb(); verts[4].X=-4.0f; verts[4].Z=-4.0f; verts[4].Y=-4.0f; verts[4].Color = Color.Blue.ToArgb(); verts[5].X=-4.0f; verts[5].Z= 4.0f; verts[5].Y=-4.0f; verts[5].Color = Color.Green.ToArgb(); verts[6].X=4.0f; verts[6].Z=-4.0f; verts[6].Y=-4.0f; verts[6].Color = Color.Red.ToArgb(); verts[7].X= 4.0f; verts[7].Z= 4.0f; verts[7].Y=-4.0f; verts[7].Color = Color.Yellow.ToArgb(); // next to make 24 vertices

6 v_cube = new CustomVertex.PositionColored[24]; v_cube[0] =verts[0] ; v_cube[1] =verts[1] ; v_cube[2] =verts[2] ; v_cube[3] =verts[3] ; // top face v_cube[4] =verts[4] ; v_cube[5] =verts[6] ; v_cube[6] =verts[5] ;v_cube[7] =verts[7] ; // bottom face v_cube[8] =verts[4] ; v_cube[9] =verts[0] ; v_cube[10] =verts[6] ;v_cube[11] =verts[2] ; // front face v_cube[12] =verts[6] ; v_cube[13] =verts[2] ; v_cube[14] =verts[7] ;v_cube[15] =verts[3] ; // right face v_cube[16] =verts[7] ; v_cube[17] =verts[3] ; v_cube[18] =verts[5] ;v_cube[19] =verts[1] ; // back face v_cube[20] =verts[5] ; v_cube[21] =verts[1] ; v_cube[22] =verts[4] ; v_cube[23] =verts[0] ; // left face }

7 private void Render() { …………… device.RenderState.CullMode = Cull.CounterClockwise ; device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); //top face device.DrawPrimitives(PrimitiveType.TriangleStrip, 4, 2); //bottom face device.DrawPrimitives(PrimitiveType.TriangleStrip, 8, 2); //front face device.DrawPrimitives(PrimitiveType.TriangleStrip, 12, 2); //right face device.DrawPrimitives(PrimitiveType.TriangleStrip, 16, 2); //back face device.DrawPrimitives(PrimitiveType.TriangleStrip, 20, 2); //left face ……….. }

8 Initialize Z-buffer for device void Init3D() { PresentParameters pp = new PresentParameters(); pp.Windowed = true; pp.SwapEffect = SwapEffect.Discard; // now add code to initialize z-buffer pp.EnableAutoDepthStencil=true; pp.AutoDepthStencilFormat=DepthFormat.D16 ; device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);} }

9 Initialize Z-buffer for drawing device.RenderState.CullMode = Cull.None; device.RenderState.ZBufferEnable=true; Clear Z-buffer to 1.0f before drawing device.Clear(ClearFlags.Target|ClearFlags.ZBuffer, Color.Black.ToArgb(),1.0f,0); Z-buffer value is from 0.0f to 1.0f. 1.0f means at infinity. 0.0f means the most closer.

10 Microsoft.DirectX.Direct3D.Font using D3D=Microsoft.DirectX.Direct3D; Constructer D3D.Font m_font = new D3D.Font (device, 20, 0, FontWeight.Bold,0, false, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.DefaultPitch, "Arial"); D3D.Font(Device device, int height, int width, FontWeight weight, int miplevel, bool italic, CharacterSet set, Precision precision, FontQuality qty, PitchAndFamily paf, string fontfamily); Example

11 Font::DrawText(…) private void DrawText(string str) { font.DrawText(null, str, new Rectangle(5,5,400, 40), DrawTextFormat.Left, Color.Yellow.ToArgb()); } int DrawText(D3D.Sprite pSprite, string pString, Rectangle pRect, DrawTextFormat Format, int Color ); Example

12 Calculate frame rate int t=0; int count =0;float fps=30.0f; Define member variables; t= Environment.TickCount; void Render() { int gap = Environment.TickCount - t; count++; if(gap>1000){ fps = (float)count*1000/(float)gap; fps= (float)Math.Round(fps,2); count=0; t=Environment.TickCount; } DrawText("Frame Rate: "+fps +" fps"); // must after Clear code }

13 Out put

14 IndexBuffer method IndexBuffer is a D3D object that could set index for a given VertexBuffer To draw 6 cube faces, we have created a VertexBuffer of 24 vertices. However, we only need 8 different vertices. In order to save memory space, we can use IndexBuffer. The basic procedure is that: (i) First create a VertexBuffer of 8 vertices. (ii) Then create an IndexBuffer of with 24 elements, each element is only one int size. (iii) Use IndexBuffer to set index for the VertexBuffer (iv) Draw cube by method. DrawIndexedPrimative(…)

15 Constructor public IndexBuffer( Type typeOfIndex int sizeOfBufferInBytes, Device device, Usage usage, Pool pool, ); Example IndexBuffer IB = new IndexBuffer(typeof(int), 24, m_device, Usage.WriteOnly, Pool.Managed);

16 Set IndexBuffer Value The IndexBuffer Value can be set by function SetData(…) private bool InitIB() { IB=new IndexBuffer(typeof(int), 24, device,Usage.WriteOnly,Pool.Managed); if(IB==null) return false; int[] indices = new int[24]; indices[0]=0; indices[1]=1; indices[2]=2; indices[3]=3; IB.SetData(indices, 0, LockFlags.None); return true; }

17 DrawIndexedPrimitives In order to draw from index, we need to device.SetStreamSource( 0, VB, 0); device.Indices=IB; // set index device.DrawIndexedPrimitives( PrimitiveType.TriangleStrip, 0, 0, 8, 0, 2); Note: What is the meaning of 0, 0, 8, 0, 2? (1) The offset in VertexBuffer is 0. (2) The minimum index used in this call is 0. (3) The total source vertices is 8. (4) Begin drawing from index 0 of VertexBuffer. (5) Draw 2 triangles.

18 Draw from user memory Device can draw geometries directly from user defined memory array instead from VertexBuffer, which is in video card. public void DrawUserPrimitives( PrimitiveType primitiveType, int primitiveCount, object vertexArray ) We can use TriangleStrip or TriangleList for PrimitiveType. Object will be the vertex array defined by user.

19 Example private void SetVertex() { // those are two class member variables Vertices = new CustomVertex.PositionColored[12]; Vertices2 = new CustomVertex.PositionColored[10]; CustomVertex.PositionColored [] cube = new CustomVertex.PositionColored[8]; cube[0].Position = new Vector3( -4.0f,4.0f, -4.0f); cube[0].Color =Color.Yellow.ToArgb(); cube[1].Position = new Vector3( 4.0f,4.0f, -4.0f); cube[1].Color =Color.Red.ToArgb(); cube[2].Position = new Vector3( -4.0f,4.0f, 4.0f); cube[2].Color =Color.Green.ToArgb(); cube[3].Position = new Vector3( 4.0f,4.0f, 4.0f); cube[3].Color =Color.Blue.ToArgb();

20 cube[4].Position = new Vector3( -4.0f,-4.0f, -4.0f); cube[4].Color =Color.Blue.ToArgb(); cube[5].Position = new Vector3( 4.0f,-4.0f, -4.0f); cube[5].Color =Color.Green.ToArgb(); cube[6].Position = new Vector3( -4.0f,-4.0f, 4.0f); cube[6].Color =Color.Red.ToArgb(); cube[7].Position = new Vector3( 4.0f,-4.0f, 4.0f); cube[7].Color =Color.Yellow.ToArgb(); // top face use List Vertices[0]=cube[0]; Vertices[1]=cube[1]; Vertices[2]=cube[2]; Vertices[3]=cube[1]; Vertices[4]=cube[2];Vertices[5]=cube[3]; // bottom face List Vertices[6]=cube[4]; Vertices[7]=cube[5]; Vertices[8]=cube[6]; Vertices[9]=cube[5]; Vertices[10]=cube[6]; Vertices[11]=cube[7];

21 // all other 4 faces use strip Vertices2[0] = cube[4]; Vertices2[1] = cube[0]; Vertices2[2] = cube[5];Vertices2[3] = cube[1]; Vertices2[4] = cube[7];Vertices2[5] = cube[3]; Vertices2[6] = cube[6];Vertices2[7] = cube[2]; Vertices2[8] = cube[4];Vertices2[9] = cube[0]; } Draw Triangles m_device.DrawUserPrimitives(PrimitiveType.TriangleList,4, Vertices); m_device.DrawUserPrimitives(PrimitiveType.TriangleStrip,8, Vertices2);

22 DrawIndexedUserPrimitives(...) public void DrawUserIndexdPrimitives( PrimitiveType primitiveType, intMinimalIndex intTotalVertexUsed int primitiveCount, objectIndexArray bool16BitIndex object vertexArray ) Note: Set false for 16BitIndex if using Int32 array index

23 private void SetVertex() { v_cube = new CustomVertex.PositionColored[8]; indeces = new int[36]; v_cube [0].Position = new Vector3( -4.0f,4.0f, -4.0f); v_ cube[0].Color =Color.Yellow.ToArgb(); v_ cube[1].Position = new Vector3( 4.0f,4.0f, -4.0f); v_ cube[1].Color =Color.Red.ToArgb(); v_ cube[2].Position = new Vector3( -4.0f,4.0f, 4.0f); v_ cube[2].Color =Color.Green.ToArgb(); v_ cube[3].Position = new Vector3( 4.0f,4.0f, 4.0f); v_ cube[3].Color =Color.Blue.ToArgb(); v_ cube[4].Position = new Vector3( -4.0f,-4.0f, -4.0f); v_ cube[4].Color =Color.Blue.ToArgb(); Define class member variables: CustomVertex.PositionColored [] v_cube; int []indeces;

24 cube[5].Position = new Vector3( 4.0f,-4.0f, -4.0f); cube[5].Color =Color.Green.ToArgb(); cube[6].Position = new Vector3( -4.0f,-4.0f, 4.0f); cube[6].Color =Color.Red.ToArgb(); cube[7].Position = new Vector3( 4.0f,-4.0f, 4.0f); cube[7].Color =Color.Yellow.ToArgb(); // now set index for each triangle, use Triangle List indeces = new int[36]; indeces[0] = 0; indeces[1] = 1;indeces[2] = 2; indeces[3] = 1; indeces[4] = 2; indeces[5] = 3; indeces[6] = 4; indeces[7] = 5;indeces[8] = 6; indeces[9] = 5; indeces[10] = 6; indeces[11] = 7; indeces[12] = 4; indeces[13] = 0; indeces[14] = 5; indeces[15] = 0; indeces[16] = 5; indeces[17] = 1;

25 indeces[18] = 5; indeces[19] = 1; indeces[20] = 7; indeces[21] = 1; indeces[22] = 7; indeces[23] = 3; indeces[24] = 7; indeces[25] = 3; indeces[26] = 6; indeces[27] = 3; indeces[28] = 6; indeces[29] = 2; indeces[30] = 6; indeces[31] = 2; indeces[32] = 4; indeces[33] = 2; indeces[34] = 4; indeces[35] = 0; } Draw code device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, 8,12,indeces, false, v_cube); Minimum index Total vertex Total triangles Index array Vertex array

26 Use mouse to control position Here we will use static function of class Matrix public static Matrix RotationYawPitchRoll( float yaw, //around the y-axis, in radians float pitch, //around the x-axis, in radians. float roll,//around the z-axis, in radians. ); bool down = false; // check mouse down int lastX, lastY; // remember the last mouse position Matrix mat = Matrix.Identity; // remember rotations private void SetPosition() // replace rotation in Render() { device.Transform.World = mat; } First we define class member variables and function

27 protected override void OnMouseDown( MouseEventArgs e) { if(e.Button==MouseButtons.Left) { down = true; lastX = e.X; lastY = e.Y ; } } protected override void OnMouseUp( MouseEventArgs e) { down = false; } Then implement three event handling functions

28 protected override void OnMouseMove( MouseEventArgs e) { if(!down)return; int x = e.X ; int y = e.Y ; float dx= (float)(lastX-x)/50.0f ; float dy= (float)(lastY-y)/50.0f ; Matrix rot = Matrix.RotationYawPitchRoll(dx, dy, 0.0f); mat = mat*rot; // combine the previous position lastX =x; lastY =y ; } And

29 Draw Spherical Ball We must decompose the spherical surface into triangles. The sphere equation is So we equally partition  value from 0 to  and partition  value from 0 to 2  to get many rectangles on the spherical surface, and each rectangle has 2 triangles. Note: Near poles, we actually get triangles directly.

30 So we totally have (m+1)(n+1) points, mn rectangles, 2mn triangles, 6mn vertices. Note: Near poles, some triangles are reduced to line segments. However, that does not affect drawing. 22    m intervals n intervals Map sphere surface to Rectangle

31 private void SetVertex() { v_sphere = new CustomVertex.PositionColored [(m+1)*(n+1)]; float alpha = 2.0f*(float)Math.PI /(float)m; float theta = (float)Math.PI /(float)n; for(int i=0; i<m+1; i++) for(int k=0; k<n+1; k++) { v_sphere[k*(m+1)+i].Z =r*(float) Math.Cos(k*theta ); v_sphere[k*(m+1)+i].X = r*(float)Math.Sin(k*theta)*(float) Math.Cos(i*alpha); v_sphere[k*(m+1)+i].Y = r*(float)Math.Sin(k*theta)*(float) Math.Sin(i*alpha); v_sphere[k*(m+1)+i].Color = Color.Yellow.ToArgb(); } Set (m+1)(n+1)Vertex Set the VertexBuffer is same as before.

32 private bool InitIB() { IB=new IndexBuffer(typeof(int), n*3*(2*m), device,Usage.WriteOnly,Pool.Managed); if(IB==null) return false; int[] indices = new int[n*3*(2*m)]; for(int k=0; k<n; k++) for(int i=0; i<m;i++) { indices[0+i*6+k*(6*m)] = i+0+k*(m+1); indices[1+i*6+k*(6*m)] = i+(m+1)+k*(m+1); indices[2+i*6+k*(6*m)] = i+(m+2)+k*(m+1); indices[3+i*6+k*(6*m)] = i+0+k*(m+1);; indices[4+i*6+k*(6*m)] = i+1+k*(m+1);; indices[5+i*6+k*(6*m)] = i+(m+2)+k*(m+1);; } IB.SetData(indices, 0, LockFlags.None); return true; } Set IndexBuffer

33 private void Render() {.... device.RenderState.FillMode=FillMode.WireFrame ; device.SetStreamSource( 0, VB2, 0); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, (m+1)*(n+1), 0, 2*m*n); } Draw Sphere Total pointsTotal triangles

34 Output

35 Draw solar system If we want draw 3 spheres, one is the sun, one is the earth and the 3 rd one is the moon. It is better to design a class to wrap all operations including VertexBuffer and IndexBuffer setting. public class Sphere { int m, n; float r; Color color; Device device; VertexBuffer VB = null; IndexBuffer IB = null; CustomVertex.PositionColored [] v_sphere = null; bool active=false;

36 private void SetVertex() { v_sphere = new CustomVertex.PositionColored [(m+1)*(n+1)]; float alpha = 2.0f*(float)Math.PI /(float)m; float theta = (float)Math.PI /(float)n; for(int i=0; i<m+1; i++) for(int k=0; k<n+1; k++) { v_sphere[k*(m+1)+i].Z =r*(float) Math.Cos(k*theta ); v_sphere[k*(m+1)+i].X = r*(float)Math.Sin(k*theta)*(float) Math.Cos(i*alpha); v_sphere[k*(m+1)+i].Y = r*(float)Math.Sin(k*theta)*(float) Math.Sin(i*alpha); v_sphere[k*(m+1)+i].Color = Color.Yellow.ToArgb(); }

37 private bool SetVB() { VB = new VertexBuffer( typeof(CustomVertex.PositionColored), v_sphere.Length, device, 0, CustomVertex.PositionColored.Format, Pool.Default); if(VB==null) return false; VB.Created += new System.EventHandler(this.WriteVBData); WriteVBData(null, null); return true; } public void WriteVBData(object sender, EventArgs e) { GraphicsStream stream = VB.Lock(0, 0, 0); stream.Write(v_sphere); VB.Unlock(); }

38 private void InitIB() { IB=new IndexBuffer(typeof(int), n*3*(2*m), device,Usage.WriteOnly,Pool.Managed); int[] indices = new int[n*3*(2*m)]; for(int k=0; k<n; k++) for(int i=0; i<m;i++) { indices[0+i*6+k*(6*m)] = i+0+k*(m+1); indices[1+i*6+k*(6*m)] = i+(m+1)+k*(m+1); indices[2+i*6+k*(6*m)] = i+(m+2)+k*(m+1); indices[3+i*6+k*(6*m)] = i+0+k*(m+1);; indices[4+i*6+k*(6*m)] = i+1+k*(m+1);; indices[5+i*6+k*(6*m)] = i+(m+2)+k*(m+1);; } IB.SetData(indices, 0, LockFlags.None); }

39 public Sphere(int mm, int nn, float rr, Color col, Device dev) { m=mm; n=nn; color =col; r = rr; device = dev; SetVertex(); active = SetVB(); SetIB(); } public void Draw() { if(!active)MessageBox.Show("Cannot draw sphere"); device.SetStreamSource( 0, VB, 0); device.Indices =IB; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0,0, (m+1)*(n+1), 0,2*m*n); }

40 public void StartGame() { GameActive =Init3D(); ball1 = new Sphere(40,20,1.2f, Color.Yellow, device); ball2 = new Sphere(12,10,0.5f, Color.Blue, device); ball3 = new Sphere(10,8, 0.2f, Color.White, device); while(GameActive) { Render(); Application.DoEvents(); } private void Render() { device.RenderState.FillMode=FillMode.WireFrame ; SetRotation1(); ball1.Draw(); SetRotation2(); ball2.Draw(); SetRotation3(); ball3.Draw(); }

41 Matrix mat; private void SetRotation2() // rotation of the earth { Matrix RY = Matrix.RotationY (theta) ; Matrix T = Matrix.Translation (2.7f,0,0) ; device.Transform.World=T*RY; mat =T*RY; // record the earth position } private void SetRotation3() // rotation of the moon { Matrix RY = Matrix.RotationY (theta) ; Matrix T = Matrix.Translation (0.7f,0,0) ; device.Transform.World=T*RY*mat; // combine mat } Note: we must record the World Translation Matrix of the earth and use this matrix to combine the rotation of the moon.

42 Output Note: We must use the world transform matrix of the earth to design the rotation function of the moon