Merge pull request #3578 from pchote/renderer-cleanup

Renderer cleanup
This commit is contained in:
Matthias Mailänder
2013-07-19 09:10:15 -07:00
11 changed files with 177 additions and 201 deletions

View File

@@ -13,8 +13,6 @@ using System.Drawing;
using OpenRA.FileFormats.Graphics;
using OpenRA.Renderer.SdlCommon;
using Tao.Cg;
using Tao.OpenGl;
using Tao.Sdl;
[assembly: Renderer(typeof(OpenRA.Renderer.Cg.DeviceFactory))]
@@ -31,7 +29,7 @@ namespace OpenRA.Renderer.Cg
public class GraphicsDevice : SdlGraphics
{
static string[] RequiredExtensions =
static string[] requiredExtensions =
{
"GL_ARB_vertex_program",
"GL_ARB_fragment_program",
@@ -39,10 +37,10 @@ namespace OpenRA.Renderer.Cg
"GL_EXT_framebuffer_object"
};
internal IntPtr cgContext;
internal int vertexProfile, fragmentProfile;
internal IntPtr Context;
internal int VertexProfile, FragmentProfile;
static Tao.Cg.Cg.CGerrorCallbackFuncDelegate CgErrorCallback = () =>
static Tao.Cg.Cg.CGerrorCallbackFuncDelegate errorCallback = () =>
{
var err = Tao.Cg.Cg.cgGetError();
var msg = "CG Error: {0}: {1}".F(err, Tao.Cg.Cg.cgGetErrorString(err));
@@ -51,16 +49,16 @@ namespace OpenRA.Renderer.Cg
};
public GraphicsDevice(Size size, WindowMode window)
: base(size, window, RequiredExtensions)
: base(size, window, requiredExtensions)
{
cgContext = Tao.Cg.Cg.cgCreateContext();
Context = Tao.Cg.Cg.cgCreateContext();
Tao.Cg.Cg.cgSetErrorCallback(CgErrorCallback);
Tao.Cg.Cg.cgSetErrorCallback(errorCallback);
Tao.Cg.CgGl.cgGLRegisterStates(cgContext);
Tao.Cg.CgGl.cgGLSetManageTextureParameters(cgContext, true);
vertexProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_VERTEX);
fragmentProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_FRAGMENT);
Tao.Cg.CgGl.cgGLRegisterStates(Context);
Tao.Cg.CgGl.cgGLSetManageTextureParameters(Context, true);
VertexProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_VERTEX);
FragmentProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_FRAGMENT);
}
public override IShader CreateShader(string name) { return new Shader(this, name); }

View File

