コード例 #1
0
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            // Any type of content (3D models, fonts, images, etc.) can be converted to an XNB file by downloading and
            // using the mgcb-editor (see Blotch3D.chm for details). XNB files are then normally added to the project
            // and loaded as shown here. 'Content', here, is the folder that contains the XNB files or subfolders with
            // XNB files. We need to create one ContentManager object for each top-level content folder we'll be loading
            // XNB files from. You can create multiple content managers if content is spread over diverse folders. Some
            // content can also be loaded in its native format using platform specific code (may not be portable) or
            // certain Blotch3D/Monogame methods, like BlGraphicsDeviceManager.LoadFromImageFile.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            // The model
            var numX = 128;
            var numY = 2;

            var geoModel = BlGeometry.CreateCylindroid(numX, numY, 0);

            // transform it
            geoModel = BlGeometry.TransformVertices(geoModel, Matrix.CreateScale(1, 1, 2f));

            // Uncomment this to generate face normals (for example, if the previous transform totally flattened the model)
            //geoModel = BlGeometry.CalcFacetNormals(geoModel);

            // Uncomment this to set texture to planar
            //geoModel = BlGeometry.SetTextureToXY(geoModel);

            // convert to vertex buffer
            var geoVertexBuffer = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, geoModel);

            var tex = Graphics.LoadFromImageFile("Content/image.png");

            // The sprite we draw in this window
            GeoObj = new BlSprite(Graphics, "geomodel");
            GeoObj.LODs.Add(geoVertexBuffer);
            GeoObj.BoundSphere = new BoundingSphere(new Vector3(), 1);
            GeoObj.Mipmap      = tex;

            /*
             * // Uncomment this to show insides, also
             * GeoObj.PreDraw = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
             *      return BlSprite.PreDrawCmd.Continue;
             * };
             * GeoObj.DrawCleanup = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
             * };
             */
        }
コード例 #2
0
ファイル: Example.cs プロジェクト: grant-my/Blotch3D
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            // We need to create one ContentManager object for each top-level content folder we'll be
            // loading things from. Here "Content" is the most senior folder name of the content tree.
            // (Content [models, fonts, etc.] are added to the project with the Content utility. Double-click
            // 'Content.mgcb' in solution explorer.). You can create multiple content managers if content
            // is spread over diverse folders.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            // The model
            var numX = 128;
            var numY = 2;

            var geoModel = BlGeometry.CreateCylindroid(numX, numY, 0);

            // transform it
            geoModel = BlGeometry.TransformVertices(geoModel, Matrix.CreateScale(1, 1, 2f));

            // Uncomment this to generate face normals (for example, if the previous transform totally flattened the model)
            //geoModel = BlGeometry.CalcFacetNormals(geoModel);

            // Uncomment this to set texture to planar
            //geoModel = BlGeometry.SetTextureToXY(geoModel);

            // convert to vertex buffer
            var geoVertexBuffer = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, geoModel);

            var tex = Graphics.LoadFromImageFile("image.png");

            // The sprite we draw in this window
            GeoObj = new BlSprite(Graphics, "geomodel");
            GeoObj.LODs.Add(geoVertexBuffer);
            GeoObj.BoundSphere = new BoundingSphere(new Vector3(), 1);
            GeoObj.Mipmap      = tex;

            /*
             * // Uncomment this to show insides, also
             * GeoObj.PreDraw = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
             *      return BlSprite.PreDrawCmd.Continue;
             * };
             * GeoObj.DrawCleanup = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
             * };
             */
        }
