public void DrawUserPrimitives <T>( PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int primitiveCount, VertexDeclaration vertexDeclaration ) where T : struct { // Flush the GL state before moving on! ApplyState(); // Unbind current VBOs. GLDevice.BindVertexBuffer(OpenGLDevice.OpenGLVertexBuffer.NullBuffer); // Pin the buffers. GCHandle vbHandle = GCHandle.Alloc(vertexData, GCHandleType.Pinned); // Setup the vertex declaration to point at the VB data. vertexDeclaration.GraphicsDevice = this; vertexDeclaration.Apply(VertexShader, vbHandle.AddrOfPinnedObject()); // Enable the appropriate vertex attributes. GLDevice.FlushGLVertexAttributes(); // Draw! GLDevice.glDrawArrays( PrimitiveTypeGL(primitiveType), vertexOffset, GetElementCountArray(primitiveType, primitiveCount) ); // Release the handles. vbHandle.Free(); }
public void DrawPrimitives(PrimitiveType primitiveType, int vertexStart, int primitiveCount) { // Flush the GL state before moving on! ApplyState(); // Set up the vertex buffers. for (int i = 0; i < vertexBufferCount; i += 1) { GLDevice.BindVertexBuffer( vertexBufferBindings[i].VertexBuffer.Handle ); vertexBufferBindings[i].VertexBuffer.VertexDeclaration.Apply( VertexShader, (IntPtr)( vertexBufferBindings[i].VertexBuffer.VertexDeclaration.VertexStride * vertexBufferBindings[i].VertexOffset ) ); } // Enable the appropriate vertex attributes. GLDevice.FlushGLVertexAttributes(); // Draw! GLDevice.glDrawArrays( PrimitiveTypeGL(primitiveType), vertexStart, GetElementCountArray(primitiveType, primitiveCount) ); }
protected virtual void Dispose(bool disposing) { if (!IsDisposed) { if (disposing) { // We're about to dispose, notify the application. if (Disposing != null) { Disposing(this, EventArgs.Empty); } /* Dispose of all remaining graphics resources before * disposing of the GraphicsDevice. */ GraphicsResource.DisposeAll(); // Free all the cached shader programs. programCache.Dispose(); // Dispose of the GL Device/Context GLDevice.Dispose(); } IsDisposed = true; } }
private void ApplyState() { // Apply RasterizerState now, as it depends on other device states GLDevice.ApplyRasterizerState( RasterizerState, RenderTargetCount > 0 ); // TODO: MSAA? if (VertexShader == null) { throw new InvalidOperationException("A vertex shader must be set!"); } if (PixelShader == null) { throw new InvalidOperationException("A pixel shader must be set!"); } if (vertexShaderDirty || pixelShaderDirty) { ActivateShaderProgram(); vertexShaderDirty = pixelShaderDirty = false; } vertexConstantBuffers.SetConstantBuffers(this, shaderProgram); pixelConstantBuffers.SetConstantBuffers(this, shaderProgram); }
public void Clear(ClearOptions options, Vector4 color, float depth, int stencil) { GLDevice.Clear( options, color, depth, stencil ); }
public void DrawInstancedPrimitives( PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount, int instanceCount ) { // Note that minVertexIndex and numVertices are NOT used! // If this device doesn't have the support, just explode now before it's too late. if (!GLDevice.SupportsHardwareInstancing) { throw new NoSuitableGraphicsDeviceException("Your hardware does not support hardware instancing!"); } // Flush the GL state before moving on! ApplyState(); // Unsigned short or unsigned int? bool shortIndices = Indices.IndexElementSize == IndexElementSize.SixteenBits; // Set up the vertex buffers. for (int i = 0; i < vertexBufferCount; i += 1) { GLDevice.BindVertexBuffer( vertexBufferBindings[i].VertexBuffer.Handle ); vertexBufferBindings[i].VertexBuffer.VertexDeclaration.Apply( VertexShader, (IntPtr)( vertexBufferBindings[i].VertexBuffer.VertexDeclaration.VertexStride * (vertexBufferBindings[i].VertexOffset + baseVertex) ), vertexBufferBindings[i].InstanceFrequency ); } // Enable the appropriate vertex attributes. GLDevice.FlushGLVertexAttributes(); // Bind the index buffer GLDevice.BindIndexBuffer(Indices.Handle); // Draw! GLDevice.glDrawElementsInstanced( PrimitiveTypeGL(primitiveType), GetElementCountArray(primitiveType, primitiveCount), shortIndices ? OpenGLDevice.GLenum.GL_UNSIGNED_SHORT : OpenGLDevice.GLenum.GL_UNSIGNED_INT, (IntPtr)(startIndex * (shortIndices ? 2 : 4)), instanceCount ); }
/// <summary> /// Draw geometry by indexing into the vertex buffer. /// </summary> /// <param name="primitiveType">The type of primitives in the index buffer.</param> /// <param name="baseVertex"> /// Used to offset the vertex range indexed from the vertex buffer. /// </param> /// <param name="minVertexIndex"> /// A hint of the lowest vertex indexed relative to baseVertex. /// </param> /// <param name="numVertices">An hint of the maximum vertex indexed.</param> /// <param name="startIndex"> /// The index within the index buffer to start drawing from. /// </param> /// <param name="primitiveCount"> /// The number of primitives to render from the index buffer. /// </param> /// <remarks> /// Note that minVertexIndex and numVertices are unused in MonoGame and will be ignored. /// </remarks> public void DrawIndexedPrimitives( PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount ) { // Flush the GL state before moving on! ApplyState(); // Unsigned short or unsigned int? bool shortIndices = Indices.IndexElementSize == IndexElementSize.SixteenBits; // Set up the vertex buffers. for (int i = 0; i < vertexBufferCount; i += 1) { GLDevice.BindVertexBuffer( vertexBufferBindings[i].VertexBuffer.Handle ); vertexBufferBindings[i].VertexBuffer.VertexDeclaration.Apply( VertexShader, (IntPtr)( vertexBufferBindings[i].VertexBuffer.VertexDeclaration.VertexStride * (vertexBufferBindings[i].VertexOffset + baseVertex) ) ); } // Enable the appropriate vertex attributes. GLDevice.FlushGLVertexAttributes(); // Bind the index buffer GLDevice.BindIndexBuffer(Indices.Handle); // Draw! GLDevice.glDrawRangeElements( PrimitiveTypeGL(primitiveType), minVertexIndex, minVertexIndex + numVertices - 1, GetElementCountArray(primitiveType, primitiveCount), shortIndices ? OpenGLDevice.GLenum.GL_UNSIGNED_SHORT : OpenGLDevice.GLenum.GL_UNSIGNED_INT, (IntPtr)(startIndex * (shortIndices ? 2 : 4)) ); }
public void Present() { // Dispose of any GL resources that were disposed in another thread lock (disposeActionsLock) { if (disposeActions.Count > 0) { foreach (Action action in disposeActions) { action(); } disposeActions.Clear(); } } GLDevice.SwapBuffers(PresentationParameters.DeviceWindowHandle); }
public void DrawUserIndexedPrimitives <T>( PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, int[] indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration ) where T : struct, IVertexType { // Flush the GL state before moving on! ApplyState(); // Unbind current buffer objects. GLDevice.BindVertexBuffer(OpenGLDevice.OpenGLVertexBuffer.NullBuffer); GLDevice.BindIndexBuffer(OpenGLDevice.OpenGLIndexBuffer.NullBuffer); // Pin the buffers. GCHandle vbHandle = GCHandle.Alloc(vertexData, GCHandleType.Pinned); GCHandle ibHandle = GCHandle.Alloc(indexData, GCHandleType.Pinned); // Setup the vertex declaration to point at the VB data. vertexDeclaration.GraphicsDevice = this; vertexDeclaration.Apply( VertexShader, (IntPtr)(vbHandle.AddrOfPinnedObject().ToInt64() + vertexDeclaration.VertexStride * vertexOffset) ); // Enable the appropriate vertex attributes. GLDevice.FlushGLVertexAttributes(); // Draw! GLDevice.glDrawRangeElements( PrimitiveTypeGL(primitiveType), 0, numVertices - 1, GetElementCountArray(primitiveType, primitiveCount), OpenGLDevice.GLenum.GL_UNSIGNED_INT, (IntPtr)(ibHandle.AddrOfPinnedObject().ToInt64() + (indexOffset * sizeof(int))) ); // Release the handles. ibHandle.Free(); vbHandle.Free(); }
public GLWindow(String title, Size size, Boolean isFullScreen) : base(title, size, isFullScreen) { //Workaround for SDL2 mouse input issues var options = new OpenTK.ToolkitOptions( ); options.Backend = OpenTK.PlatformBackend.PreferNative; options.EnableHighResolution = true; //Just for testing OpenTK.Toolkit.Init(options); // select display device DisplayDevice = OpenTK.DisplayDevice.Default; OpenTKWindow = new OpenTK.GameWindow(size.Width, size.Height, new OpenTK.Graphics.GraphicsMode( ), title, isFullScreen ? OpenTK.GameWindowFlags.Fullscreen : OpenTK.GameWindowFlags.Default); RouteEvents( ); Device = new GLDevice(OpenTKWindow, DisplayDevice); }
public void GetBackBufferData <T>(T[] data) where T : struct { // Store off the old frame buffer components uint prevReadBuffer = GLDevice.CurrentReadFramebuffer; GLDevice.BindReadFramebuffer(GLDevice.Backbuffer.Handle); GCHandle ptr = GCHandle.Alloc(data, GCHandleType.Pinned); try { GLDevice.glReadPixels( 0, 0, GLDevice.Backbuffer.Width, GLDevice.Backbuffer.Height, OpenGLDevice.GLenum.GL_RGBA, OpenGLDevice.GLenum.GL_UNSIGNED_BYTE, ptr.AddrOfPinnedObject() ); } finally { ptr.Free(); } // Restore old buffer components GLDevice.BindReadFramebuffer(prevReadBuffer); // Now we get to do a software-based flip! Yes, really! -flibit int width = GLDevice.Backbuffer.Width; int height = GLDevice.Backbuffer.Height; int pitch = width * 4 / Marshal.SizeOf(typeof(T)); T[] tempRow = new T[pitch]; for (int row = 0; row < height / 2; row += 1) { Array.Copy(data, row * pitch, tempRow, 0, pitch); Array.Copy(data, (height - row - 1) * pitch, data, row * pitch, pitch); Array.Copy(tempRow, 0, data, (height - row - 1) * pitch, pitch); } }
private void ApplyState() { // Apply RasterizerState now, as it depends on other device states GLDevice.ApplyRasterizerState( RasterizerState, RenderTargetCount > 0 ); while (ModifiedSamplers.Count > 0) { int sampler = ModifiedSamplers.Dequeue(); GLDevice.VerifySampler( sampler, Textures[sampler], SamplerStates[sampler] ); } // TODO: MSAA? if (VertexShader == null) { throw new InvalidOperationException("A vertex shader must be set!"); } if (PixelShader == null) { throw new InvalidOperationException("A pixel shader must be set!"); } if (vertexShaderDirty || pixelShaderDirty) { ActivateShaderProgram(); vertexShaderDirty = pixelShaderDirty = false; } vertexConstantBuffers.SetConstantBuffers(this, shaderProgram); pixelConstantBuffers.SetConstantBuffers(this, shaderProgram); }
public GLTextureAtlas(GLDevice device, Int32 maxTextures, Int32 width, Int32 height) : base(device, maxTextures, width, height) { }
public GLTextureAtlas(GLDevice device, int maxTextures, int width, int height) : base(device, maxTextures, width, height) { }
public void SetStringMarkerEXT(string text) { GLDevice.SetStringMarker(text); }
public void SetRenderTargets(params RenderTargetBinding[] renderTargets) { // Checking for redundant SetRenderTargets... if (renderTargets == null && RenderTargetCount == 0) { return; } else if (renderTargets != null && renderTargets.Length == RenderTargetCount) { bool isRedundant = true; for (int i = 0; i < renderTargets.Length; i += 1) { if (renderTargets[i].RenderTarget != renderTargetBindings[i].RenderTarget || renderTargets[i].CubeMapFace != renderTargetBindings[i].CubeMapFace) { isRedundant = false; } } if (isRedundant) { return; } } Array.Clear(renderTargetBindings, 0, renderTargetBindings.Length); if (renderTargets == null || renderTargets.Length == 0) { GLDevice.SetRenderTargets(null, null, 0, DepthFormat.None); RenderTargetCount = 0; // Set the viewport to the size of the backbuffer. Viewport = new Viewport(0, 0, PresentationParameters.BackBufferWidth, PresentationParameters.BackBufferHeight); // Set the scissor rectangle to the size of the backbuffer. ScissorRectangle = new Rectangle(0, 0, PresentationParameters.BackBufferWidth, PresentationParameters.BackBufferHeight); if (PresentationParameters.RenderTargetUsage == RenderTargetUsage.DiscardContents) { Clear(DiscardColor); } } else { uint[] glTarget = new uint[renderTargets.Length]; OpenGLDevice.GLenum[] glTargetFace = new OpenGLDevice.GLenum[renderTargets.Length]; for (int i = 0; i < renderTargets.Length; i += 1) { glTarget[i] = renderTargets[i].RenderTarget.texture.Handle; if (renderTargets[i].RenderTarget is RenderTarget2D) { glTargetFace[i] = OpenGLDevice.GLenum.GL_TEXTURE_2D; } else { glTargetFace[i] = OpenGLDevice.GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int)renderTargets[i].CubeMapFace; } } IRenderTarget target = renderTargets[0].RenderTarget as IRenderTarget; GLDevice.SetRenderTargets( glTarget, glTargetFace, target.DepthStencilBuffer, target.DepthStencilFormat ); Array.Copy(renderTargets, renderTargetBindings, renderTargets.Length); RenderTargetCount = renderTargets.Length; // Set the viewport to the size of the first render target. Viewport = new Viewport(0, 0, target.Width, target.Height); // Set the scissor rectangle to the size of the first render target. ScissorRectangle = new Rectangle(0, 0, target.Width, target.Height); if (target.RenderTargetUsage == RenderTargetUsage.DiscardContents) { Clear(DiscardColor); } } }
public GLTexture(GLDevice device, GLTextureDesc desc) : base(device, desc) { }
/// <summary> /// Activates the Current Vertex/Pixel shader pair into a program. /// </summary> private void ActivateShaderProgram() { // Lookup the shader program. ShaderProgram program = programCache.GetProgram(VertexShader, PixelShader); if (program.Program == 0) { return; } // Set the new program if it has changed. if (shaderProgram != program) { GLDevice.glUseProgram(program.Program); shaderProgram = program; } int posFixupLoc = shaderProgram.GetUniformLocation("posFixup"); if (posFixupLoc == -1) { return; } /* Apply vertex shader fix: * The following two lines are appended to the end of vertex shaders * to account for rendering differences between OpenGL and DirectX: * * gl_Position.y = gl_Position.y * posFixup.y; * gl_Position.xy += posFixup.zw * gl_Position.ww; * * (the following paraphrased from wine, wined3d/state.c and * wined3d/glsl_shader.c) * * - We need to flip along the y-axis in case of offscreen rendering. * - D3D coordinates refer to pixel centers while GL coordinates refer * to pixel corners. * - D3D has a top-left filling convention. We need to maintain this * even after the y-flip mentioned above. * * In order to handle the last two points, we translate by * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to * translating slightly less than half a pixel. We want the difference to * be large enough that it doesn't get lost due to rounding inside the * driver, but small enough to prevent it from interfering with any * anti-aliasing. * * OpenGL coordinates specify the center of the pixel while d3d coords * specify the corner. The offsets are stored in z and w in posFixup. * posFixup.y contains 1.0 or -1.0 to turn the rendering upside down for * offscreen rendering. */ posFixup[0] = 1.0f; posFixup[1] = 1.0f; posFixup[2] = (63.0f / 64.0f) / Viewport.Width; posFixup[3] = -(63.0f / 64.0f) / Viewport.Height; // Flip vertically if we have a render target bound (rendering offscreen) if (RenderTargetCount > 0) { posFixup[1] *= -1.0f; posFixup[3] *= -1.0f; } GLDevice.glUniform4fv( posFixupLoc, 1, posFixupPtr ); }