@@ -28,12 +28,12 @@ namespace OpenRA.Renderer.Cg
string code;
using (var file = new StreamReader(FileSystem.Open("cg{0}{1}.fx".F(Path.DirectorySeparatorChar, name))))
code = file.ReadToEnd();
effect = Tao.Cg.Cg.cgCreateEffect(dev.cgContext, code, null);
effect = Tao.Cg.Cg.cgCreateEffect(dev.Context, code, null);
if (effect == IntPtr.Zero)
{
var err = Tao.Cg.Cg.cgGetErrorString(Tao.Cg.Cg.cgGetError());
var results = Tao.Cg.Cg.cgGetLastListing(dev.cgContext);
var results = Tao.Cg.Cg.cgGetLastListing(dev.Context);
throw new InvalidOperationException(
"Cg compile failed ({0}):\n{1}".F(err, results));
}
@@ -51,8 +51,8 @@ namespace OpenRA.Renderer.Cg
public void Render(Action a)
{
Tao.Cg.CgGl.cgGLEnableProfile(dev.vertexProfile);
Tao.Cg.CgGl.cgGLEnableProfile(dev.fragmentProfile);
Tao.Cg.CgGl.cgGLEnableProfile(dev.VertexProfile);
Tao.Cg.CgGl.cgGLEnableProfile(dev.FragmentProfile);
var pass = Tao.Cg.Cg.cgGetFirstPass(technique);
while (pass != IntPtr.Zero)
@@ -63,8 +63,8 @@ namespace OpenRA.Renderer.Cg
pass = Tao.Cg.Cg.cgGetNextPass(pass);
}
Tao.Cg.CgGl.cgGLDisableProfile(dev.fragmentProfile);
Tao.Cg.CgGl.cgGLDisableProfile(dev.vertexProfile);
Tao.Cg.CgGl.cgGLDisableProfile(dev.FragmentProfile);
Tao.Cg.CgGl.cgGLDisableProfile(dev.VertexProfile);
}
public void SetTexture(string name, ITexture t)
@@ -95,7 +95,7 @@ namespace OpenRA.Renderer.Cg
if (param == IntPtr.Zero)
return;
switch(length)
switch (length)
{
case 1: Tao.Cg.CgGl.cgGLSetParameter1fv(param, vec); break;
case 2: Tao.Cg.CgGl.cgGLSetParameter2fv(param, vec); break;

View File

@@ -12,8 +12,6 @@ using System;
using System.Drawing;
using OpenRA.FileFormats.Graphics;
using OpenRA.Renderer.SdlCommon;
using Tao.OpenGl;
using Tao.Sdl;
[assembly: Renderer(typeof(OpenRA.Renderer.Glsl.DeviceFactory))]
@@ -30,7 +28,7 @@ namespace OpenRA.Renderer.Glsl
public class GraphicsDevice : SdlGraphics
{
static string[] RequiredExtensions =
static string[] requiredExtensions =
{
"GL_ARB_vertex_shader",
"GL_ARB_fragment_shader",
@@ -39,8 +37,8 @@ namespace OpenRA.Renderer.Glsl
};
public GraphicsDevice(Size size, WindowMode window)
: base(size, window, RequiredExtensions) {}
: base(size, window, requiredExtensions) { }
public override IShader CreateShader(string name) { return new Shader( this, name ); }
public override IShader CreateShader(string name) { return new Shader(this, name); }
}
}

View File