コード例 #3
0
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            // Any type of content (3D models, fonts, images, etc.) can be converted to an XNB file by downloading and
            // using the mgcb-editor (see Blotch3D.chm for details). XNB files are then normally added to the project
            // and loaded as shown here. 'Content', here, is the folder that contains the XNB files or subfolders with
            // XNB files. We need to create one ContentManager object for each top-level content folder we'll be loading
            // XNB files from. You can create multiple content managers if content is spread over diverse folders. Some
            // content can also be loaded in its native format using platform specific code (may not be portable) or
            // certain Blotch3D/Monogame methods, like BlGraphicsDeviceManager.LoadFromImageFile.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            var width  = 128;
            var height = 128;

            // Create the surface triangles
            var SurfaceArray = BlGeometry.CreatePlanarSurface
                               (
                (x, y) => .06 * Math.Sin(((x - width / 2) * (y - height / 2)) / 300.0),
                width,
                height
                               );

            // convert to vertex buffer
            var vertexBuf = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, SurfaceArray);

            // The sprite we draw in this window
            Surface             = new BlSprite(Graphics, "Surface");
            Surface.BoundSphere = new BoundingSphere(Vector3.Zero, 1);
            Surface.LODs.Add(vertexBuf);
            Surface.SetAllMaterialBlack();
            Surface.Color = new Vector3(1, 1, 1);

            // When drawing this sprite, don't cull any polygons so that we can see both sides of them
            Surface.PreDraw = (s) =>
            {
                Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
                return(BlSprite.PreDrawCmd.Continue);
            };

            // Undo the previous 'CullNone' after the sprite is drawn so that other sprites use the default mode
            // (although there are no other sprites in this example, so this isn't technically necessary here)
            Surface.DrawCleanup = (s) =>
            {
                Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            };
        }
コード例 #4
0
ファイル: Example.cs プロジェクト: grant-my/Blotch3D
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            // We need to create one ContentManager object for each top-level content folder we'll be
            // loading things from. Here "Content" is the most senior folder name of the content tree.
            // (Content [models, fonts, etc.] are added to the project with the Content utility. Double-click
            // 'Content.mgcb' in solution explorer.). You can create multiple content managers if content
            // is spread over diverse folders.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            var width  = 128;
            var height = 128;

            // Create the surface triangles
            var SurfaceArray = BlGeometry.CreatePlanarSurface
                               (
                (x, y) => .06 * Math.Sin(((x - width / 2) * (y - height / 2)) / 300.0),
                width,
                height
                               );

            // convert to vertex buffer
            var vertexBuf = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, SurfaceArray);

            // The sprite we draw in this window
            Surface             = new BlSprite(Graphics, "Surface");
            Surface.BoundSphere = new BoundingSphere(Vector3.Zero, 1);
            Surface.LODs.Add(vertexBuf);
            Surface.SetAllMaterialBlack();
            Surface.Color   = new Vector3(1, 1, 1);
            Surface.PreDraw = (s) =>
            {
                Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
                return(BlSprite.PreDrawCmd.Continue);
            };
        }
コード例 #5
0
ファイル: Example.cs プロジェクト: Blotch3D/Blotch3D
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            Graphics.Lights.Clear();
            var light = new BlGraphicsDeviceManager.Light();

            light.LightDiffuseColor = new Vector3(1, 1, .5f);
            light.LightDirection    = new Vector3(1, 0, 0);
            Graphics.Lights.Add(light);

            // Any type of content (3D models, fonts, images, etc.) can be converted to an XNB file by downloading and
            // using the mgcb-editor (see Blotch3D.chm for details). XNB files are then normally added to the project
            // and loaded as shown here. 'Content', here, is the folder that contains the XNB files or subfolders with
            // XNB files. We need to create one ContentManager object for each top-level content folder we'll be loading
            // XNB files from. You can create multiple content managers if content is spread over diverse folders. Some
            // content can also be loaded in its native format using platform specific code (may not be portable) or
            // certain Blotch3D/Monogame methods, like BlGraphicsDeviceManager.LoadFromImageFile.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            // load the terrain image
            var terrain = Graphics.LoadFromImageFile("Content/terrain.png", true);

            // The vertices of the surface
            var SurfaceArray = BlGeometry.CreatePlanarSurface(terrain);

            // convert to vertex buffer
            var vertexBuf = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, SurfaceArray);

            // The sprite we draw in this window
            Surface        = new BlSprite(Graphics, "Surface");
            Surface.Mipmap = terrain;
            Surface.LODs.Add(vertexBuf);
            Surface.BoundSphere = new BoundingSphere(Vector3.Zero, 1);
            Surface.SetAllMaterialBlack();
            Surface.Color = new Vector3(1, 1, 1);
        }
