Esempio n. 1
0
        /// <summary>
        /// Application constructor
        /// </summary>
        public BillboardForm()
        {
            // Set the window text
            this.Text = "Billboard: D3D Billboarding Example";

            this.MinimizeBox = false;

            skyBoxMesh  = new GraphicsMesh();
            terrainMesh = new GraphicsMesh();

            OnetimeSceneInitialization();
            // Now let's setup our D3D parameters
            PresentParameters presentParams = new PresentParameters();

            presentParams.Windowed               = true;
            presentParams.SwapEffect             = SwapEffect.Discard;
            presentParams.AutoDepthStencilFormat = DepthFormat.D16;
            presentParams.EnableAutoDepthStencil = true;

            // create the device
            device = new Device(0, DeviceType.Default, this,
                                CreateFlags.None, presentParams);
            // store the render state
            renderState = device.RenderState;
            // initialize any device resources that aren't lost on reset
            InitializeDeviceObjects();
            // attach the reset callback
            device.DeviceReset += new EventHandler(RestoreDeviceObjects);
            // initialize any device resources that are lost on reset
            RestoreDeviceObjects(device, EventArgs.Empty);
        }
Esempio n. 2
0
        /// <summary>
        /// Renders the mesh
        /// </summary>
        /// <param name="canDrawOpaque">Enables drawing opaque portions
        /// of the mesh</param>
        /// <param name="canDrawAlpha">Enables drawing alpha blended portions
        /// of the mesh</param>
        public void Render(bool canDrawOpaque, bool canDrawAlpha)
        {
            RenderStateManager rs = device.RenderState;

            // Frist, draw the subsets without alpha
            if (canDrawOpaque)
            {
                for (int i = 0; i < meshMaterials.Length; i++)
                {
                    if (canDrawAlpha)
                    {
                        if (meshMaterials[i].Diffuse.A < 0xff)
                        {
                            continue;
                        }
                    }
                    // Set the material and texture for this subset
                    device.Material = meshMaterials[i];

                    if (meshTextures[i] != null)
                    {
                        device.SetTexture(0, meshTextures[i]);
                    }

                    // Draw the mesh subset
                    meshValue.DrawSubset(i);
                }
            }

            // Then, draw the subsets with alpha
            if (canDrawAlpha)
            {
                // Enable alpha blending
                rs.AlphaBlendEnable = true;
                rs.SourceBlend      = Blend.SourceAlpha;
                rs.DestinationBlend = Blend.InvSourceAlpha;
                for (int i = 0; i < meshMaterials.Length; i++)
                {
                    if (meshMaterials[i].Diffuse.A == 0xff)
                    {
                        continue;
                    }

                    // Set the material and texture for this subset
                    device.Material = meshMaterials[i];

                    if (meshTextures[i] != null)
                    {
                        device.SetTexture(0, meshTextures[i]);
                    }

                    // Draw the mesh subset
                    meshValue.DrawSubset(i);
                }
                // Restore state
                rs.AlphaBlendEnable = false;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Actually draw the mesh
        /// </summary>
        /// <param name="device">The device used to draw</param>
        /// <param name="canDrawOpaque">Can draw the opaque parts of the mesh</param>
        /// <param name="canDrawAlpha">Can draw the alpha parts of the mesh</param>
        public void Render(Device device, bool canDrawOpaque, bool canDrawAlpha)
        {
            if (null == localMemoryMesh)
            {
                throw new ArgumentException();
            }

            RenderStateManager rs = device.RenderState;

            // Frist, draw the subsets without alpha
            if (canDrawOpaque)
            {
                for (int i = 0; i < materials.Length; i++)
                {
                    if (isUsingMeshMaterials)
                    {
                        if (canDrawAlpha)
                        {
                            if (materials[i].DiffuseColor.Alpha < 0xff)
                            {
                                continue;
                            }
                        }
                        device.Material = materials[i];
                        device.SetTexture(0, textures[i]);
                    }
                    localMemoryMesh.DrawSubset(i);
                }
            }

            // Then, draw the subsets with alpha
            if (canDrawAlpha && isUsingMeshMaterials)
            {
                // Enable alpha blending
                rs.AlphaBlendEnable = true;
                rs.SourceBlend      = Blend.SourceAlpha;
                rs.DestinationBlend = Blend.InvSourceAlpha;
                for (int i = 0; i < materials.Length; i++)
                {
                    if (materials[i].DiffuseColor.Alpha == 0xff)
                    {
                        continue;
                    }

                    // Set the material and texture
                    device.Material = materials[i];
                    device.SetTexture(0, textures[i]);
                    localMemoryMesh.DrawSubset(i);
                }
                // Restore state
                rs.AlphaBlendEnable = false;
            }
        }
    /// <summary>
    /// Initialize the device objects
    /// </summary>
    /// <param name="dev">The grpahics device used to initialize</param>
    public void InitializeDeviceObjects(Device dev)
    {
        if (dev != null) {
            // Set up our events
            dev.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects);
        }

        // Keep a local copy of the device
        device = dev;
        textureState0 = device.TextureState[0];
        textureState1 = device.TextureState[1];
        samplerState0 = device.SamplerState[0];
        renderState = device.RenderState;

        // Create a bitmap on which to measure the alphabet
        Bitmap bmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        Graphics g = Graphics.FromImage(bmp);
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast = 0;

        // Establish the font and texture size
        textureScale  = 1.0f; // Draw fonts into texture without scaling

        // Calculate the dimensions for the smallest power-of-two texture which
        // can hold all the printable characters
        textureWidth = textureHeight = 128;
        for (;;) {
            try {
                // Measure the alphabet
                PaintAlphabet(g, true);
            }
            catch (System.InvalidOperationException) {
                // Scale up the texture size and try again
                textureWidth *= 2;
                textureHeight *= 2;
                continue;
            }

            break;
        }

        // If requested texture is too big, use a smaller texture and smaller font,
        // and scale up when rendering.
        Direct3D.Caps d3dCaps = device.DeviceCaps;

        // If the needed texture is too large for the video card...
        if (textureWidth > d3dCaps.MaxTextureWidth) {
            // Scale the font size down to fit on the largest possible texture
            textureScale = (float)d3dCaps.MaxTextureWidth / (float)textureWidth;
            textureWidth = textureHeight = d3dCaps.MaxTextureWidth;

            for(;;) {
                // Create a new, smaller font
                ourFontHeight = (int) Math.Floor(ourFontHeight * textureScale);
                systemFont = new System.Drawing.Font(systemFont.Name, ourFontHeight, systemFont.Style);

                try {
                    // Measure the alphabet
                    PaintAlphabet(g, true);
                }
                catch (System.InvalidOperationException) {
                    // If that still doesn't fit, scale down again and continue
                    textureScale *= 0.9F;
                    continue;
                }

                break;
            }
        }

        // Release the bitmap used for measuring and create one for drawing
        bmp.Dispose();
        bmp = new Bitmap(textureWidth, textureHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        g = Graphics.FromImage(bmp);
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast = 0;

        // Draw the alphabet
        PaintAlphabet(g, false);

        // Create a new texture for the font from the bitmap we just created
        fontTexture = Texture.FromBitmap(device, bmp, 0, Pool.Managed);
        RestoreDeviceObjects(null, null);
    }
    /// <summary>
    /// Initialize the device objects
    /// </summary>
    /// <param name="dev">The grpahics device used to initialize</param>
    public void InitializeDeviceObjects(Device dev)
    {
        if (dev != null)
        {
            // Set up our events
            dev.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects);
        }

        // Keep a local copy of the device
        device        = dev;
        textureState0 = device.TextureState[0];
        textureState1 = device.TextureState[1];
        samplerState0 = device.SamplerState[0];
        renderState   = device.RenderState;

        // Create a bitmap on which to measure the alphabet
        Bitmap   bmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        Graphics g   = Graphics.FromImage(bmp);

        g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast      = 0;

        // Establish the font and texture size
        textureScale = 1.0f;          // Draw fonts into texture without scaling

        // Calculate the dimensions for the smallest power-of-two texture which
        // can hold all the printable characters
        textureWidth = textureHeight = 128;
        for (;;)
        {
            try {
                // Measure the alphabet
                PaintAlphabet(g, true);
            }
            catch (System.InvalidOperationException) {
                // Scale up the texture size and try again
                textureWidth  *= 2;
                textureHeight *= 2;
                continue;
            }

            break;
        }

        // If requested texture is too big, use a smaller texture and smaller font,
        // and scale up when rendering.
        Direct3D.Caps d3dCaps = device.DeviceCaps;

        // If the needed texture is too large for the video card...
        if (textureWidth > d3dCaps.MaxTextureWidth)
        {
            // Scale the font size down to fit on the largest possible texture
            textureScale = (float)d3dCaps.MaxTextureWidth / (float)textureWidth;
            textureWidth = textureHeight = d3dCaps.MaxTextureWidth;

            for (;;)
            {
                // Create a new, smaller font
                ourFontHeight = (int)Math.Floor(ourFontHeight * textureScale);
                systemFont    = new System.Drawing.Font(systemFont.Name, ourFontHeight, systemFont.Style);

                try {
                    // Measure the alphabet
                    PaintAlphabet(g, true);
                }
                catch (System.InvalidOperationException) {
                    // If that still doesn't fit, scale down again and continue
                    textureScale *= 0.9F;
                    continue;
                }

                break;
            }
        }

        // Release the bitmap used for measuring and create one for drawing
        bmp.Dispose();
        bmp                 = new Bitmap(textureWidth, textureHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        g                   = Graphics.FromImage(bmp);
        g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast      = 0;

        // Draw the alphabet
        PaintAlphabet(g, false);

        // Create a new texture for the font from the bitmap we just created
        fontTexture = Texture.FromBitmap(device, bmp, 0, Pool.Managed);
        RestoreDeviceObjects(null, null);
    }
Esempio n. 6
0
    /// <summary>
    /// Initialize the device objects
    /// </summary>
    /// <param name="dev">The grpahics device used to initialize</param>
    public void InitializeDeviceObjects(Device dev)
    {
        if (dev != null)
        {
            // Set up our events
            dev.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects);
        }

        // Keep a local copy of the device
        device        = dev;
        textureState0 = device.TextureState[0];
        textureState1 = device.TextureState[1];
        samplerState0 = device.SamplerState[0];
        renderState   = device.RenderState;

        // Establish the font and texture size
        textureScale = 1.0f; // Draw fonts into texture without scaling

        // Large fonts need larger textures
        if (ourFontHeight > 60)
        {
            textureWidth = textureHeight = 2048;
        }
        else if (ourFontHeight > 30)
        {
            textureWidth = textureHeight = 1024;
        }
        else if (ourFontHeight > 15)
        {
            textureWidth = textureHeight = 512;
        }
        else
        {
            textureWidth = textureHeight = 256;
        }

        // If requested texture is too big, use a smaller texture and smaller font,
        // and scale up when rendering.
        Direct3D.Caps d3dCaps = device.DeviceCaps;

        if (textureWidth > d3dCaps.MaxTextureWidth)
        {
            textureScale = (float)d3dCaps.MaxTextureWidth / (float)textureWidth;
            textureWidth = textureHeight = d3dCaps.MaxTextureWidth;
        }

        Bitmap   bmp = new Bitmap(textureWidth, textureHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        Graphics g   = Graphics.FromImage(bmp);

        g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast      = 0;

        string str;
        float  x    = 0;
        float  y    = 0;
        Point  p    = new Point(0, 0);
        Size   size = new Size(0, 0);

        // Calculate the spacing between characters based on line height
        size = g.MeasureString(" ", systemFont).ToSize();
        x    = spacingPerChar = (int)Math.Ceiling(size.Height * 0.3);

        for (char c = (char)32; c < (char)127; c++)
        {
            str = c.ToString();
            // We need to do some things here to get the right sizes.  The default implemententation of MeasureString
            // will return a resolution independant size.  For our height, this is what we want.  However, for our width, we
            // want a resolution dependant size.
            Size resSize = g.MeasureString(str, systemFont).ToSize();
            size.Height = resSize.Height + 1;

            // Now the Resolution independent width
            if (c != ' ') // We need the special case here because a space has a 0 width in GenericTypoGraphic stringformats
            {
                resSize    = g.MeasureString(str, systemFont, p, StringFormat.GenericTypographic).ToSize();
                size.Width = resSize.Width;
            }
            else
            {
                size.Width = resSize.Width;
            }

            if ((x + size.Width + spacingPerChar) > textureWidth)
            {
                x  = spacingPerChar;
                y += size.Height;
            }

            if (c != ' ') // We need the special case here because a space has a 0 width in GenericTypoGraphic stringformats
            {
                g.DrawString(str, systemFont, Brushes.White, new Point((int)x, (int)y), StringFormat.GenericTypographic);
            }
            else
            {
                g.DrawString(str, systemFont, Brushes.White, new Point((int)x, (int)y));
            }
            textureCoords[c - 32, 0] = ((float)(x + 0 - spacingPerChar)) / textureWidth;
            textureCoords[c - 32, 1] = ((float)(y + 0 + 0)) / textureHeight;
            textureCoords[c - 32, 2] = ((float)(x + size.Width + spacingPerChar)) / textureWidth;
            textureCoords[c - 32, 3] = ((float)(y + size.Height + 0)) / textureHeight;

            x += size.Width + (2 * spacingPerChar);
        }

        // Create a new texture for the font from the bitmap we just created
        fontTexture = Texture.FromBitmap(device, bmp, 0, Pool.Managed);
        RestoreDeviceObjects(null, null);
    }
    /// <summary>
    /// Initialize the graphics environment
    /// </summary>
    public void InitializeEnvironment()
    {
        GraphicsAdapterInfo adapterInfo = graphicsSettings.AdapterInfo;
        GraphicsDeviceInfo deviceInfo = graphicsSettings.DeviceInfo;

        windowed = graphicsSettings.IsWindowed;

        // Set up the presentation parameters
        BuildPresentParamsFromSettings();

        if (deviceInfo.Caps.PrimitiveMiscCaps.IsNullReference) {
            // Warn user about null ref device that can't render anything
            HandleSampleException(new NullReferenceDeviceException(), ApplicationMessage.None);
        }

        CreateFlags createFlags = new CreateFlags();
        if (graphicsSettings.VertexProcessingType == VertexProcessingType.Software)
            createFlags = CreateFlags.SoftwareVertexProcessing;
        else if (graphicsSettings.VertexProcessingType == VertexProcessingType.Mixed)
            createFlags = CreateFlags.MixedVertexProcessing;
        else if (graphicsSettings.VertexProcessingType == VertexProcessingType.Hardware)
            createFlags = CreateFlags.HardwareVertexProcessing;
        else if (graphicsSettings.VertexProcessingType == VertexProcessingType.PureHardware) {
            createFlags = CreateFlags.HardwareVertexProcessing;
        }
        else
            throw new ApplicationException();
        #if (DX9)
        #else
        // Make sure to allow multithreaded apps if we need them
        presentParams.ForceNoMultiThreadedFlag = !isMultiThreaded;
        #endif
        try {
            // Create the device
            device = new Device(graphicsSettings.AdapterOrdinal, graphicsSettings.DevType,
                windowed ? ourRenderTarget : this , createFlags, presentParams);

            // Cache our local objects
            renderState = device.RenderState;
            sampleState = device.SamplerState;
            textureStates = device.TextureState;
            // When moving from fullscreen to windowed mode, it is important to
            // adjust the window size after recreating the device rather than
            // beforehand to ensure that you get the window size you want.  For
            // example, when switching from 640x480 fullscreen to windowed with
            // a 1000x600 window on a 1024x768 desktop, it is impossible to set
            // the window size to 1000x600 until after the display mode has
            // changed to 1024x768, because windows cannot be larger than the
            // desktop.
            if (windowed) {
                // Make sure main window isn't topmost, so error message is visible
                System.Drawing.Size currentClientSize = this.ClientSize;
                this.Size = this.ClientSize;
                this.SendToBack();
                this.BringToFront();
                this.ClientSize = currentClientSize;
            }

            // Store device Caps
            graphicsCaps = device.DeviceCaps;
            behavior = createFlags;

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            // Store device description
            if (deviceInfo.DevType == DeviceType.Reference)
                sb.Append("REF");
            else if (deviceInfo.DevType == DeviceType.Hardware)
                sb.Append("HAL");
            else if (deviceInfo.DevType == DeviceType.Software)
                sb.Append("SW");

            BehaviorFlags behaviorFlags = new BehaviorFlags(createFlags);
            if ((behaviorFlags.HardwareVertexProcessing) &&
                (behaviorFlags.PureDevice)) {
                if (deviceInfo.DevType == DeviceType.Hardware)
                    sb.Append(" (pure hw vp)");
                else
                    sb.Append(" (simulated pure hw vp)");
            }
            else if (behaviorFlags.HardwareVertexProcessing) {
                if (deviceInfo.DevType == DeviceType.Hardware)
                    sb.Append(" (hw vp)");
                else
                    sb.Append(" (simulated hw vp)");
            }
            else if (behaviorFlags.MixedVertexProcessing) {
                if (deviceInfo.DevType == DeviceType.Hardware)
                    sb.Append(" (mixed vp)");
                else
                    sb.Append(" (simulated mixed vp)");
            }
            else if (behaviorFlags.SoftwareVertexProcessing) {
                sb.Append(" (sw vp)");
            }

            if (deviceInfo.DevType == DeviceType.Hardware) {
                sb.Append(": ");
                sb.Append(adapterInfo.AdapterDetails.Description);
            }

            // Set device stats string
            deviceStats = sb.ToString();

            // Set up the fullscreen cursor
            if (showCursorWhenFullscreen && !windowed) {
                System.Windows.Forms.Cursor ourCursor = this.Cursor;
                device.SetCursor(ourCursor, true);
                device.ShowCursor(true);
            }

            // Confine cursor to fullscreen window
            if (clipCursorWhenFullscreen) {
                if (!windowed) {
                    System.Drawing.Rectangle rcWindow = this.ClientRectangle;
                }
            }

            // Setup the event handlers for our device
            device.DeviceLost += new System.EventHandler(this.InvalidateDeviceObjects);
            device.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects);
            device.Disposing += new System.EventHandler(this.DeleteDeviceObjects);
            device.DeviceResizing += new System.ComponentModel.CancelEventHandler(this.EnvironmentResized);

            // Initialize the app's device-dependent objects
            try {
                InitializeDeviceObjects();
                RestoreDeviceObjects(null, null);
                active = true;
                return;
            }
            catch {
                // Cleanup before we try again
                InvalidateDeviceObjects(null, null);
                DeleteDeviceObjects(null, null);
                device.Dispose();
                device = null;
                if (this.Disposing)
                    return;
            }
        }
        catch {
            // If that failed, fall back to the reference rasterizer
            if (deviceInfo.DevType == DeviceType.Hardware) {
                if (FindBestWindowedMode(false, true)) {
                    windowed = true;

                    // Make sure main window isn't topmost, so error message is visible
                    System.Drawing.Size currentClientSize = this.ClientSize;
                    this.Size = this.ClientSize;
                    this.SendToBack();
                    this.BringToFront();
                    this.ClientSize = currentClientSize;

                    // Let the user know we are switching from HAL to the reference rasterizer
                    HandleSampleException(null, ApplicationMessage.WarnSwitchToRef);

                    InitializeEnvironment();
                }
            }
        }
    }