@@ -21,20 +21,20 @@ namespace OpenRA.Renderer.Glsl
{
public class Shader : IShader
{
int program;
readonly Dictionary<string, int> samplers = new Dictionary<string, int>();
readonly Dictionary<int, ITexture> textures = new Dictionary<int, ITexture>();
int program;
public Shader(GraphicsDevice dev, string type)
public Shader(GraphicsDevice dev, string name)
{
// Vertex shader
string vertexCode;
using (var file = new StreamReader(FileSystem.Open("glsl{0}{1}.vert".F(Path.DirectorySeparatorChar, type))))
using (var file = new StreamReader(FileSystem.Open("glsl{0}{1}.vert".F(Path.DirectorySeparatorChar, name))))
vertexCode = file.ReadToEnd();
int v = Gl.glCreateShaderObjectARB(Gl.GL_VERTEX_SHADER_ARB);
var v = Gl.glCreateShaderObjectARB(Gl.GL_VERTEX_SHADER_ARB);
ErrorHandler.CheckGlError();
Gl.glShaderSourceARB(v,1,new string[]{vertexCode},null);
Gl.glShaderSourceARB(v, 1, new string[] { vertexCode }, null);
ErrorHandler.CheckGlError();
Gl.glCompileShaderARB(v);
ErrorHandler.CheckGlError();
@@ -43,15 +43,16 @@ namespace OpenRA.Renderer.Glsl
Gl.glGetObjectParameterivARB(v, Gl.GL_OBJECT_COMPILE_STATUS_ARB, out success);
ErrorHandler.CheckGlError();
if (success == 0)
throw new InvalidProgramException("Compile error in {0}{1}.vert".F(Path.DirectorySeparatorChar, type));
throw new InvalidProgramException("Compile error in {0}{1}.vert".F(Path.DirectorySeparatorChar, name));
// Fragment shader
string fragmentCode;
using (var file = new StreamReader(FileSystem.Open("glsl{0}{1}.frag".F(Path.DirectorySeparatorChar, type))))
using (var file = new StreamReader(FileSystem.Open("glsl{0}{1}.frag".F(Path.DirectorySeparatorChar, name))))
fragmentCode = file.ReadToEnd();
int f = Gl.glCreateShaderObjectARB(Gl.GL_FRAGMENT_SHADER_ARB);
var f = Gl.glCreateShaderObjectARB(Gl.GL_FRAGMENT_SHADER_ARB);
ErrorHandler.CheckGlError();
Gl.glShaderSourceARB(f,1,new string[]{fragmentCode},null);
Gl.glShaderSourceARB(f, 1, new string[] { fragmentCode }, null);
ErrorHandler.CheckGlError();
Gl.glCompileShaderARB(f);
ErrorHandler.CheckGlError();
@@ -59,15 +60,14 @@ namespace OpenRA.Renderer.Glsl
Gl.glGetObjectParameterivARB(f, Gl.GL_OBJECT_COMPILE_STATUS_ARB, out success);
ErrorHandler.CheckGlError();
if (success == 0)
throw new InvalidProgramException("Compile error in glsl{0}{1}.frag".F(Path.DirectorySeparatorChar, type));
throw new InvalidProgramException("Compile error in glsl{0}{1}.frag".F(Path.DirectorySeparatorChar, name));
// Assemble program
program = Gl.glCreateProgramObjectARB();
ErrorHandler.CheckGlError();
Gl.glAttachObjectARB(program,v);
Gl.glAttachObjectARB(program, v);
ErrorHandler.CheckGlError();
Gl.glAttachObjectARB(program,f);
Gl.glAttachObjectARB(program, f);
ErrorHandler.CheckGlError();
Gl.glLinkProgramARB(program);
@@ -76,32 +76,35 @@ namespace OpenRA.Renderer.Glsl
Gl.glGetObjectParameterivARB(program, Gl.GL_OBJECT_LINK_STATUS_ARB, out success);
ErrorHandler.CheckGlError();
if (success == 0)
throw new InvalidProgramException("Linking error in {0} shader".F(type));
throw new InvalidProgramException("Linking error in {0} shader".F(name));
Gl.glUseProgramObjectARB(program);
ErrorHandler.CheckGlError();
int numUniforms;
Gl.glGetObjectParameterivARB( program, Gl.GL_ACTIVE_UNIFORMS, out numUniforms );
Gl.glGetObjectParameterivARB(program, Gl.GL_ACTIVE_UNIFORMS, out numUniforms);
ErrorHandler.CheckGlError();
int nextTexUnit = 0;
for( int i = 0 ; i < numUniforms ; i++ )
for (var i = 0; i < numUniforms; i++)
{
int uLen, uSize, uType, loc;
int length, size, type;
var sb = new StringBuilder(128);
Gl.glGetActiveUniformARB( program, i, 128, out uLen, out uSize, out uType, sb );
Gl.glGetActiveUniformARB(program, i, 128, out length, out size, out type, sb);
var sampler = sb.ToString();
ErrorHandler.CheckGlError();
if( uType == Gl.GL_SAMPLER_2D_ARB )
if (type == Gl.GL_SAMPLER_2D_ARB)
{
samplers.Add( sampler, nextTexUnit );
loc = Gl.glGetUniformLocationARB(program, sampler);
samplers.Add(sampler, nextTexUnit);
var loc = Gl.glGetUniformLocationARB(program, sampler);
ErrorHandler.CheckGlError();
Gl.glUniform1iARB( loc, nextTexUnit );
Gl.glUniform1iARB(loc, nextTexUnit);
ErrorHandler.CheckGlError();
++nextTexUnit;
nextTexUnit++;
}
}
}
@@ -110,8 +113,7 @@ namespace OpenRA.Renderer.Glsl
{
Gl.glUseProgramObjectARB(program);
/* bind the textures */
// bind the textures
foreach (var kv in textures)
{
Gl.glActiveTextureARB(Gl.GL_TEXTURE0_ARB + kv.Key);
@@ -127,6 +129,7 @@ namespace OpenRA.Renderer.Glsl
{
if (t == null)
return;
int texUnit;
if (samplers.TryGetValue(name, out texUnit))
textures[texUnit] = t;
@@ -136,9 +139,9 @@ namespace OpenRA.Renderer.Glsl
{
Gl.glUseProgramObjectARB(program);
ErrorHandler.CheckGlError();
int param = Gl.glGetUniformLocationARB(program, name);
var param = Gl.glGetUniformLocationARB(program, name);
ErrorHandler.CheckGlError();
Gl.glUniform1fARB(param,x);
Gl.glUniform1fARB(param, x);
ErrorHandler.CheckGlError();
}
@@ -146,17 +149,17 @@ namespace OpenRA.Renderer.Glsl
{
Gl.glUseProgramObjectARB(program);
ErrorHandler.CheckGlError();
int param = Gl.glGetUniformLocationARB(program, name);
var param = Gl.glGetUniformLocationARB(program, name);
ErrorHandler.CheckGlError();
Gl.glUniform2fARB(param,x,y);
Gl.glUniform2fARB(param, x, y);
ErrorHandler.CheckGlError();
}
public void SetVec(string name, float[] vec, int length)
{
int param = Gl.glGetUniformLocationARB(program, name);
var param = Gl.glGetUniformLocationARB(program, name);
ErrorHandler.CheckGlError();
switch(length)
switch (length)
{
case 1: Gl.glUniform1fv(param, 1, vec); break;
case 2: Gl.glUniform2fv(param, 1, vec); break;
@@ -164,6 +167,7 @@ namespace OpenRA.Renderer.Glsl
case 4: Gl.glUniform4fv(param, 1, vec); break;
default: throw new InvalidDataException("Invalid vector length");
}
ErrorHandler.CheckGlError();
}
@@ -174,7 +178,7 @@ namespace OpenRA.Renderer.Glsl
Gl.glUseProgramObjectARB(program);
ErrorHandler.CheckGlError();
int param = Gl.glGetUniformLocationARB(program, name);
var param = Gl.glGetUniformLocationARB(program, name);
ErrorHandler.CheckGlError();
Gl.glUniformMatrix4fv(param, 1, Gl.GL_FALSE, mtx);
ErrorHandler.CheckGlError();

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Renderer.SdlCommon
public static void CheckGlError()
{
var n = Gl.glGetError();
if( n != Gl.GL_NO_ERROR )
if (n != Gl.GL_NO_ERROR)
{
var error = "GL Error: {0}\n{1}".F((GlError)n, new StackTrace());
WriteGraphicsLog(error);
@@ -53,5 +53,4 @@ namespace OpenRA.Renderer.SdlCommon
Log.Write("graphics", Gl.glGetString(Gl.GL_EXTENSIONS));
}
}
}
}

View File

@@ -64,6 +64,22 @@ namespace OpenRA.Renderer.SdlCommon
ErrorHandler.CheckGlError();
}
static int[] ViewportRectangle()
{
var v = new int[4];
unsafe
{
fixed (int* ptr = &v[0])
{
IntPtr intPtr = new IntPtr((void*)ptr);
Gl.glGetIntegerv(Gl.GL_VIEWPORT, intPtr);
}
}
ErrorHandler.CheckGlError();
return v;
}
void FinalizeInner()
{
Gl.glDeleteFramebuffersEXT(1, ref framebuffer);
@@ -74,22 +90,6 @@ namespace OpenRA.Renderer.SdlCommon
~FrameBuffer() { Game.RunAfterTick(FinalizeInner); }
static int[] ViewportRectangle()
{
int[] v = new int[4];
unsafe
{
fixed (int *ptr = &v[0])
{
IntPtr intPtr = new IntPtr((void*)ptr);
Gl.glGetIntegerv(Gl.GL_VIEWPORT, intPtr);
}
}
ErrorHandler.CheckGlError();
return v;
}
int[] cv = new int[4];
public void Bind()
{

View File

@@ -14,33 +14,29 @@ using OpenRA.FileFormats;
public static class MultiTapDetection
{
static Cache<string, TapHistory> KeyHistoryCache =
static Cache<string, TapHistory> keyHistoryCache =
new Cache<string, TapHistory>(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1)));
static Cache<byte, TapHistory> ClickHistoryCache =
static Cache<byte, TapHistory> clickHistoryCache =
new Cache<byte, TapHistory>(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1)));
public static int DetectFromMouse(byte MBName, int2 xy)
public static int DetectFromMouse(byte button, int2 xy)
{
var clickHistory = ClickHistoryCache[MBName];
return clickHistory.GetTapCount(xy);
return clickHistoryCache[button].GetTapCount(xy);
}
public static int InfoFromMouse(byte MBName)
public static int InfoFromMouse(byte button)
{
var clickHistory = ClickHistoryCache[MBName];
return clickHistory.LastTapCount();
return clickHistoryCache[button].LastTapCount();
}
public static int DetectFromKeyboard(string KeyName)
public static int DetectFromKeyboard(string key)
{
var keyHistory = KeyHistoryCache[KeyName];
return keyHistory.GetTapCount(int2.Zero);
return keyHistoryCache[key].GetTapCount(int2.Zero);
}
public static int InfoFromKeyboard(string KeyName)
public static int InfoFromKeyboard(string key)
{
var keyHistory = KeyHistoryCache[KeyName];
return keyHistory.LastTapCount();
return keyHistoryCache[key].LastTapCount();
}
}
@@ -50,12 +46,12 @@ class TapHistory
public TapHistory(DateTime now)
{
FirstRelease = SecondRelease = ThirdRelease = Pair.New( now, int2.Zero );
FirstRelease = SecondRelease = ThirdRelease = Pair.New(now, int2.Zero);
}
static bool CloseEnough(Pair<DateTime, int2> a, Pair<DateTime, int2> b)
{
return a.First - b.First < TimeSpan.FromMilliseconds( 250 )
return a.First - b.First < TimeSpan.FromMilliseconds(250)
&& (a.Second - b.Second).Length < 4;
}
@@ -65,15 +61,21 @@ class TapHistory
SecondRelease = ThirdRelease;
ThirdRelease = Pair.New(DateTime.Now, xy);
if (!CloseEnough(ThirdRelease, SecondRelease)) return 1;
if (!CloseEnough(SecondRelease, FirstRelease)) return 2;
if (!CloseEnough(ThirdRelease, SecondRelease))
return 1;
if (!CloseEnough(SecondRelease, FirstRelease))
return 2;
return 3;
}
public int LastTapCount()
{
if (!CloseEnough(ThirdRelease, SecondRelease)) return 1;
if (!CloseEnough(SecondRelease, FirstRelease)) return 2;
if (!CloseEnough(ThirdRelease, SecondRelease))
return 1;
if (!CloseEnough(SecondRelease, FirstRelease))
return 2;
return 3;
}
}