コード例 #6
0
ファイル: Example.cs プロジェクト: grant-my/Blotch3D
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            Graphics.Lights.Clear();
            var light = new BlGraphicsDeviceManager.Light();

            light.LightDiffuseColor = new Vector3(1, 1, .5f);
            light.LightDirection    = new Vector3(1, 0, 0);
            Graphics.Lights.Add(light);

            // We need to create one ContentManager object for each top-level content folder we'll be
            // loading things from. Here "Content" is the most senior folder name of the content tree.
            // (Content [models, fonts, etc.] are added to the project with the Content utility. Double-click
            // 'Content.mgcb' in solution explorer.). You can create multiple content managers if content
            // is spread over diverse folders.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            // load the terrain image
            var terrain = Graphics.LoadFromImageFile("terrain.png", true);

            // The vertices of the surface
            var SurfaceArray = BlGeometry.CreatePlanarSurface(terrain);

            // convert to vertex buffer
            var vertexBuf = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, SurfaceArray);

            // The sprite we draw in this window
            Surface        = new BlSprite(Graphics, "Surface");
            Surface.Mipmap = terrain;
            Surface.LODs.Add(vertexBuf);
            Surface.BoundSphere = new BoundingSphere(Vector3.Zero, 1);
            Surface.SetAllMaterialBlack();
            Surface.Color = new Vector3(1, 1, 1);
        }
