Replace MiniTK.Graphics with custom OpenGL shim.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user