View File

@@ -21,7 +21,6 @@ namespace OpenRA.Renderer.SdlCommon
public abstract class SdlGraphics : IGraphicsDevice
{
Size windowSize;
IntPtr surf;
SdlInput input;
public Size WindowSize { get { return windowSize; } }
@@ -29,7 +28,7 @@ namespace OpenRA.Renderer.SdlCommon
public SdlGraphics(Size size, WindowMode window, string[] extensions)
{
windowSize = size;
surf = InitializeSdlGl(ref windowSize, window, extensions);
InitializeSdlGl(ref windowSize, window, extensions);
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
ErrorHandler.CheckGlError();
@@ -38,18 +37,17 @@ namespace OpenRA.Renderer.SdlCommon
Sdl.SDL_SetModState(0);
input = new SdlInput(surf);
input = new SdlInput();
}
IntPtr InitializeSdlGl(ref Size size, WindowMode window, string[] requiredExtensions)
{
Sdl.SDL_Init( Sdl.SDL_INIT_NOPARACHUTE | Sdl.SDL_INIT_VIDEO );
Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_DOUBLEBUFFER, 1 );
Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_RED_SIZE, 8 );
Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_GREEN_SIZE, 8 );
Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_BLUE_SIZE, 8 );
Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_ALPHA_SIZE, 0 );
Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_STENCIL_SIZE, 1 );
Sdl.SDL_Init(Sdl.SDL_INIT_NOPARACHUTE | Sdl.SDL_INIT_VIDEO);
Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_DOUBLEBUFFER, 1);
Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_RED_SIZE, 8);
Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_GREEN_SIZE, 8);
Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_BLUE_SIZE, 8);
Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_ALPHA_SIZE, 0);
int windowFlags = 0;
switch (window)
@@ -59,16 +57,16 @@ namespace OpenRA.Renderer.SdlCommon
break;
case WindowMode.PseudoFullscreen:
windowFlags |= Sdl.SDL_NOFRAME;
Environment.SetEnvironmentVariable( "SDL_VIDEO_WINDOW_POS", "0,0" );
Environment.SetEnvironmentVariable("SDL_VIDEO_WINDOW_POS", "0,0");
break;
case WindowMode.Windowed:
Environment.SetEnvironmentVariable( "SDL_VIDEO_CENTERED", "1" );
Environment.SetEnvironmentVariable("SDL_VIDEO_CENTERED", "1");
break;
default:
break;
}
var info = (Sdl.SDL_VideoInfo) Marshal.PtrToStructure(
var info = (Sdl.SDL_VideoInfo)Marshal.PtrToStructure(
Sdl.SDL_GetVideoInfo(), typeof(Sdl.SDL_VideoInfo));
Console.WriteLine("Desktop resolution: {0}x{1}",
info.current_w, info.current_h);
@@ -76,7 +74,7 @@ namespace OpenRA.Renderer.SdlCommon
if (size.Width == 0 && size.Height == 0)
{
Console.WriteLine("No custom resolution provided, using desktop resolution");
size = new Size( info.current_w, info.current_h );
size = new Size(info.current_w, info.current_h);
}
Console.WriteLine("Using resolution: {0}x{1}", size.Width, size.Height);
@@ -110,13 +108,14 @@ namespace OpenRA.Renderer.SdlCommon
int ModeFromPrimitiveType(PrimitiveType pt)
{
switch(pt)
switch (pt)
{
case PrimitiveType.PointList: return Gl.GL_POINTS;
case PrimitiveType.LineList: return Gl.GL_LINES;
case PrimitiveType.TriangleList: return Gl.GL_TRIANGLES;
case PrimitiveType.QuadList: return Gl.GL_QUADS;
}
throw new NotImplementedException();
}
@@ -193,5 +192,4 @@ namespace OpenRA.Renderer.SdlCommon
public IFrameBuffer CreateFrameBuffer(Size s) { return new FrameBuffer(s); }
public abstract IShader CreateShader(string name);
}
}
}