コード例 #7
0
        /// <summary>
        /// 'Setup' is automatically called one time just after the object is created, by the 3D thread.
        /// You can load fonts, load models, and do other time consuming one-time things here that must be done
        /// by the object's thread..
        /// You can also load content later if necessary (like in the Update or Draw methods), but try
        /// to load them as few times as necessary because loading things takes time.
        /// </summary>
        protected override void Setup()
        {
            TopSprite           = new BlSprite(Graphics, "topSprite");
            TopHudSprite        = new BlSprite(Graphics, "topHudSprite");
            HudBackground       = new BlSprite(Graphics, "HudBackground");
            Graphics.ClearColor = new Microsoft.Xna.Framework.Color();
            //graphics.AutoRotate = .002;

            Content = new ContentManager(Services, "Content");

            Font = Content.Load <SpriteFont>("Arial14");

            var floor     = new BlSprite(Graphics, "floor");
            var plane     = Content.Load <Model>("Plane");
            var sphere    = Content.Load <Model>("uv_sphere_192x96");
            var MyTexture = Graphics.LoadFromImageFile("image_with_alpha.png");

            //
            // Create floor
            //
            floor.LODs.Add(plane);
            floor.Mipmap = new BlMipmap(Graphics, MyTexture);
            floor.SetAllMaterialBlack();
            floor.EmissiveColor = new Vector3(1, 1, 1);
            TopSprite.Add("floor", floor);

            //
            // Create parent
            //
            var modelParent = new BlSprite(Graphics, "parent");

            modelParent.Matrix *= Matrix.CreateTranslation(1, 1, 1);
            TopSprite.Add("modelParent", modelParent);

            //
            // Create model
            //
            Model        = new BlSprite(Graphics, "model");
            Model.Mipmap = new BlMipmap(Graphics, MyTexture);
            Model.Matrix = Microsoft.Xna.Framework.Matrix.CreateScale(.12f);
            Model.SetAllMaterialBlack();
            Model.EmissiveColor = new Vector3(1, 1, 1);
            modelParent.Add("model", Model);

            var verts = new VertexPositionNormalTexture[6];
            var norm  = new Vector3(0, 0, 1);

            verts[0].Position          = new Vector3(-1, -1, 0);
            verts[0].TextureCoordinate = new Vector2(0, 0);
            verts[0].Normal            = norm;

            verts[1].Position          = new Vector3(-1, 1, 0);
            verts[1].TextureCoordinate = new Vector2(0, 1);
            verts[1].Normal            = norm;

            verts[2].Position          = new Vector3(1, -1, 0);
            verts[2].TextureCoordinate = new Vector2(1, 0);
            verts[2].Normal            = norm;

            verts[3].Position          = verts[1].Position;
            verts[3].TextureCoordinate = new Vector2(0, 1);
            verts[3].Normal            = norm;

            verts[4].Position          = new Vector3(1, 1, 0);
            verts[4].TextureCoordinate = new Vector2(1, 1);
            verts[4].Normal            = norm;

            verts[5].Position          = verts[2].Position;
            verts[5].TextureCoordinate = new Vector2(1, 0);
            verts[5].Normal            = norm;

            var vertBuf = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, verts);

            Model.LODs.Add(sphere);
            Model.LODs.Add(vertBuf);
            Model.LODs.Add(sphere);
            Model.LODs.Add(vertBuf);
            Model.LODs.Add(null);
            Model.BoundSphere = new BoundingSphere(Vector3.Zero, 1);


            //
            // Create text
            //
            var text = new BlSprite(Graphics, "text");

            text.SphericalBillboard = true;
            text.ConstSize          = true;
            modelParent.Add("text", text);

            // Note that in-world textures with alpha (like this one) really need to use
            // an alpha test to work correctly (see the SpriteAlphaTexture demo)
            // This one works because it is drawn last and there is no other alpha texture in front of it.
            var title = new BlSprite(Graphics, "title");

            title.LODs.Add(Content.Load <Model>("Plane"));
            title.Matrix      = Matrix.CreateScale(.15f, .05f, .15f);
            title.Mipmap      = new BlMipmap(Graphics, Graphics.TextToTexture("These words are\nin world space", Font, Microsoft.Xna.Framework.Color.Red, Microsoft.Xna.Framework.Color.Transparent));
            title.MipmapScale = -1000;
            title.SetAllMaterialBlack();
            title.EmissiveColor = new Vector3(1, 1, 1);
            title.PreDraw       = (s) =>
            {
                // Disable depth testing
                Graphics.GraphicsDevice.DepthStencilState = Graphics.DepthStencilStateDisabled;
                return(BlSprite.PreDrawCmd.Continue);
            };
            title.DrawCleanup = (s) =>
            {
                // Disable depth testing
                Graphics.GraphicsDevice.DepthStencilState = Graphics.DepthStencilStateEnabled;
            };
            text.Add("title", title);

            //
            // Create hud
            //
            HudBackground.IncludeInAutoClipping = false;
            HudBackground.ConstSize             = true;
            TopHudSprite.Add("hudBackground", HudBackground);

            var myHud = new BlSprite(Graphics, "myHud");

            HudBackground.Add("myHud", myHud);

            myHud.Matrix  = Matrix.CreateScale(.2f, .1f, .2f);
            myHud.Matrix *= Matrix.CreateTranslation(3, 1, 0);

            myHud.LODs.Add(Content.Load <Model>("Plane"));
            myHud.Mipmap = new BlMipmap(Graphics, Graphics.TextToTexture("HUD text", Font, Microsoft.Xna.Framework.Color.White, Microsoft.Xna.Framework.Color.Transparent), 1);
            myHud.SetAllMaterialBlack();
            myHud.EmissiveColor = new Vector3(1, 1, 1);

            // Create skybox, with a FrameProc that keeps it centered on the camera
            Skybox = new BlSprite(Graphics, "Skybox", (s) =>
            {
                s.Matrix.Translation = Graphics.TargetEye;
            });
            Skybox.Mipmap = new BlMipmap(Graphics, Graphics.LoadFromImageFile("Skybox.jpg"), 1);
            SkyboxModel   = Content.Load <Model>("uv_sphere_192x96");
            Skybox.LODs.Add(SkyboxModel);

            // Exclude from auto-clipping
            Skybox.IncludeInAutoClipping = false;

            // The sphere model is rotated a bit to avoid distortion at the poles. So we have to rotate it back
            Skybox.Matrix = Matrix.CreateFromYawPitchRoll(.462f, 0, .4504f);

            Skybox.Matrix *= Matrix.CreateScale(SkyboxDiameter);
            Skybox.PreDraw = (s) =>
            {
                // Set inside facets to visible, rather than outside
                Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullClockwise;

                // Disable depth testing
                Graphics.GraphicsDevice.DepthStencilState = Graphics.DepthStencilStateDisabled;

                // Create a separate View matrix when drawing the skybox, which is the same as the current view matrix but with very high farclip
                LastProjectionMatrix = Graphics.Projection;
                Graphics.Projection  = Microsoft.Xna.Framework.Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians((float)Graphics.Zoom), (float)Graphics.CurrentAspect, SkyboxDiameter / 100, SkyboxDiameter * 100);

                return(BlSprite.PreDrawCmd.Continue);
            };
            Skybox.DrawCleanup = (s) =>
            {
                // retore default settings

                Graphics.GraphicsDevice.DepthStencilState = Graphics.DepthStencilStateEnabled;
                Graphics.GraphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;
                Graphics.Projection = LastProjectionMatrix;
            };
            Skybox.SpecularColor = Vector3.Zero;
            Skybox.Color         = Vector3.Zero;
            Skybox.EmissiveColor = new Vector3(1, 1, 1);

            var guiCtrl = new BlGuiControl(this)
            {
                Texture     = Graphics.TextToTexture("Click me for a console message", Font, Color.Green, Color.Transparent),
                Position    = new Vector2(600, 100),
                OnMouseOver = (ctrl) =>
                {
                    if (ctrl.PrevMouseState.LeftButton == ButtonState.Released && Mouse.GetState().LeftButton == ButtonState.Pressed)
                    {
                        Console.WriteLine("GUI button was clicked");
                    }
                }
            };


            GuiControls.TryAdd("MyControl", guiCtrl);
        }
