Replace MiniTK.Graphics with custom OpenGL shim.
This commit is contained in:
@@ -10,7 +10,6 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
@@ -18,7 +17,7 @@ namespace OpenRA.Platforms.Default
|
||||
{
|
||||
public static void CheckGlVersion()
|
||||
{
|
||||
var versionString = GL.GetString(StringName.Version);
|
||||
var versionString = OpenGL.glGetString(OpenGL.GL_VERSION);
|
||||
var version = versionString.Contains(" ") ? versionString.Split(' ')[0].Split('.') : versionString.Split('.');
|
||||
|
||||
var major = 0;
|
||||
@@ -39,8 +38,8 @@ namespace OpenRA.Platforms.Default
|
||||
|
||||
public static void CheckGlError()
|
||||
{
|
||||
var n = GL.GetError();
|
||||
if (n != ErrorCode.NoError)
|
||||
var n = OpenGL.glGetError();
|
||||
if (n != OpenGL.GL_NO_ERROR)
|
||||
{
|
||||
var error = "GL Error: {0}\n{1}".F(n, new StackTrace());
|
||||
WriteGraphicsLog(error);
|
||||
@@ -53,8 +52,9 @@ namespace OpenRA.Platforms.Default
|
||||
Log.Write("graphics", message);
|
||||
Log.Write("graphics", "");
|
||||
Log.Write("graphics", "OpenGL Information:");
|
||||
Log.Write("graphics", "Vendor: {0}", GL.GetString(StringName.Vendor));
|
||||
if (GL.GetString(StringName.Vendor).Contains("Microsoft"))
|
||||
var vendor = OpenGL.glGetString(OpenGL.GL_VENDOR);
|
||||
Log.Write("graphics", "Vendor: {0}", vendor);
|
||||
if (vendor.Contains("Microsoft"))
|
||||
{
|
||||
var msg = "";
|
||||
msg += "Note: The default driver provided by Microsoft does not include full OpenGL support.\n";
|
||||
@@ -62,11 +62,11 @@ namespace OpenRA.Platforms.Default
|
||||
Log.Write("graphics", msg);
|
||||
}
|
||||
|
||||
Log.Write("graphics", "Renderer: {0}", GL.GetString(StringName.Renderer));
|
||||
Log.Write("graphics", "GL Version: {0}", GL.GetString(StringName.Version));
|
||||
Log.Write("graphics", "Shader Version: {0}", GL.GetString(StringName.ShadingLanguageVersion));
|
||||
Log.Write("graphics", "Renderer: {0}", OpenGL.glGetString(OpenGL.GL_RENDERER));
|
||||
Log.Write("graphics", "GL Version: {0}", OpenGL.glGetString(OpenGL.GL_VERSION));
|
||||
Log.Write("graphics", "Shader Version: {0}", OpenGL.glGetString(OpenGL.GL_SHADING_LANGUAGE_VERSION));
|
||||
Log.Write("graphics", "Available extensions:");
|
||||
Log.Write("graphics", GL.GetString(StringName.Extensions));
|
||||
Log.Write("graphics", OpenGL.glGetString(OpenGL.GL_EXTENSIONS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
@@ -20,7 +19,7 @@ namespace OpenRA.Platforms.Default
|
||||
{
|
||||
readonly Texture texture;
|
||||
readonly Size size;
|
||||
int framebuffer, depth;
|
||||
uint framebuffer, depth;
|
||||
bool disposed;
|
||||
|
||||
public FrameBuffer(Size size)
|
||||
@@ -29,33 +28,33 @@ namespace OpenRA.Platforms.Default
|
||||
if (!Exts.IsPowerOf2(size.Width) || !Exts.IsPowerOf2(size.Height))
|
||||
throw new InvalidDataException("Frame buffer size ({0}x{1}) must be a power of two".F(size.Width, size.Height));
|
||||
|
||||
GL.Ext.GenFramebuffers(1, out framebuffer);
|
||||
OpenGL.glGenFramebuffersEXT(1, out framebuffer);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer);
|
||||
OpenGL.glBindFramebufferEXT(OpenGL.FRAMEBUFFER_EXT, framebuffer);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
// Color
|
||||
texture = new Texture();
|
||||
texture.SetEmpty(size.Width, size.Height);
|
||||
GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, texture.ID, 0);
|
||||
OpenGL.glFramebufferTexture2DEXT(OpenGL.FRAMEBUFFER_EXT, OpenGL.COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, texture.ID, 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
// Depth
|
||||
GL.Ext.GenRenderbuffers(1, out depth);
|
||||
OpenGL.glGenRenderbuffersEXT(1, out depth);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, depth);
|
||||
OpenGL.glBindRenderbufferEXT(OpenGL.RENDERBUFFER_EXT, depth);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.Ext.RenderbufferStorage(RenderbufferTarget.RenderbufferExt, RenderbufferStorage.DepthComponent, size.Width, size.Height);
|
||||
OpenGL.glRenderbufferStorageEXT(OpenGL.RENDERBUFFER_EXT, OpenGL.GL_DEPTH_COMPONENT, size.Width, size.Height);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, RenderbufferTarget.RenderbufferExt, depth);
|
||||
OpenGL.glFramebufferRenderbufferEXT(OpenGL.FRAMEBUFFER_EXT, OpenGL.DEPTH_ATTACHMENT_EXT, OpenGL.RENDERBUFFER_EXT, depth);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
// Test for completeness
|
||||
var status = GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt);
|
||||
if (status != FramebufferErrorCode.FramebufferCompleteExt)
|
||||
var status = OpenGL.glCheckFramebufferStatus(OpenGL.FRAMEBUFFER_EXT);
|
||||
if (status != OpenGL.FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
var error = "Error creating framebuffer: {0}\n{1}".F(status, new StackTrace());
|
||||
ErrorHandler.WriteGraphicsLog(error);
|
||||
@@ -63,7 +62,7 @@ namespace OpenRA.Platforms.Default
|
||||
}
|
||||
|
||||
// Restore default buffer
|
||||
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
|
||||
OpenGL.glBindFramebufferEXT(OpenGL.FRAMEBUFFER_EXT, 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -73,7 +72,7 @@ namespace OpenRA.Platforms.Default
|
||||
unsafe
|
||||
{
|
||||
fixed (int* ptr = &v[0])
|
||||
GL.GetInteger(GetPName.Viewport, ptr);
|
||||
OpenGL.glGetIntegerv(OpenGL.GL_VIEWPORT, ptr);
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
@@ -88,26 +87,26 @@ namespace OpenRA.Platforms.Default
|
||||
// Cache viewport rect to restore when unbinding
|
||||
cv = ViewportRectangle();
|
||||
|
||||
GL.Flush();
|
||||
OpenGL.glFlush();
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer);
|
||||
OpenGL.glBindFramebufferEXT(OpenGL.FRAMEBUFFER_EXT, framebuffer);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Viewport(0, 0, size.Width, size.Height);
|
||||
OpenGL.glViewport(0, 0, size.Width, size.Height);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.ClearColor(0, 0, 0, 0);
|
||||
OpenGL.glClearColor(0, 0, 0, 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void Unbind()
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.Flush();
|
||||
OpenGL.glFlush();
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
|
||||
OpenGL.glBindFramebufferEXT(OpenGL.FRAMEBUFFER_EXT, 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Viewport(cv[0], cv[1], cv[2], cv[3]);
|
||||
OpenGL.glViewport(cv[0], cv[1], cv[2], cv[3]);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -138,9 +137,10 @@ namespace OpenRA.Platforms.Default
|
||||
disposed = true;
|
||||
if (disposing)
|
||||
texture.Dispose();
|
||||
GL.Ext.DeleteFramebuffers(1, ref framebuffer);
|
||||
|
||||
OpenGL.glDeleteFramebuffersEXT(1, ref framebuffer);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Ext.DeleteRenderbuffers(1, ref depth);
|
||||
OpenGL.glDeleteRenderbuffersEXT(1, ref depth);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
}
|
||||
|
||||
413
OpenRA.Platforms.Default/OpenGL.cs
Normal file
413
OpenRA.Platforms.Default/OpenGL.cs
Normal file
@@ -0,0 +1,413 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SDL2;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1300:ElementMustBeginWithUpperCaseLetter",
|
||||
Justification = "C-style naming is kept for consistency with the underlying native API.")]
|
||||
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore",
|
||||
Justification = "C-style naming is kept for consistency with the underlying native API.")]
|
||||
internal static class OpenGL
|
||||
{
|
||||
public const int GL_FALSE = 0;
|
||||
|
||||
// ClearBufferMask
|
||||
public const int GL_COLOR_BUFFER_BIT = 0x4000;
|
||||
public const int GL_DEPTH_BUFFER_BIT = 0x0100;
|
||||
public const int GL_STENCIL_BUFFER_BIT = 0x0400;
|
||||
|
||||
// Data types
|
||||
public const int GL_UNSIGNED_BYTE = 0x1401;
|
||||
public const int GL_FLOAT = 0x1406;
|
||||
|
||||
// Errors
|
||||
public const int GL_NO_ERROR = 0;
|
||||
|
||||
// BeginMode
|
||||
public const int GL_POINTS = 0;
|
||||
public const int GL_LINES = 0x0001;
|
||||
public const int GL_TRIANGLES = 0x0004;
|
||||
|
||||
// EnableCap
|
||||
public const int GL_ALPHA_TEST = 0x0BC0;
|
||||
public const int GL_BLEND = 0x0BE2;
|
||||
public const int GL_STENCIL_TEST = 0x0B90;
|
||||
public const int GL_DEPTH_TEST = 0x0B71;
|
||||
public const int GL_SCISSOR_TEST = 0x0C11;
|
||||
|
||||
// Texture mapping
|
||||
public const int GL_TEXTURE_2D = 0x0DE1;
|
||||
public const int GL_TEXTURE_WRAP_S = 0x2802;
|
||||
public const int GL_TEXTURE_WRAP_T = 0x2803;
|
||||
public const int GL_TEXTURE_MAG_FILTER = 0x2800;
|
||||
public const int GL_TEXTURE_MIN_FILTER = 0x2801;
|
||||
public const int GL_NEAREST = 0x2600;
|
||||
public const int GL_LINEAR = 0x2601;
|
||||
|
||||
// Depth buffer
|
||||
public const int GL_DEPTH_COMPONENT = 0x1902;
|
||||
|
||||
// BlendingFactorDest
|
||||
public const int GL_ZERO = 0;
|
||||
public const int GL_ONE = 1;
|
||||
public const int GL_SRC_COLOR = 0x0300;
|
||||
public const int GL_ONE_MINUS_SRC_COLOR = 0x0301;
|
||||
public const int GL_SRC_ALPHA = 0x0302;
|
||||
public const int GL_ONE_MINUS_SRC_ALPHA = 0x0303;
|
||||
public const int GL_DST_ALPHA = 0x0304;
|
||||
public const int GL_ONE_MINUS_DST_ALPHA = 0x0305;
|
||||
public const int GL_DST_COLOR = 0x0306;
|
||||
public const int GL_ONE_MINUS_DST_COLOR = 0x0307;
|
||||
|
||||
// GL_ARB_imaging
|
||||
public const int GL_FUNC_ADD = 0x8006;
|
||||
public const int GL_FUNC_SUBTRACT = 0x800A;
|
||||
public const int GL_FUNC_REVERSE_SUBTRACT = 0x800B;
|
||||
public const int GL_BLEND_COLOR = 0x8005;
|
||||
|
||||
// OpenGL 1.1 - 1.5
|
||||
public const int GL_CLIENT_PIXEL_STORE_BIT = 0x0001;
|
||||
public const int GL_BGRA = 0x80E1;
|
||||
public const int GL_RGBA8 = 0x8058;
|
||||
public const int GL_CLAMP_TO_EDGE = 0x812F;
|
||||
public const int GL_TEXTURE_BASE_LEVEL = 0x813C;
|
||||
public const int GL_TEXTURE_MAX_LEVEL = 0x813D;
|
||||
|
||||
public const int GL_ARRAY_BUFFER = 0x8892;
|
||||
public const int GL_DYNAMIC_DRAW = 0x88E8;
|
||||
|
||||
public const int GL_TEXTURE0 = 0x84C0;
|
||||
|
||||
// OpenGL 2
|
||||
public const int GL_FRAGMENT_SHADER = 0x8B30;
|
||||
public const int GL_VERTEX_SHADER = 0x8B31;
|
||||
public const int GL_SAMPLER_2D = 0x8B5E;
|
||||
public const int GL_COMPILE_STATUS = 0x8B81;
|
||||
public const int GL_LINK_STATUS = 0x8B82;
|
||||
public const int GL_INFO_LOG_LENGTH = 0x8B84;
|
||||
public const int GL_ACTIVE_UNIFORMS = 0x8B86;
|
||||
|
||||
// Pixel Mode / Transfer
|
||||
public const int GL_PACK_ROW_LENGTH = 0x0D02;
|
||||
public const int GL_PACK_ALIGNMENT = 0x0D05;
|
||||
|
||||
// Gets
|
||||
public const int GL_VIEWPORT = 0x0BA2;
|
||||
|
||||
// Utility
|
||||
public const int GL_VENDOR = 0x1F00;
|
||||
public const int GL_RENDERER = 0x1F01;
|
||||
public const int GL_VERSION = 0x1F02;
|
||||
public const int GL_EXTENSIONS = 0x1F03;
|
||||
public const int GL_SHADING_LANGUAGE_VERSION = 0x8B8C;
|
||||
|
||||
// Framebuffers
|
||||
public const int FRAMEBUFFER_EXT = 0x8D40;
|
||||
public const int RENDERBUFFER_EXT = 0x8D41;
|
||||
public const int COLOR_ATTACHMENT0_EXT = 0x8CE0;
|
||||
public const int DEPTH_ATTACHMENT_EXT = 0x8D00;
|
||||
public const int FRAMEBUFFER_COMPLETE_EXT = 0x8CD5;
|
||||
|
||||
public delegate void Flush();
|
||||
public static Flush glFlush { get; private set; }
|
||||
|
||||
public delegate void Viewport(int x, int y, int width, int height);
|
||||
public static Viewport glViewport { get; private set; }
|
||||
|
||||
public delegate void Clear(int mask);
|
||||
public static Clear glClear { get; private set; }
|
||||
|
||||
public delegate void ClearColor(float red, float green, float blue, float alpha);
|
||||
public static ClearColor glClearColor { get; private set; }
|
||||
|
||||
public delegate int GetError();
|
||||
public static GetError glGetError { get; private set; }
|
||||
|
||||
delegate IntPtr GetString(int name);
|
||||
static GetString glGetStringInternal;
|
||||
|
||||
public static string glGetString(int name)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return new string((sbyte*)glGetStringInternal(name));
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe delegate int GetIntegerv(int pname, int* param);
|
||||
public static GetIntegerv glGetIntegerv { get; private set; }
|
||||
|
||||
public delegate void Finish();
|
||||
public static Finish glFinish { get; private set; }
|
||||
|
||||
public delegate uint CreateProgram();
|
||||
public static CreateProgram glCreateProgram { get; private set; }
|
||||
|
||||
public delegate void UseProgram(uint program);
|
||||
public static UseProgram glUseProgram { get; private set; }
|
||||
|
||||
public delegate void GetProgramiv(uint program, int pname, out int param);
|
||||
public static GetProgramiv glGetProgramiv { get; private set; }
|
||||
|
||||
public delegate uint CreateShader(int shaderType);
|
||||
public static CreateShader glCreateShader { get; private set; }
|
||||
|
||||
public delegate void ShaderSource(uint shader, int count, string[] str, IntPtr length);
|
||||
public static ShaderSource glShaderSource { get; private set; }
|
||||
|
||||
public delegate void CompileShader(uint shader);
|
||||
public static CompileShader glCompileShader { get; private set; }
|
||||
|
||||
public delegate int GetShaderiv(uint shader, int name, out int param);
|
||||
public static GetShaderiv glGetShaderiv { get; private set; }
|
||||
|
||||
public delegate void AttachShader(uint program, uint shader);
|
||||
public static AttachShader glAttachShader { get; private set; }
|
||||
|
||||
public delegate void GetShaderInfoLog(uint shader, int maxLength, out int length, StringBuilder infoLog);
|
||||
public static GetShaderInfoLog glGetShaderInfoLog { get; private set; }
|
||||
|
||||
public delegate void LinkProgram(uint program);
|
||||
public static LinkProgram glLinkProgram { get; private set; }
|
||||
|
||||
public delegate void GetProgramInfoLog(uint program, int maxLength, out int length, StringBuilder infoLog);
|
||||
public static GetProgramInfoLog glGetProgramInfoLog { get; private set; }
|
||||
|
||||
public delegate int GetUniformLocation(uint program, string name);
|
||||
public static GetUniformLocation glGetUniformLocation { get; private set; }
|
||||
|
||||
public delegate void GetActiveUniform(uint program, int index, int bufSize,
|
||||
out int length, out int size, out int type, StringBuilder name);
|
||||
public static GetActiveUniform glGetActiveUniform { get; private set; }
|
||||
|
||||
public delegate void Uniform1i(int location, int v0);
|
||||
public static Uniform1i glUniform1i { get; private set; }
|
||||
|
||||
public delegate void Uniform1f(int location, float v0);
|
||||
public static Uniform1f glUniform1f { get; private set; }
|
||||
|
||||
public delegate void Uniform2f(int location, float v0, float v1);
|
||||
public static Uniform2f glUniform2f { get; private set; }
|
||||
|
||||
public delegate void Uniform1fv(int location, int count, IntPtr value);
|
||||
public static Uniform1fv glUniform1fv { get; private set; }
|
||||
|
||||
public delegate void Uniform2fv(int location, int count, IntPtr value);
|
||||
public static Uniform2fv glUniform2fv { get; private set; }
|
||||
|
||||
public delegate void Uniform3fv(int location, int count, IntPtr value);
|
||||
public static Uniform3fv glUniform3fv { get; private set; }
|
||||
|
||||
public delegate void Uniform4fv(int location, int count, IntPtr value);
|
||||
public static Uniform4fv glUniform4fv { get; private set; }
|
||||
|
||||
public delegate void UniformMatrix4fv(int location, int count, bool transpose, IntPtr value);
|
||||
public static UniformMatrix4fv glUniformMatrix4fv { get; private set; }
|
||||
|
||||
public delegate void GenBuffers(int n, out uint buffers);
|
||||
public static GenBuffers glGenBuffers { get; private set; }
|
||||
|
||||
public delegate void BindBuffer(int target, uint buffer);
|
||||
public static BindBuffer glBindBuffer { get; private set; }
|
||||
|
||||
public delegate void BufferData(int target, IntPtr size, IntPtr data, int usage);
|
||||
public static BufferData glBufferData { get; private set; }
|
||||
|
||||
public delegate void BufferSubData(int target, IntPtr offset, IntPtr size, IntPtr data);
|
||||
public static BufferSubData glBufferSubData { get; private set; }
|
||||
|
||||
public delegate void DeleteBuffers(int n, ref uint buffers);
|
||||
public static DeleteBuffers glDeleteBuffers { get; private set; }
|
||||
|
||||
public delegate void BindAttribLocation(uint program, int index, string name);
|
||||
public static BindAttribLocation glBindAttribLocation { get; private set; }
|
||||
|
||||
public delegate void VertexAttribPointer(int index, int size, int type, bool normalized,
|
||||
int stride, IntPtr pointer);
|
||||
public static VertexAttribPointer glVertexAttribPointer { get; private set; }
|
||||
|
||||
public delegate void EnableVertexAttribArray(int index);
|
||||
public static EnableVertexAttribArray glEnableVertexAttribArray { get; private set; }
|
||||
|
||||
public delegate void DisableVertexAttribArray(int index);
|
||||
public static DisableVertexAttribArray glDisableVertexAttribArray { get; private set; }
|
||||
|
||||
public delegate void DrawArrays(int mode, int first, int count);
|
||||
public static DrawArrays glDrawArrays { get; private set; }
|
||||
|
||||
public delegate void Enable(int cap);
|
||||
public static Enable glEnable { get; private set; }
|
||||
|
||||
public delegate void Disable(int cap);
|
||||
public static Disable glDisable { get; private set; }
|
||||
|
||||
public delegate void BlendEquation(int mode);
|
||||
public static BlendEquation glBlendEquation { get; private set; }
|
||||
|
||||
public delegate void BlendFunc(int sfactor, int dfactor);
|
||||
public static BlendFunc glBlendFunc { get; private set; }
|
||||
|
||||
public delegate void Scissor(int x, int y, int width, int height);
|
||||
public static Scissor glScissor { get; private set; }
|
||||
|
||||
public delegate void PushClientAttrib(int mask);
|
||||
public static PushClientAttrib glPushClientAttrib { get; private set; }
|
||||
|
||||
public delegate void PopClientAttrib();
|
||||
public static PopClientAttrib glPopClientAttrib { get; private set; }
|
||||
|
||||
public delegate void PixelStoref(int param, float pname);
|
||||
public static PixelStoref glPixelStoref { get; private set; }
|
||||
|
||||
public delegate void ReadPixels(int x, int y, int width, int height,
|
||||
int format, int type, IntPtr data);
|
||||
public static ReadPixels glReadPixels { get; private set; }
|
||||
|
||||
public delegate void GenTextures(int n, out uint textures);
|
||||
public static GenTextures glGenTextures { get; private set; }
|
||||
|
||||
public delegate void DeleteTextures(int n, ref uint textures);
|
||||
public static DeleteTextures glDeleteTextures { get; private set; }
|
||||
|
||||
public delegate void BindTexture(int target, uint texture);
|
||||
public static BindTexture glBindTexture { get; private set; }
|
||||
|
||||
public delegate void ActiveTexture(int texture);
|
||||
public static ActiveTexture glActiveTexture { get; private set; }
|
||||
|
||||
public delegate void TexImage2D(int target, int level, int internalFormat,
|
||||
int width, int height, int border, int format, int type, IntPtr pixels);
|
||||
public static TexImage2D glTexImage2D { get; private set; }
|
||||
|
||||
public delegate void GetTexImage(int target, int level,
|
||||
int format, int type, IntPtr pixels);
|
||||
public static GetTexImage glGetTexImage { get; private set; }
|
||||
|
||||
public delegate void TexParameteri(int target, int pname, int param);
|
||||
public static TexParameteri glTexParameteri { get; private set; }
|
||||
|
||||
public delegate void TexParameterf(int target, int pname, float param);
|
||||
public static TexParameterf glTexParameterf { get; private set; }
|
||||
|
||||
public delegate void GenFramebuffersEXT(int n, out uint framebuffers);
|
||||
public static GenFramebuffersEXT glGenFramebuffersEXT { get; private set; }
|
||||
|
||||
public delegate void BindFramebufferEXT(int target, uint framebuffer);
|
||||
public static BindFramebufferEXT glBindFramebufferEXT { get; private set; }
|
||||
|
||||
public delegate void FramebufferTexture2DEXT(int target, int attachment,
|
||||
int textarget, uint texture, int level);
|
||||
public static FramebufferTexture2DEXT glFramebufferTexture2DEXT { get; private set; }
|
||||
|
||||
public delegate void DeleteFramebuffersEXT(int n, ref uint framebuffers);
|
||||
public static DeleteFramebuffersEXT glDeleteFramebuffersEXT { get; private set; }
|
||||
|
||||
public delegate void GenRenderbuffersEXT(int n, out uint renderbuffers);
|
||||
public static GenRenderbuffersEXT glGenRenderbuffersEXT { get; private set; }
|
||||
|
||||
public delegate void BindRenderbufferEXT(int target, uint renderbuffer);
|
||||
public static BindRenderbufferEXT glBindRenderbufferEXT { get; private set; }
|
||||
|
||||
public delegate void RenderbufferStorageEXT(int target, int internalformat,
|
||||
int width, int height);
|
||||
public static RenderbufferStorageEXT glRenderbufferStorageEXT { get; private set; }
|
||||
|
||||
public delegate void DeleteRenderbuffersEXT(int n, ref uint renderbuffers);
|
||||
public static DeleteRenderbuffersEXT glDeleteRenderbuffersEXT { get; private set; }
|
||||
|
||||
public delegate void FramebufferRenderbufferEXT(int target, int attachment,
|
||||
int renderbuffertarget, uint renderbuffer);
|
||||
public static FramebufferRenderbufferEXT glFramebufferRenderbufferEXT { get; private set; }
|
||||
|
||||
public delegate int CheckFramebufferStatus(int target);
|
||||
public static CheckFramebufferStatus glCheckFramebufferStatus { get; private set; }
|
||||
|
||||
public static void LoadDelegates()
|
||||
{
|
||||
glFlush = Bind<Flush>("glFlush");
|
||||
glViewport = Bind<Viewport>("glViewport");
|
||||
glClear = Bind<Clear>("glClear");
|
||||
glClearColor = Bind<ClearColor>("glClearColor");
|
||||
glGetError = Bind<GetError>("glGetError");
|
||||
glGetStringInternal = Bind<GetString>("glGetString");
|
||||
glGetIntegerv = Bind<GetIntegerv>("glGetIntegerv");
|
||||
glFinish = Bind<Finish>("glFinish");
|
||||
glCreateProgram = Bind<CreateProgram>("glCreateProgram");
|
||||
glUseProgram = Bind<UseProgram>("glUseProgram");
|
||||
glGetProgramiv = Bind<GetProgramiv>("glGetProgramiv");
|
||||
glCreateShader = Bind<CreateShader>("glCreateShader");
|
||||
glShaderSource = Bind<ShaderSource>("glShaderSource");
|
||||
glCompileShader = Bind<CompileShader>("glCompileShader");
|
||||
glGetShaderiv = Bind<GetShaderiv>("glGetShaderiv");
|
||||
glAttachShader = Bind<AttachShader>("glAttachShader");
|
||||
glGetShaderInfoLog = Bind<GetShaderInfoLog>("glGetShaderInfoLog");
|
||||
glLinkProgram = Bind<LinkProgram>("glLinkProgram");
|
||||
glGetProgramInfoLog = Bind<GetProgramInfoLog>("glGetProgramInfoLog");
|
||||
glGetUniformLocation = Bind<GetUniformLocation>("glGetUniformLocation");
|
||||
glGetActiveUniform = Bind<GetActiveUniform>("glGetActiveUniform");
|
||||
glUniform1i = Bind<Uniform1i>("glUniform1i");
|
||||
glUniform1f = Bind<Uniform1f>("glUniform1f");
|
||||
glUniform2f = Bind<Uniform2f>("glUniform2f");
|
||||
glUniform1fv = Bind<Uniform1fv>("glUniform1fv");
|
||||
glUniform2fv = Bind<Uniform2fv>("glUniform2fv");
|
||||
glUniform3fv = Bind<Uniform3fv>("glUniform3fv");
|
||||
glUniform4fv = Bind<Uniform4fv>("glUniform4fv");
|
||||
glUniformMatrix4fv = Bind<UniformMatrix4fv>("glUniformMatrix4fv");
|
||||
glGenBuffers = Bind<GenBuffers>("glGenBuffers");
|
||||
glBindBuffer = Bind<BindBuffer>("glBindBuffer");
|
||||
glBufferData = Bind<BufferData>("glBufferData");
|
||||
glBufferSubData = Bind<BufferSubData>("glBufferSubData");
|
||||
glDeleteBuffers = Bind<DeleteBuffers>("glDeleteBuffers");
|
||||
glBindAttribLocation = Bind<BindAttribLocation>("glBindAttribLocation");
|
||||
glVertexAttribPointer = Bind<VertexAttribPointer>("glVertexAttribPointer");
|
||||
glEnableVertexAttribArray = Bind<EnableVertexAttribArray>("glEnableVertexAttribArray");
|
||||
glDisableVertexAttribArray = Bind<DisableVertexAttribArray>("glDisableVertexAttribArray");
|
||||
glDrawArrays = Bind<DrawArrays>("glDrawArrays");
|
||||
glEnable = Bind<Enable>("glEnable");
|
||||
glDisable = Bind<Disable>("glDisable");
|
||||
glBlendEquation = Bind<BlendEquation>("glBlendEquation");
|
||||
glBlendFunc = Bind<BlendFunc>("glBlendFunc");
|
||||
glScissor = Bind<Scissor>("glScissor");
|
||||
glPushClientAttrib = Bind<PushClientAttrib>("glPushClientAttrib");
|
||||
glPopClientAttrib = Bind<PopClientAttrib>("glPopClientAttrib");
|
||||
glPixelStoref = Bind<PixelStoref>("glPixelStoref");
|
||||
glReadPixels = Bind<ReadPixels>("glReadPixels");
|
||||
glGenTextures = Bind<GenTextures>("glGenTextures");
|
||||
glDeleteTextures = Bind<DeleteTextures>("glDeleteTextures");
|
||||
glBindTexture = Bind<BindTexture>("glBindTexture");
|
||||
glActiveTexture = Bind<ActiveTexture>("glActiveTexture");
|
||||
glTexImage2D = Bind<TexImage2D>("glTexImage2D");
|
||||
glGetTexImage = Bind<GetTexImage>("glGetTexImage");
|
||||
glTexParameteri = Bind<TexParameteri>("glTexParameteri");
|
||||
glTexParameterf = Bind<TexParameterf>("glTexParameterf");
|
||||
glGenFramebuffersEXT = Bind<GenFramebuffersEXT>("glGenFramebuffersEXT");
|
||||
glBindFramebufferEXT = Bind<BindFramebufferEXT>("glBindFramebufferEXT");
|
||||
glFramebufferTexture2DEXT = Bind<FramebufferTexture2DEXT>("glFramebufferTexture2DEXT");
|
||||
glDeleteFramebuffersEXT = Bind<DeleteFramebuffersEXT>("glDeleteFramebuffersEXT");
|
||||
glGenRenderbuffersEXT = Bind<GenRenderbuffersEXT>("glGenRenderbuffersEXT");
|
||||
glBindRenderbufferEXT = Bind<BindRenderbufferEXT>("glBindRenderbufferEXT");
|
||||
glRenderbufferStorageEXT = Bind<RenderbufferStorageEXT>("glRenderbufferStorageEXT");
|
||||
glDeleteRenderbuffersEXT = Bind<DeleteRenderbuffersEXT>("glDeleteRenderbuffersEXT");
|
||||
glFramebufferRenderbufferEXT = Bind<FramebufferRenderbufferEXT>("glFramebufferRenderbufferEXT");
|
||||
glCheckFramebufferStatus = Bind<CheckFramebufferStatus>("glCheckFramebufferStatus");
|
||||
}
|
||||
|
||||
static T Bind<T>(string name)
|
||||
{
|
||||
return (T)(object)Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress(name), typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@
|
||||
<Compile Include="ThreadAffine.cs" />
|
||||
<Compile Include="VertexBuffer.cs" />
|
||||
<Compile Include="OpenAlSoundEngine.cs" />
|
||||
<Compile Include="OpenGL.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
||||
@@ -15,8 +15,6 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using OpenRA;
|
||||
using OpenRA.Graphics;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using SDL2;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
@@ -78,9 +76,7 @@ namespace OpenRA.Platforms.Default
|
||||
if (context == IntPtr.Zero || SDL.SDL_GL_MakeCurrent(window, context) < 0)
|
||||
throw new InvalidOperationException("Can not create OpenGL context. (Error: {0})".F(SDL.SDL_GetError()));
|
||||
|
||||
GraphicsContext.CurrentContext = context;
|
||||
|
||||
GL.LoadAll();
|
||||
OpenGL.LoadDelegates();
|
||||
ErrorHandler.CheckGlVersion();
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
@@ -91,9 +87,9 @@ namespace OpenRA.Platforms.Default
|
||||
throw new InvalidProgramException("Missing OpenGL extension GL_EXT_framebuffer_object. See graphics.log for details.");
|
||||
}
|
||||
|
||||
GL.EnableVertexAttribArray(Shader.VertexPosAttributeIndex);
|
||||
OpenGL.glEnableVertexAttribArray(Shader.VertexPosAttributeIndex);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.EnableVertexAttribArray(Shader.TexCoordAttributeIndex);
|
||||
OpenGL.glEnableVertexAttribArray(Shader.TexCoordAttributeIndex);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
SDL.SDL_SetModState(SDL.SDL_Keymod.KMOD_NONE);
|
||||
@@ -203,13 +199,13 @@ namespace OpenRA.Platforms.Default
|
||||
SDL.SDL_Quit();
|
||||
}
|
||||
|
||||
static BeginMode ModeFromPrimitiveType(PrimitiveType pt)
|
||||
static int ModeFromPrimitiveType(PrimitiveType pt)
|
||||
{
|
||||
switch (pt)
|
||||
{
|
||||
case PrimitiveType.PointList: return BeginMode.Points;
|
||||
case PrimitiveType.LineList: return BeginMode.Lines;
|
||||
case PrimitiveType.TriangleList: return BeginMode.Triangles;
|
||||
case PrimitiveType.PointList: return OpenGL.GL_POINTS;
|
||||
case PrimitiveType.LineList: return OpenGL.GL_LINES;
|
||||
case PrimitiveType.TriangleList: return OpenGL.GL_TRIANGLES;
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
@@ -218,78 +214,78 @@ namespace OpenRA.Platforms.Default
|
||||
public void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.DrawArrays(ModeFromPrimitiveType(pt), firstVertex, numVertices);
|
||||
OpenGL.glDrawArrays(ModeFromPrimitiveType(pt), firstVertex, numVertices);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.ClearColor(0, 0, 0, 1);
|
||||
OpenGL.glClearColor(0, 0, 0, 1);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void EnableDepthBuffer()
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.Clear(ClearBufferMask.DepthBufferBit);
|
||||
OpenGL.glClear(OpenGL.GL_DEPTH_BUFFER_BIT);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
OpenGL.glEnable(OpenGL.GL_DEPTH_TEST);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void DisableDepthBuffer()
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
OpenGL.glDisable(OpenGL.GL_DEPTH_TEST);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void SetBlendMode(BlendMode mode)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.BlendEquation(BlendEquationMode.FuncAdd);
|
||||
OpenGL.glBlendEquation(OpenGL.GL_FUNC_ADD);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case BlendMode.None:
|
||||
GL.Disable(EnableCap.Blend);
|
||||
OpenGL.glDisable(OpenGL.GL_BLEND);
|
||||
break;
|
||||
case BlendMode.Alpha:
|
||||
GL.Enable(EnableCap.Blend);
|
||||
OpenGL.glEnable(OpenGL.GL_BLEND);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
|
||||
OpenGL.glBlendFunc(OpenGL.GL_ONE, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case BlendMode.Additive:
|
||||
case BlendMode.Subtractive:
|
||||
GL.Enable(EnableCap.Blend);
|
||||
OpenGL.glEnable(OpenGL.GL_BLEND);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One);
|
||||
OpenGL.glBlendFunc(OpenGL.GL_ONE, OpenGL.GL_ONE);
|
||||
if (mode == BlendMode.Subtractive)
|
||||
{
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BlendEquation(BlendEquationMode.FuncReverseSubtract);
|
||||
OpenGL.glBlendEquation(OpenGL.GL_FUNC_REVERSE_SUBTRACT);
|
||||
}
|
||||
|
||||
break;
|
||||
case BlendMode.Multiply:
|
||||
GL.Enable(EnableCap.Blend);
|
||||
OpenGL.glEnable(OpenGL.GL_BLEND);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.OneMinusSrcAlpha);
|
||||
OpenGL.glBlendFunc(OpenGL.GL_DST_COLOR, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
|
||||
ErrorHandler.CheckGlError();
|
||||
break;
|
||||
case BlendMode.Multiplicative:
|
||||
GL.Enable(EnableCap.Blend);
|
||||
OpenGL.glEnable(OpenGL.GL_BLEND);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.SrcColor);
|
||||
OpenGL.glBlendFunc(OpenGL.GL_ZERO, OpenGL.GL_SRC_COLOR);
|
||||
break;
|
||||
case BlendMode.DoubleMultiplicative:
|
||||
GL.Enable(EnableCap.Blend);
|
||||
OpenGL.glEnable(OpenGL.GL_BLEND);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.SrcColor);
|
||||
OpenGL.glBlendFunc(OpenGL.GL_DST_COLOR, OpenGL.GL_SRC_COLOR);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -318,16 +314,16 @@ namespace OpenRA.Platforms.Default
|
||||
if (height < 0)
|
||||
height = 0;
|
||||
|
||||
GL.Scissor(left, WindowSize.Height - (top + height), width, height);
|
||||
OpenGL.glScissor(left, WindowSize.Height - (top + height), width, height);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
OpenGL.glEnable(OpenGL.GL_SCISSOR_TEST);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void DisableScissor()
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.Disable(EnableCap.ScissorTest);
|
||||
OpenGL.glDisable(OpenGL.GL_SCISSOR_TEST);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -338,15 +334,15 @@ namespace OpenRA.Platforms.Default
|
||||
var data = bitmap.LockBits(rect,
|
||||
System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
GL.PushClientAttrib(ClientAttribMask.ClientPixelStoreBit);
|
||||
OpenGL.glPushClientAttrib(OpenGL.GL_CLIENT_PIXEL_STORE_BIT);
|
||||
|
||||
GL.PixelStore(PixelStoreParameter.PackRowLength, data.Stride / 4f);
|
||||
GL.PixelStore(PixelStoreParameter.PackAlignment, 1);
|
||||
OpenGL.glPixelStoref(OpenGL.GL_PACK_ROW_LENGTH, data.Stride / 4f);
|
||||
OpenGL.glPixelStoref(OpenGL.GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
GL.ReadPixels(rect.X, rect.Y, rect.Width, rect.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
|
||||
GL.Finish();
|
||||
OpenGL.glReadPixels(rect.X, rect.Y, rect.Width, rect.Height, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, data.Scan0);
|
||||
OpenGL.glFinish();
|
||||
|
||||
GL.PopClientAttrib();
|
||||
OpenGL.glPopClientAttrib();
|
||||
|
||||
bitmap.UnlockBits(data);
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
@@ -23,32 +22,35 @@ namespace OpenRA.Platforms.Default
|
||||
|
||||
readonly Dictionary<string, int> samplers = new Dictionary<string, int>();
|
||||
readonly Dictionary<int, ITexture> textures = new Dictionary<int, ITexture>();
|
||||
readonly int program;
|
||||
readonly uint program;
|
||||
|
||||
protected int CompileShaderObject(ShaderType type, string name)
|
||||
protected uint CompileShaderObject(int type, string name)
|
||||
{
|
||||
var ext = type == ShaderType.VertexShader ? "vert" : "frag";
|
||||
var ext = type == OpenGL.GL_VERTEX_SHADER ? "vert" : "frag";
|
||||
var filename = Path.Combine(Platform.GameDir, "glsl", name + "." + ext);
|
||||
var code = File.ReadAllText(filename);
|
||||
|
||||
var shader = GL.CreateShader(type);
|
||||
var shader = OpenGL.glCreateShader(type);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.ShaderSource(shader, code);
|
||||
unsafe
|
||||
{
|
||||
var length = code.Length;
|
||||
OpenGL.glShaderSource(shader, 1, new string[] { code }, new IntPtr(&length));
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.CompileShader(shader);
|
||||
OpenGL.glCompileShader(shader);
|
||||
ErrorHandler.CheckGlError();
|
||||
int success;
|
||||
GL.GetShader(shader, ShaderParameter.CompileStatus, out success);
|
||||
OpenGL.glGetShaderiv(shader, OpenGL.GL_COMPILE_STATUS, out success);
|
||||
ErrorHandler.CheckGlError();
|
||||
if (success == (int)All.False)
|
||||
if (success == (int)OpenGL.GL_FALSE)
|
||||
{
|
||||
int len;
|
||||
GL.GetShader(shader, ShaderParameter.InfoLogLength, out len);
|
||||
OpenGL.glGetShaderiv(shader, OpenGL.GL_INFO_LOG_LENGTH, out len);
|
||||
var log = new StringBuilder(len);
|
||||
unsafe
|
||||
{
|
||||
GL.GetShaderInfoLog(shader, len, null, log);
|
||||
}
|
||||
int length;
|
||||
OpenGL.glGetShaderInfoLog(shader, len, out length, log);
|
||||
|
||||
Log.Write("graphics", "GL Info Log:\n{0}", log.ToString());
|
||||
throw new InvalidProgramException("Compile error in shader object '{0}'".F(filename));
|
||||
@@ -59,66 +61,65 @@ namespace OpenRA.Platforms.Default
|
||||
|
||||
public Shader(string name)
|
||||
{
|
||||
var vertexShader = CompileShaderObject(ShaderType.VertexShader, name);
|
||||
var fragmentShader = CompileShaderObject(ShaderType.FragmentShader, name);
|
||||
var vertexShader = CompileShaderObject(OpenGL.GL_VERTEX_SHADER, name);
|
||||
var fragmentShader = CompileShaderObject(OpenGL.GL_FRAGMENT_SHADER, name);
|
||||
|
||||
// Assemble program
|
||||
program = GL.CreateProgram();
|
||||
program = OpenGL.glCreateProgram();
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.BindAttribLocation(program, VertexPosAttributeIndex, "aVertexPosition");
|
||||
OpenGL.glBindAttribLocation(program, VertexPosAttributeIndex, "aVertexPosition");
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BindAttribLocation(program, TexCoordAttributeIndex, "aVertexTexCoord");
|
||||
OpenGL.glBindAttribLocation(program, TexCoordAttributeIndex, "aVertexTexCoord");
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.AttachShader(program, vertexShader);
|
||||
OpenGL.glAttachShader(program, vertexShader);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.AttachShader(program, fragmentShader);
|
||||
OpenGL.glAttachShader(program, fragmentShader);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.LinkProgram(program);
|
||||
OpenGL.glLinkProgram(program);
|
||||
ErrorHandler.CheckGlError();
|
||||
int success;
|
||||
GL.GetProgram(program, ProgramParameter.LinkStatus, out success);
|
||||
OpenGL.glGetProgramiv(program, OpenGL.GL_LINK_STATUS, out success);
|
||||
ErrorHandler.CheckGlError();
|
||||
if (success == (int)All.False)
|
||||
if (success == (int)OpenGL.GL_FALSE)
|
||||
{
|
||||
int len;
|
||||
GL.GetProgram(program, ProgramParameter.InfoLogLength, out len);
|
||||
var log = new StringBuilder(len);
|
||||
unsafe
|
||||
{
|
||||
GL.GetProgramInfoLog(program, len, null, log);
|
||||
}
|
||||
OpenGL.glGetProgramiv(program, OpenGL.GL_INFO_LOG_LENGTH, out len);
|
||||
|
||||
var log = new StringBuilder(len);
|
||||
int length;
|
||||
OpenGL.glGetProgramInfoLog(program, len, out length, log);
|
||||
Log.Write("graphics", "GL Info Log:\n{0}", log.ToString());
|
||||
throw new InvalidProgramException("Link error in shader program '{0}'".F(name));
|
||||
}
|
||||
|
||||
GL.UseProgram(program);
|
||||
OpenGL.glUseProgram(program);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
int numUniforms;
|
||||
GL.GetProgram(program, ProgramParameter.ActiveUniforms, out numUniforms);
|
||||
OpenGL.glGetProgramiv(program, OpenGL.GL_ACTIVE_UNIFORMS, out numUniforms);
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
var nextTexUnit = 0;
|
||||
for (var i = 0; i < numUniforms; i++)
|
||||
{
|
||||
int length, size;
|
||||
ActiveUniformType type;
|
||||
int type;
|
||||
var sb = new StringBuilder(128);
|
||||
GL.GetActiveUniform(program, i, 128, out length, out size, out type, sb);
|
||||
OpenGL.glGetActiveUniform(program, i, 128, out length, out size, out type, sb);
|
||||
var sampler = sb.ToString();
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
if (type == ActiveUniformType.Sampler2D)
|
||||
if (type == OpenGL.GL_SAMPLER_2D)
|
||||
{
|
||||
samplers.Add(sampler, nextTexUnit);
|
||||
|
||||
var loc = GL.GetUniformLocation(program, sampler);
|
||||
var loc = OpenGL.glGetUniformLocation(program, sampler);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Uniform1(loc, nextTexUnit);
|
||||
OpenGL.glUniform1i(loc, nextTexUnit);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
nextTexUnit++;
|
||||
@@ -129,13 +130,13 @@ namespace OpenRA.Platforms.Default
|
||||
public void Render(Action a)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.UseProgram(program);
|
||||
OpenGL.glUseProgram(program);
|
||||
|
||||
// bind the textures
|
||||
foreach (var kv in textures)
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + kv.Key);
|
||||
GL.BindTexture(TextureTarget.Texture2D, ((Texture)kv.Value).ID);
|
||||
OpenGL.glActiveTexture(OpenGL.GL_TEXTURE0 + kv.Key);
|
||||
OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, ((Texture)kv.Value).ID);
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
@@ -157,48 +158,55 @@ namespace OpenRA.Platforms.Default
|
||||
public void SetBool(string name, bool value)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.UseProgram(program);
|
||||
OpenGL.glUseProgram(program);
|
||||
ErrorHandler.CheckGlError();
|
||||
var param = GL.GetUniformLocation(program, name);
|
||||
var param = OpenGL.glGetUniformLocation(program, name);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Uniform1(param, value ? 1 : 0);
|
||||
OpenGL.glUniform1i(param, value ? 1 : 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void SetVec(string name, float x)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.UseProgram(program);
|
||||
OpenGL.glUseProgram(program);
|
||||
ErrorHandler.CheckGlError();
|
||||
var param = GL.GetUniformLocation(program, name);
|
||||
var param = OpenGL.glGetUniformLocation(program, name);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Uniform1(param, x);
|
||||
OpenGL.glUniform1f(param, x);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void SetVec(string name, float x, float y)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.UseProgram(program);
|
||||
OpenGL.glUseProgram(program);
|
||||
ErrorHandler.CheckGlError();
|
||||
var param = GL.GetUniformLocation(program, name);
|
||||
var param = OpenGL.glGetUniformLocation(program, name);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.Uniform2(param, x, y);
|
||||
OpenGL.glUniform2f(param, x, y);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void SetVec(string name, float[] vec, int length)
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
var param = GL.GetUniformLocation(program, name);
|
||||
var param = OpenGL.glGetUniformLocation(program, name);
|
||||
ErrorHandler.CheckGlError();
|
||||
switch (length)
|
||||
unsafe
|
||||
{
|
||||
case 1: GL.Uniform1(param, 1, vec); break;
|
||||
case 2: GL.Uniform2(param, 1, vec); break;
|
||||
case 3: GL.Uniform3(param, 1, vec); break;
|
||||
case 4: GL.Uniform4(param, 1, vec); break;
|
||||
default: throw new InvalidDataException("Invalid vector length");
|
||||
fixed (float* pVec = vec)
|
||||
{
|
||||
var ptr = new IntPtr(pVec);
|
||||
switch (length)
|
||||
{
|
||||
case 1: OpenGL.glUniform1fv(param, 1, ptr); break;
|
||||
case 2: OpenGL.glUniform2fv(param, 1, ptr); break;
|
||||
case 3: OpenGL.glUniform3fv(param, 1, ptr); break;
|
||||
case 4: OpenGL.glUniform4fv(param, 1, ptr); break;
|
||||
default: throw new InvalidDataException("Invalid vector length");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
@@ -210,11 +218,17 @@ namespace OpenRA.Platforms.Default
|
||||
if (mtx.Length != 16)
|
||||
throw new InvalidDataException("Invalid 4x4 matrix");
|
||||
|
||||
GL.UseProgram(program);
|
||||
OpenGL.glUseProgram(program);
|
||||
ErrorHandler.CheckGlError();
|
||||
var param = GL.GetUniformLocation(program, name);
|
||||
var param = OpenGL.glGetUniformLocation(program, name);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.UniformMatrix4(param, 1, false, mtx);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (float* pMtx = mtx)
|
||||
OpenGL.glUniformMatrix4fv(param, 1, false, new IntPtr(pMtx));
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,15 @@ using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
sealed class Texture : ThreadAffine, ITexture
|
||||
{
|
||||
int texture;
|
||||
uint texture;
|
||||
TextureScaleFilter scaleFilter;
|
||||
|
||||
public int ID { get { return texture; } }
|
||||
public uint ID { get { return texture; } }
|
||||
public Size Size { get; private set; }
|
||||
|
||||
bool disposed;
|
||||
@@ -46,13 +45,13 @@ namespace OpenRA.Platforms.Default
|
||||
|
||||
public Texture()
|
||||
{
|
||||
GL.GenTextures(1, out texture);
|
||||
OpenGL.glGenTextures(1, out texture);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public Texture(Bitmap bitmap)
|
||||
{
|
||||
GL.GenTextures(1, out texture);
|
||||
OpenGL.glGenTextures(1, out texture);
|
||||
ErrorHandler.CheckGlError();
|
||||
SetData(bitmap);
|
||||
}
|
||||
@@ -60,23 +59,23 @@ namespace OpenRA.Platforms.Default
|
||||
void PrepareTexture()
|
||||
{
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture);
|
||||
OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, texture);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
var filter = scaleFilter == TextureScaleFilter.Linear ? (int)TextureMinFilter.Linear : (int)TextureMinFilter.Nearest;
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, filter);
|
||||
var filter = scaleFilter == TextureScaleFilter.Linear ? OpenGL.GL_LINEAR : OpenGL.GL_NEAREST;
|
||||
OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, (int)filter);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, filter);
|
||||
OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, (int)filter);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.ClampToEdge);
|
||||
OpenGL.glTexParameterf(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, (float)OpenGL.GL_CLAMP_TO_EDGE);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.ClampToEdge);
|
||||
OpenGL.glTexParameterf(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, (float)OpenGL.GL_CLAMP_TO_EDGE);
|
||||
ErrorHandler.CheckGlError();
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);
|
||||
OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_BASE_LEVEL, 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 0);
|
||||
OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAX_LEVEL, 0);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -93,8 +92,8 @@ namespace OpenRA.Platforms.Default
|
||||
{
|
||||
var intPtr = new IntPtr((void*)ptr);
|
||||
PrepareTexture();
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, width, height,
|
||||
0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, intPtr);
|
||||
OpenGL.glTexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA8, width, height,
|
||||
0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, intPtr);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
}
|
||||
@@ -117,8 +116,8 @@ namespace OpenRA.Platforms.Default
|
||||
{
|
||||
var intPtr = new IntPtr((void*)ptr);
|
||||
PrepareTexture();
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, width, height,
|
||||
0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, intPtr);
|
||||
OpenGL.glTexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA8, width, height,
|
||||
0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, intPtr);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
}
|
||||
@@ -141,8 +140,8 @@ namespace OpenRA.Platforms.Default
|
||||
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
PrepareTexture();
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, bits.Width, bits.Height,
|
||||
0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bits.Scan0); // TODO: weird strides
|
||||
OpenGL.glTexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA8, bits.Width, bits.Height,
|
||||
0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, bits.Scan0); // TODO: weird strides
|
||||
ErrorHandler.CheckGlError();
|
||||
bitmap.UnlockBits(bits);
|
||||
}
|
||||
@@ -159,13 +158,14 @@ namespace OpenRA.Platforms.Default
|
||||
var data = new byte[4 * Size.Width * Size.Height];
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture);
|
||||
OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, texture);
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* ptr = &data[0])
|
||||
{
|
||||
var intPtr = new IntPtr((void*)ptr);
|
||||
GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, intPtr);
|
||||
OpenGL.glGetTexImage(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_BGRA,
|
||||
OpenGL.GL_UNSIGNED_BYTE, intPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +181,8 @@ namespace OpenRA.Platforms.Default
|
||||
|
||||
Size = new Size(width, height);
|
||||
PrepareTexture();
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, width, height,
|
||||
0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
|
||||
OpenGL.glTexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA8, width, height,
|
||||
0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, IntPtr.Zero);
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace OpenRA.Platforms.Default
|
||||
if (disposed)
|
||||
return;
|
||||
disposed = true;
|
||||
GL.DeleteTextures(1, ref texture);
|
||||
OpenGL.glDeleteTextures(1, ref texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
@@ -18,18 +17,28 @@ namespace OpenRA.Platforms.Default
|
||||
where T : struct
|
||||
{
|
||||
static readonly int VertexSize = Marshal.SizeOf(typeof(T));
|
||||
int buffer;
|
||||
uint buffer;
|
||||
bool disposed;
|
||||
|
||||
public VertexBuffer(int size)
|
||||
{
|
||||
GL.GenBuffers(1, out buffer);
|
||||
OpenGL.glGenBuffers(1, out buffer);
|
||||
ErrorHandler.CheckGlError();
|
||||
Bind();
|
||||
GL.BufferData(BufferTarget.ArrayBuffer,
|
||||
new IntPtr(VertexSize * size),
|
||||
new T[size],
|
||||
BufferUsageHint.DynamicDraw);
|
||||
|
||||
var ptr = GCHandle.Alloc(new T[size], GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
OpenGL.glBufferData(OpenGL.GL_ARRAY_BUFFER,
|
||||
new IntPtr(VertexSize * size),
|
||||
ptr.AddrOfPinnedObject(),
|
||||
OpenGL.GL_DYNAMIC_DRAW);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ptr.Free();
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -41,17 +50,27 @@ namespace OpenRA.Platforms.Default
|
||||
public void SetData(T[] data, int start, int length)
|
||||
{
|
||||
Bind();
|
||||
GL.BufferSubData(BufferTarget.ArrayBuffer,
|
||||
new IntPtr(VertexSize * start),
|
||||
new IntPtr(VertexSize * length),
|
||||
data);
|
||||
|
||||
var ptr = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
OpenGL.glBufferSubData(OpenGL.GL_ARRAY_BUFFER,
|
||||
new IntPtr(VertexSize * start),
|
||||
new IntPtr(VertexSize * length),
|
||||
ptr.AddrOfPinnedObject());
|
||||
}
|
||||
finally
|
||||
{
|
||||
ptr.Free();
|
||||
}
|
||||
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public void SetData(IntPtr data, int start, int length)
|
||||
{
|
||||
Bind();
|
||||
GL.BufferSubData(BufferTarget.ArrayBuffer,
|
||||
OpenGL.glBufferSubData(OpenGL.GL_ARRAY_BUFFER,
|
||||
new IntPtr(VertexSize * start),
|
||||
new IntPtr(VertexSize * length),
|
||||
data);
|
||||
@@ -61,11 +80,11 @@ namespace OpenRA.Platforms.Default
|
||||
public void Bind()
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
|
||||
OpenGL.glBindBuffer(OpenGL.GL_ARRAY_BUFFER, buffer);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.VertexAttribPointer(Shader.VertexPosAttributeIndex, 3, VertexAttribPointerType.Float, false, VertexSize, IntPtr.Zero);
|
||||
OpenGL.glVertexAttribPointer(Shader.VertexPosAttributeIndex, 3, OpenGL.GL_FLOAT, false, VertexSize, IntPtr.Zero);
|
||||
ErrorHandler.CheckGlError();
|
||||
GL.VertexAttribPointer(Shader.TexCoordAttributeIndex, 4, VertexAttribPointerType.Float, false, VertexSize, new IntPtr(12));
|
||||
OpenGL.glVertexAttribPointer(Shader.TexCoordAttributeIndex, 4, OpenGL.GL_FLOAT, false, VertexSize, new IntPtr(12));
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
@@ -85,7 +104,7 @@ namespace OpenRA.Platforms.Default
|
||||
if (disposed)
|
||||
return;
|
||||
disposed = true;
|
||||
GL.DeleteBuffers(1, ref buffer);
|
||||
OpenGL.glDeleteBuffers(1, ref buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user