View File

@@ -17,11 +17,8 @@ namespace OpenRA.Renderer.SdlCommon
public class SdlInput
{
MouseButton lastButtonBits = (MouseButton)0;
IntPtr surface;
public SdlInput( IntPtr surface ) { this.surface = surface; }
MouseButton MakeButton( byte b )
MouseButton MakeButton(byte b)
{
return b == Sdl.SDL_BUTTON_LEFT ? MouseButton.Left
: b == Sdl.SDL_BUTTON_RIGHT ? MouseButton.Right
@@ -31,26 +28,26 @@ namespace OpenRA.Renderer.SdlCommon
: 0;
}
Modifiers MakeModifiers( int raw )
Modifiers MakeModifiers(int raw)
{
return ( ( raw & Sdl.KMOD_ALT ) != 0 ? Modifiers.Alt : 0 )
| ( ( raw & Sdl.KMOD_CTRL ) != 0 ? Modifiers.Ctrl : 0 )
| ( ( raw & Sdl.KMOD_META ) != 0 ? Modifiers.Meta : 0 )
| ( ( raw & Sdl.KMOD_SHIFT ) != 0 ? Modifiers.Shift : 0 );
return ((raw & Sdl.KMOD_ALT) != 0 ? Modifiers.Alt : 0)
| ((raw & Sdl.KMOD_CTRL) != 0 ? Modifiers.Ctrl : 0)
| ((raw & Sdl.KMOD_META) != 0 ? Modifiers.Meta : 0)
| ((raw & Sdl.KMOD_SHIFT) != 0 ? Modifiers.Shift : 0);
}
public void PumpInput( IInputHandler inputHandler )
public void PumpInput(IInputHandler inputHandler)
{
Game.HasInputFocus = 0 != ( Sdl.SDL_GetAppState() & Sdl.SDL_APPINPUTFOCUS );
Game.HasInputFocus = 0 != (Sdl.SDL_GetAppState() & Sdl.SDL_APPINPUTFOCUS);
var mods = MakeModifiers( Sdl.SDL_GetModState() );
inputHandler.ModifierKeys( mods );
var mods = MakeModifiers(Sdl.SDL_GetModState());
inputHandler.ModifierKeys(mods);
MouseInput? pendingMotion = null;
Sdl.SDL_Event e;
while( Sdl.SDL_PollEvent( out e ) != 0 )
while (Sdl.SDL_PollEvent(out e) != 0)
{
switch( e.type )
switch (e.type)
{
case Sdl.SDL_QUIT:
OpenRA.Game.Exit();
@@ -58,118 +55,97 @@ namespace OpenRA.Renderer.SdlCommon
case Sdl.SDL_MOUSEBUTTONDOWN:
{
if( pendingMotion != null )
if (pendingMotion != null)
{
inputHandler.OnMouseInput( pendingMotion.Value );
inputHandler.OnMouseInput(pendingMotion.Value);
pendingMotion = null;
}
var button = MakeButton( e.button.button );
var button = MakeButton(e.button.button);
lastButtonBits |= button;
var pos = new int2( e.button.x, e.button.y );
var pos = new int2(e.button.x, e.button.y);
inputHandler.OnMouseInput(new MouseInput(
MouseInputEvent.Down, button, pos, mods,
MultiTapDetection.DetectFromMouse(e.button.button, pos)
));
} break;
MouseInputEvent.Down, button, pos, mods,
MultiTapDetection.DetectFromMouse(e.button.button, pos)));
break;
}
case Sdl.SDL_MOUSEBUTTONUP:
{
if( pendingMotion != null )
if (pendingMotion != null)
{
inputHandler.OnMouseInput( pendingMotion.Value );
inputHandler.OnMouseInput(pendingMotion.Value);
pendingMotion = null;
}
var button = MakeButton( e.button.button );
var button = MakeButton(e.button.button);
lastButtonBits &= ~button;
var pos = new int2( e.button.x, e.button.y );
var pos = new int2(e.button.x, e.button.y);
inputHandler.OnMouseInput(new MouseInput(
MouseInputEvent.Up, button, pos, mods,
MultiTapDetection.InfoFromMouse(e.button.button)
));
} break;
MultiTapDetection.InfoFromMouse(e.button.button)));
break;
}
case Sdl.SDL_MOUSEMOTION:
{
pendingMotion = new MouseInput(
MouseInputEvent.Move,
lastButtonBits,
new int2( e.motion.x, e.motion.y ),
mods, 0 );
} break;
MouseInputEvent.Move, lastButtonBits,
new int2(e.motion.x, e.motion.y), mods, 0);
break;
}
case Sdl.SDL_KEYDOWN:
{
var keyName = Sdl.SDL_GetKeyName( e.key.keysym.sym );
var keyName = Sdl.SDL_GetKeyName(e.key.keysym.sym);
var keyEvent = new KeyInput
{
Event = KeyInputEvent.Down,
Modifiers = mods,
UnicodeChar = (char)e.key.keysym.unicode,
KeyName = Sdl.SDL_GetKeyName( e.key.keysym.sym ),
KeyName = Sdl.SDL_GetKeyName(e.key.keysym.sym),
VirtKey = e.key.keysym.sym,
MultiTapCount = MultiTapDetection.DetectFromKeyboard(keyName)
};
if( !HandleSpecialKey( keyEvent ) )
inputHandler.OnKeyInput( keyEvent );
} break;
inputHandler.OnKeyInput(keyEvent);
break;
}
case Sdl.SDL_KEYUP:
{
var keyName = Sdl.SDL_GetKeyName( e.key.keysym.sym );
var keyName = Sdl.SDL_GetKeyName(e.key.keysym.sym);
var keyEvent = new KeyInput
{
Event = KeyInputEvent.Up,
Modifiers = mods,
UnicodeChar = (char)e.key.keysym.unicode,
KeyName = Sdl.SDL_GetKeyName( e.key.keysym.sym ),
KeyName = Sdl.SDL_GetKeyName(e.key.keysym.sym),
VirtKey = e.key.keysym.sym,
MultiTapCount = MultiTapDetection.InfoFromKeyboard(keyName)
};
inputHandler.OnKeyInput( keyEvent );
} break;
inputHandler.OnKeyInput(keyEvent);
break;
}
}
}
if( pendingMotion != null )
if (pendingMotion != null)
{
inputHandler.OnMouseInput( pendingMotion.Value );
inputHandler.OnMouseInput(pendingMotion.Value);
pendingMotion = null;
}
ErrorHandler.CheckGlError();
}
bool HandleSpecialKey( KeyInput k )
{
switch( k.VirtKey )
{
case Sdl.SDLK_F13:
var path = Environment.GetFolderPath( Environment.SpecialFolder.Personal )
+ Path.DirectorySeparatorChar + DateTime.UtcNow.ToString( "OpenRA-yyyy-MM-ddThhmmssZ" ) + ".bmp";
Sdl.SDL_SaveBMP( surface, path );
return true;
case Sdl.SDLK_F4:
if( k.Modifiers.HasModifier( Modifiers.Alt ) )
{
OpenRA.Game.Exit();
return true;
}
return false;
default:
return false;
}
}
}
}
}