コード例 #8
0
ファイル: Example.cs プロジェクト: hyb1234hi/Blotch3D
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            // We need to create one ContentManager object for each top-level content folder we'll be
            // loading things from. Here "Content" is the most senior folder name of the content tree.
            // (Content [models, fonts, etc.] are added to the project with the Content utility. Double-click
            // 'Content.mgcb' in solution explorer.). You can create multiple content managers if content
            // is spread over diverse folders.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            // The model resolution
            var numX = 512;
            var numY = 512;

            // tapered bent screw shape parameters
            var taperSize   = .1;
            var numThreads  = 5;
            var numTurns    = 8;          // (total for all threads)
            var threadDepth = .2;
            var bend        = .001;

            // Create bending matrix (this could also include scale and translation)
            var matrix = Matrix.CreateRotationX((float)bend);

            // Create the tapered screw
            var triangles = BlGeometry.CreateCylindroid
                            (
                (x, y) => threadDepth * Math.Sin(Math.PI * 2 * (numThreads * x / (double)numX + numTurns * y / (double)numY)) + 1,
                numX,
                numY,
                taperSize,
                false,
                true,
                true,
                matrix
                            );

            // Uncomment this for facet normals
            //geoModel = BlGeometry.CalcFacetNormals(geoModel);

            // uncomment this to transform it
            //geoModel = BlGeometry.TransformVertices(geoModel, Matrix.CreateScale(1, 1, 2f));

            // Uncomment this to generate face normals (for example, if the previous transform totally flattened the model)
            //geoModel = BlGeometry.CalcFacetNormals(geoModel);

            // Uncomment this to set texture to planar
            // (note: to control the planar direction, transform the vertices, call this method, then transform them back)
            //geoModel = BlGeometry.SetTextureToXY(geoModel);

            // convert to vertex buffer
            var geoVertexBuffer = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, triangles);

            // The sprite we draw in this window
            GeoObj = new BlSprite(Graphics, "geomodel");
            GeoObj.LODs.Add(geoVertexBuffer);
            GeoObj.BoundSphere = BlGeometry.GetBoundingSphere(triangles);
            GeoObj.Mipmap      = new BlMipmap(Graphics, Graphics.LoadFromImageFile("image.png"));

            /*
             * // Uncomment this to make insides visible, also.
             * GeoObj.PreDraw = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
             *      return BlSprite.PreDrawCmd.Continue;
             * };
             * GeoObj.DrawCleanup = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
             * };
             */
        }
