/// <summary> /// Function to update the texture coordinates. /// </summary> private void UpdateTextureCoordinates() { if (_captionHeight < 1) { CalculateCaptionHeight(); } _sprite.Size = new Vector2(_windowSize.X - 2, _windowSize.Y - _captionHeight - 1); Vector2 textureSize = _sprite.Size; Vector2.Divide(ref textureSize, _zoom, out _zoomSize); _sprite.TextureSize = _texture.ToTexel(_zoomSize); }
/// <summary> /// Function to perform initialization on the content. /// </summary> /// <returns>A control to embed into the container interface.</returns> protected override ContentPanel OnInitialize() { _delta = Program.Settings.AnimateStartPageLogo ? Program.Settings.StartPageAnimationPulseRate.Abs() : 0; _container = new ContentPanel(this) { CaptionVisible = false }; _2D = Graphics.Output.Create2DRenderer(_container.PanelDisplay); // Create the logo for display. _logo = Graphics.Textures.FromMemory <GorgonTexture2D>("Logo", Resources.Gorgon_2_x_Logo_Blurry, new GorgonCodecDDS()); var textureCoordinates = new RectangleF(Vector2.Zero, _logo.ToTexel(new Vector2(_logo.Settings.Width, _logo.Settings.Height / 3))); // Set up coordinates for our blurred images. _blurStates = new[] { textureCoordinates, // No blur. new RectangleF(new Vector2(0, textureCoordinates.Height), textureCoordinates.Size), // Medium blur. new RectangleF(new Vector2(0, textureCoordinates.Height * 2), textureCoordinates.Size) // Max blur. }; _sourceState = _blurStates[2]; _destState = _blurStates[1]; return(_container); }
/// <summary> /// Function to execute during idle time. /// </summary> /// <returns>TRUE to continue executing, FALSE to stop.</returns> private bool Idle() { _renderer.Drawing.TextureSampler.HorizontalWrapping = TextureAddressing.Wrap; _renderer.Drawing.TextureSampler.VerticalWrapping = TextureAddressing.Wrap; _renderer.Drawing.Blit(_defaultTexture, new RectangleF(0, 0, panelTextureDisplay.Width, panelTextureDisplay.Height), _defaultTexture.ToTexel(panelTextureDisplay.ClientRectangle)); _renderer.Drawing.TextureSampler.HorizontalWrapping = TextureAddressing.Clamp; _renderer.Drawing.TextureSampler.VerticalWrapping = TextureAddressing.Clamp; if (Texture == null) { _renderer.Render(2); return(true); } _renderer.Drawing.Blit(Texture, _displayRegion, new RectangleF(0, 0, 1, 1)); _clipper.Draw(); _renderer.Render(2); return(true); }
/// <summary> /// Function to change the texture pointed at by this glyph. /// </summary> /// <param name="texture">The texture to assign to the glyph.</param> /// <param name="glyphCoordinates">The coordinates of the glyph on the texture, in pixels.</param> /// <param name="outlineCoordinates">The coordinates of the glyph outline on the texture, in pixels.</param> /// <param name="textureArrayIndex">The array index on the 2D texture array to use for this glyph.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="texture"/> parameter is <b>null</b>.</exception> /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="texture"/> is not a 2D texture. /// <para>-or-</para> /// <para>Thrown if the <paramref name="texture"/> format is not <see cref="BufferFormat.R8G8B8A8_UNorm"/>, <see cref="BufferFormat.R8G8B8A8_UNorm_SRgb"/>, <see cref="BufferFormat.B8G8R8A8_UNorm"/> or /// <see cref="BufferFormat.B8G8R8A8_UNorm_SRgb"/>.</para> /// </exception> /// <remarks> /// <para> /// This allows an application to point a glyph at a new <see cref="GorgonTexture2D"/> for custom bitmap glyphs, or allows the region on the texture that contains the glyph to be modified. This /// allows applications to create custom characters in fonts that the font generation code cannot produce. /// </para> /// <para> /// Currently any custom texture/coordinates are not persisted when the font is saved. This may change in a future release of Gorgon. /// </para> /// <para> /// If the <see cref="GorgonFont"/> for this glyph does not have an outline, then the <paramref name="outlineCoordinates"/> should be set to empty. /// </para> /// </remarks> public void UpdateTexture(GorgonTexture2D texture, DX.Rectangle glyphCoordinates, DX.Rectangle outlineCoordinates, int textureArrayIndex) { if (texture == null) { throw new ArgumentNullException(nameof(texture)); } if ((texture == TextureView?.Texture) && (glyphCoordinates == GlyphCoordinates) && (outlineCoordinates == OutlineCoordinates) && (TextureIndex == textureArrayIndex)) { return; } if (texture != TextureView?.Texture) { if ((texture.Format != BufferFormat.R8G8B8A8_UNorm) && (texture.Format != BufferFormat.R8G8B8A8_UNorm_SRgb) && (texture.Format != BufferFormat.B8G8R8A8_UNorm) && (texture.Format != BufferFormat.B8G8R8A8_UNorm_SRgb)) { throw new ArgumentException(Resources.GORGFX_ERR_GLYPH_TEXTURE_FORMAT_INVALID, nameof(texture)); } TextureView = texture.GetShaderResourceView(); } // Ensure that this index is valid. textureArrayIndex = textureArrayIndex.Max(0).Min(TextureView?.Texture.ArrayCount - 1 ?? 0); TextureIndex = textureArrayIndex; GlyphCoordinates = glyphCoordinates; OutlineCoordinates = outlineCoordinates; TextureCoordinates = texture.ToTexel(glyphCoordinates); if (OutlineCoordinates.IsEmpty) { return; } OutlineTextureCoordinates = texture.ToTexel(outlineCoordinates); }
/// <summary> /// Function to create a new sprite object. /// </summary> /// <param name="name">Name of the sprite.</param> /// <param name="size">Size of the sprite.</param> /// <param name="texture">Texture to apply to the sprite.</param> /// <returns>A new sprite.</returns> /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="name"/> parameter is NULL (Nothing in VB.Net).</exception> /// <exception cref="System.ArgumentException">Thrown when the name parameter is an empty string.</exception> public GorgonSprite CreateSprite(string name, Vector2 size, GorgonTexture2D texture) { Vector2 texelSize = Vector2.Zero; if (texture != null) { texelSize = texture.ToTexel(size); } return(CreateSprite(name, size, texture, new RectangleF(Vector2.Zero, texelSize))); }
/// <summary> /// Function to initialize the application. /// </summary> private static void Initialize() { var depthFormat = BufferFormat.D24_UIntNormal_S8_UInt; // Depth buffer format. // Create our form. _mainForm = new formMain(); // Add a keybinding to switch to full screen or windowed. _mainForm.KeyDown += _mainForm_KeyDown; // Create the main graphics interface. Graphics = new GorgonGraphics(); // Validate depth buffer for this device. // Odds are good that if this fails, you should probably invest in a // better video card. Preferably something created after 2005. if (!Graphics.VideoDevice.SupportsDepthFormat(depthFormat)) { depthFormat = BufferFormat.D16_UIntNormal; if (Graphics.VideoDevice.SupportsDepthFormat(depthFormat)) { return; } GorgonDialogs.ErrorBox(_mainForm, "Video device does not support a 24 or 16 bit depth buffer."); return; } // Create a 1280x800 window with a depth buffer. // We can modify the resolution in the config file for the application, but // like other Gorgon examples, the default is 1280x800. _swap = Graphics.Output.CreateSwapChain("Main", new GorgonSwapChainSettings { Window = _mainForm, // Assign to our form. Format = BufferFormat.R8G8B8A8_UIntNormal, // Set up for 32 bit RGBA normalized display. Size = Settings.Default.Resolution, // Get the resolution from the config file. DepthStencilFormat = depthFormat, // Get our depth format. IsWindowed = Settings.Default.IsWindowed // Set up for windowed or full screen (depending on config file). }); // Center on the primary monitor. // This is necessary because we already created the window, so it'll be off center at this point. _mainForm.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width / 2 - _mainForm.Width / 2, Screen.PrimaryScreen.WorkingArea.Height / 2 - _mainForm.Height / 2); // Handle any resizing. // This is here because the base graphics library will NOT handle state loss due to resizing. // This is up to the developer to handle. _swap.AfterSwapChainResized += _swap_Resized; // Create the 2D interface for our text. _2D = Graphics.Output.Create2DRenderer(_swap); // Create our shaders. // Our vertex shader. This is a simple shader, it just processes a vertex by multiplying it against // the world/view/projection matrix and spits it back out. _vertexShader = Graphics.Shaders.CreateShader <GorgonVertexShader>("VertexShader", "BoingerVS", Resources.Shader); // Our main pixel shader. This is a very simple shader, it just reads a texture and spits it back out. Has no // diffuse capability. _pixelShader = Graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "BoingerPS", Resources.Shader); // Our shadow shader for our ball "shadow". This is hard coded to send back black (R:0, G:0, B:0) at 50% opacity (A: 0.5). _pixelShaderShadow = Graphics.Shaders.CreateShader <GorgonPixelShader>("ShadowShader", "BoingerShadowPS", Resources.Shader); // Create the vertex input layout. // We need to create a layout for our vertex type because the shader won't know // how to interpret the data we're sending it otherwise. This is why we need a // vertex shader before we even create the layout. _inputLayout = Graphics.Input.CreateInputLayout("InputLayout", typeof(BoingerVertex), _vertexShader); // Create the view port. // This just tells the renderer how big our display is. var view = new GorgonViewport(0, 0, _mainForm.ClientSize.Width, _mainForm.ClientSize.Height, 0.0f, 1.0f); // Load our textures from the resources. // This contains our textures for the walls and ball. _texture = Graphics.Textures.CreateTexture <GorgonTexture2D>("PlaneTexture", Resources.Texture); // Set up our view matrix. // Move the camera (view matrix) back 2.2 units. This will give us enough room to see what's // going on. Matrix.Translation(0, 0, 2.2f, out _viewMatrix); // Set up our projection matrix. // This matrix is probably the cause of almost EVERY problem you'll ever run into in 3D programming. // Basically we're telling the renderer that we want to have a vertical FOV of 75 degrees, with the aspect ratio // based on our form width and height. The final values indicate how to distribute Z values across depth (tip: // it's not linear). _projMatrix = Matrix.PerspectiveFovLH((75.0f).Radians(), _mainForm.Width / (float)_mainForm.Height, 0.125f, 500.0f); // Create our constant buffer and backing store. // Our constant buffers are how we send data to our shaders. This one in particular will be responsible // for sending our world/view/projection matrix to the vertex shader. The stream we're creating after // the constant buffer is our system memory store for the data. Basically we write to the system // memory and then upload that data to the video card. This is very different from how things used to // work, but allows a lot more flexibility. _wvpBuffer = Graphics.Buffers.CreateConstantBuffer("WVPBuffer", new GorgonConstantBufferSettings { SizeInBytes = Matrix.SizeInBytes }); _wvpBufferStream = new GorgonDataStream(_wvpBuffer.SizeInBytes); // Create our planes. // Here's where we create the 2 planes for our rear wall and floor. We set the texture size to texel units // because that's how the video card expects them. However, it's a little hard to eyeball 0.67798223f by looking // at the texture image display, so we use the ToTexel function to determine our texel size. var textureSize = _texture.ToTexel(new Vector2(500, 500)); _planes = new[] { new Plane(new Vector2(3.5f), new RectangleF(Vector2.Zero, textureSize)), new Plane(new Vector2(3.5f), new RectangleF(Vector2.Zero, textureSize)) }; // Set up default positions and orientations. _planes[0].Position = new Vector3(0, 0, 3.0f); _planes[1].Position = new Vector3(0, -3.5f, 3.5f); _planes[1].Rotation = new Vector3(90.0f, 0, 0); // Create our sphere. // Again, here we're using texels to align the texture coordinates to the other image // packed into the texture (atlasing). var textureOffset = _texture.ToTexel(new Vector2(516, 0)); // This is to scale our texture coordinates because the actual image is much smaller // (256x256) than the full texture (1024x512). textureSize.X = 0.245f; textureSize.Y = 0.5f; // Give the sphere a place to live. _sphere = new Sphere(1.0f, textureOffset, textureSize) { Position = new Vector3(2.2f, 1.5f, 2.5f) }; // Bind our objects to the pipeline and set default states. // At this point we need to give the graphics card a bunch of things // it needs to do its job. // Give our current input layout. Graphics.Input.Layout = _inputLayout; // We're drawing individual triangles for this (and this is usyally the case). Graphics.Input.PrimitiveType = PrimitiveType.TriangleList; // Bind our current vertex shader and send over our world/view/projection matrix // constant buffer. Graphics.Shaders.VertexShader.Current = _vertexShader; Graphics.Shaders.VertexShader.ConstantBuffers[0] = _wvpBuffer; // Do the same with the pixel shader, only we're binding our texture to it as well. // We also need to bind a sampler to the texture because without it, the shader won't // know how to interpret the texture data (e.g. how will the shader know if the texture // is supposed to be bilinear filtered or point filtered?) Graphics.Shaders.PixelShader.Current = _pixelShader; Graphics.Shaders.PixelShader.Resources[0] = _texture; Graphics.Shaders.PixelShader.TextureSamplers[0] = GorgonTextureSamplerStates.LinearFilter; // Turn on alpha blending. Graphics.Output.BlendingState.States = GorgonBlendStates.ModulatedBlending; // Turn on depth writing. // This is our depth writing state. When this is on, all polygon data sent to the card // will write to our depth buffer. Normally we want this, but for translucent objects, it's // problematic.... _depth = new GorgonDepthStencilStates { DepthComparison = ComparisonOperator.LessEqual, IsDepthEnabled = true, IsDepthWriteEnabled = true, IsStencilEnabled = false }; // Turn off depth writing. // So, we copy the depth state and turn off depth writing so that translucent objects // won't write to the depth buffer but can still read it. _noDepth = _depth; _noDepth.IsDepthWriteEnabled = false; Graphics.Output.DepthStencilState.States = _depth; // Bind our swap chain and set up the default rasterizer states. Graphics.Output.SetRenderTarget(_swap, _swap.DepthStencilBuffer); Graphics.Rasterizer.States = GorgonRasterizerStates.CullBackFace; Graphics.Rasterizer.SetViewport(view); // I know, there's a lot in here. Thing is, if this were Direct 3D 11 code, it'd probably MUCH // more code and that's even before creating our planes and sphere. }