View File

@@ -84,14 +84,14 @@ namespace OpenRA.Renderer.SdlCommon
int height = colors.GetUpperBound(0) + 1;
if (!Exts.IsPowerOf2(width) || !Exts.IsPowerOf2(height))
throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width,height));
throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width, height));
size = new Size(width, height);
unsafe
{
fixed (uint* ptr = &colors[0,0])
fixed (uint* ptr = &colors[0, 0])
{
IntPtr intPtr = new IntPtr((void *) ptr);
IntPtr intPtr = new IntPtr((void*)ptr);
PrepareTexture();
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height,
0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr);
@@ -107,8 +107,7 @@ namespace OpenRA.Renderer.SdlCommon
size = new Size(bitmap.Width, bitmap.Height);
var bits = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
PrepareTexture();
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, bits.Width, bits.Height,
@@ -119,18 +118,20 @@ namespace OpenRA.Renderer.SdlCommon
public byte[] GetData()
{
var data = new byte[4*size.Width * size.Height];
var data = new byte[4 * size.Width * size.Height];
ErrorHandler.CheckGlError();
Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture);
unsafe
{
fixed (byte *ptr = &data[0])
fixed (byte* ptr = &data[0])
{
IntPtr intPtr = new IntPtr((void*)ptr);
Gl.glGetTexImage(Gl.GL_TEXTURE_2D, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr);
}
}
ErrorHandler.CheckGlError();
return data;
}