コード例 #9
0
ファイル: Example.cs プロジェクト: Blotch3D/Blotch3D
        /// <summary>
        /// See BlWindow3D for details.
        /// </summary>
        protected override void Setup()
        {
            // Any type of content (3D models, fonts, images, etc.) can be converted to an XNB file by downloading and
            // using the mgcb-editor (see Blotch3D.chm for details). XNB files are then normally added to the project
            // and loaded as shown here. 'Content', here, is the folder that contains the XNB files or subfolders with
            // XNB files. We need to create one ContentManager object for each top-level content folder we'll be loading
            // XNB files from. You can create multiple content managers if content is spread over diverse folders. Some
            // content can also be loaded in its native format using platform specific code (may not be portable) or
            // certain Blotch3D/Monogame methods, like BlGraphicsDeviceManager.LoadFromImageFile.
            var MyContent = new ContentManager(Services, "Content");

            // The font we will use to draw the menu on the screen.
            // "Arial14" is the pathname to the font file
            Font = MyContent.Load <SpriteFont>("Arial14");

            // The model resolution
            var numX = 512;
            var numY = 512;

            // tapered bent screw shape parameters
            var taperSize   = .1;
            var numThreads  = 5;
            var numTurns    = 8;          // (total for all threads)
            var threadDepth = .2;
            var bend        = .001;

            // Create bending matrix (this could also include scale and translation)
            var matrix = Matrix.CreateRotationX((float)bend);

            // Create the tapered screw
            var triangles = BlGeometry.CreateCylindroid
                            (
                (x, y) => threadDepth * Math.Sin(Math.PI * 2 * (numThreads * x / (double)numX + numTurns * y / (double)numY)) + 1,
                numX,
                numY,
                taperSize,
                false,
                true,
                true,
                matrix
                            );

            // Uncomment this for facet normals
            //geoModel = BlGeometry.CalcFacetNormals(geoModel);

            // uncomment this to transform it
            //geoModel = BlGeometry.TransformVertices(geoModel, Matrix.CreateScale(1, 1, 2f));

            // Uncomment this to generate face normals (for example, if the previous transform totally flattened the model)
            //geoModel = BlGeometry.CalcFacetNormals(geoModel);

            // Uncomment this to set texture to planar
            // (note: to control the planar direction, transform the vertices, call this method, then transform them back)
            //geoModel = BlGeometry.SetTextureToXY(geoModel);

            // convert to vertex buffer
            var geoVertexBuffer = BlGeometry.TrianglesToVertexBuffer(Graphics.GraphicsDevice, triangles);

            // The sprite we draw in this window
            GeoObj = new BlSprite(Graphics, "geomodel");
            GeoObj.LODs.Add(geoVertexBuffer);
            GeoObj.BoundSphere = BlGeometry.GetBoundingSphere(triangles);
            GeoObj.Mipmap      = new BlMipmap(Graphics, Graphics.LoadFromImageFile("Content/image.png"));

            /*
             * // Uncomment this to make insides visible, also.
             * GeoObj.PreDraw = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
             *      return BlSprite.PreDrawCmd.Continue;
             * };
             * GeoObj.DrawCleanup = (s) =>
             * {
             *      Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
             * };
             */
        }