예제 #1
0
        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();
        }
예제 #2
0
        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)
                );
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
 public void Clear(ClearOptions options, Vector4 color, float depth, int stencil)
 {
     GLDevice.Clear(
         options,
         color,
         depth,
         stencil
         );
 }
예제 #6
0
        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
                );
        }
예제 #7
0
        /// <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))
                );
        }
예제 #8
0
 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);
 }
예제 #9
0
        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();
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
 public GLTextureAtlas(GLDevice device, Int32 maxTextures, Int32 width, Int32 height)
     : base(device, maxTextures, width, height)
 {
 }
예제 #14
0
 public GLTextureAtlas(GLDevice device, int maxTextures, int width, int height)
     : base(device, maxTextures, width, height)
 {
 }
예제 #15
0
 public void SetStringMarkerEXT(string text)
 {
     GLDevice.SetStringMarker(text);
 }
예제 #16
0
        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);
                }
            }
        }
예제 #17
0
 public GLTexture(GLDevice device, GLTextureDesc desc) : base(device, desc)
 {
 }
예제 #18
0
        /// <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
                );
        }