View File

@@ -18,8 +18,8 @@ namespace OpenRA.Renderer.SdlCommon
public class VertexBuffer<T> : IVertexBuffer<T>
where T : struct
{
static readonly int VertexSize = Marshal.SizeOf(typeof(T));
int buffer;
static readonly int vertexSize = Marshal.SizeOf(typeof(T));
public VertexBuffer(int size)
{
@@ -27,8 +27,8 @@ namespace OpenRA.Renderer.SdlCommon
ErrorHandler.CheckGlError();
Bind();
Gl.glBufferDataARB(Gl.GL_ARRAY_BUFFER_ARB,
new IntPtr(vertexSize * size),
new T[ size ],
new IntPtr(VertexSize * size),
new T[size],
Gl.GL_DYNAMIC_DRAW_ARB);
ErrorHandler.CheckGlError();
}
@@ -38,7 +38,7 @@ namespace OpenRA.Renderer.SdlCommon
Bind();
Gl.glBufferSubDataARB(Gl.GL_ARRAY_BUFFER_ARB,
IntPtr.Zero,
new IntPtr(vertexSize * length),
new IntPtr(VertexSize * length),
data);
ErrorHandler.CheckGlError();
}
@@ -47,13 +47,13 @@ namespace OpenRA.Renderer.SdlCommon
{
Gl.glBindBufferARB(Gl.GL_ARRAY_BUFFER_ARB, buffer);
ErrorHandler.CheckGlError();
Gl.glVertexPointer(3, Gl.GL_FLOAT, vertexSize, IntPtr.Zero);
Gl.glVertexPointer(3, Gl.GL_FLOAT, VertexSize, IntPtr.Zero);
ErrorHandler.CheckGlError();
Gl.glTexCoordPointer(4, Gl.GL_FLOAT, vertexSize, new IntPtr(12));
Gl.glTexCoordPointer(4, Gl.GL_FLOAT, VertexSize, new IntPtr(12));
ErrorHandler.CheckGlError();
}
void FinalizeInner() { Gl.glDeleteBuffersARB( 1, ref buffer ); }
~VertexBuffer() { Game.RunAfterTick( FinalizeInner ); }
void FinalizeInner() { Gl.glDeleteBuffersARB(1, ref buffer); }
~VertexBuffer() { Game.RunAfterTick(FinalizeInner); }
}
}