A game framework written with osu! in mind.

Initial implementation of texture wrapping

+65 -26
-1
osu.Framework/Graphics/Lines/Path_DrawNode.cs
··· 215 215 216 216 pathShader.Bind(); 217 217 218 - texture.TextureGL.WrapMode = TextureWrapMode.ClampToEdge; 219 218 texture.TextureGL.Bind(); 220 219 221 220 updateVertexBuffer();
+17 -2
osu.Framework/Graphics/OpenGL/GLWrapper.cs
··· 362 362 /// <returns>true if the provided texture was not already bound (causing a binding change).</returns> 363 363 public static bool BindTexture(TextureGL texture, TextureUnit unit = TextureUnit.Texture0) 364 364 { 365 - bool didBind = BindTexture(texture?.TextureId ?? 0, unit); 365 + bool didBind = BindTexture(texture?.TextureId ?? 0, texture.WrapModeS, texture.WrapModeT, unit); 366 366 last_bound_texture_is_atlas[GetTextureUnitId(unit)] = texture is TextureGLAtlas; 367 367 368 368 return didBind; 369 369 } 370 + 371 + private static WrapMode currentWrapModeS; 372 + private static WrapMode currentWrapModeT; 370 373 371 374 /// <summary> 372 375 /// Binds a texture to draw with. ··· 374 377 /// <param name="textureId">The texture to bind.</param> 375 378 /// <param name="unit">The texture unit to bind it to.</param> 376 379 /// <returns>true if the provided texture was not already bound (causing a binding change).</returns> 377 - public static bool BindTexture(int textureId, TextureUnit unit = TextureUnit.Texture0) 380 + public static bool BindTexture(int textureId, WrapMode wrapModeS = WrapMode.None, WrapMode wrapModeT = WrapMode.None, TextureUnit unit = TextureUnit.Texture0) 378 381 { 379 382 var index = GetTextureUnitId(unit); 383 + 384 + if (wrapModeS != currentWrapModeS) 385 + { 386 + GlobalPropertyManager.Set(GlobalProperty.WrapModeS, (int)wrapModeS); 387 + currentWrapModeS = wrapModeS; 388 + } 389 + 390 + if (wrapModeT != currentWrapModeT) 391 + { 392 + GlobalPropertyManager.Set(GlobalProperty.WrapModeT, (int)wrapModeT); 393 + currentWrapModeT = wrapModeT; 394 + } 380 395 381 396 if (last_bound_texture[index] == textureId) 382 397 return false;
+11 -1
osu.Framework/Graphics/OpenGL/Textures/TextureGL.cs
··· 15 15 public abstract class TextureGL : IDisposable 16 16 { 17 17 public bool IsTransparent; 18 - public TextureWrapMode WrapMode = TextureWrapMode.ClampToEdge; 18 + 19 + public WrapMode WrapModeS; 20 + 21 + public WrapMode WrapModeT; 19 22 20 23 #region Disposal 21 24 ··· 111 114 internal abstract void FlushUploads(); 112 115 113 116 public abstract void SetData(ITextureUpload upload); 117 + } 118 + 119 + public enum WrapMode 120 + { 121 + None = 0, 122 + Clamp = 1, 123 + Repeat = 2 114 124 } 115 125 }
+2 -15
osu.Framework/Graphics/OpenGL/Textures/TextureGLSingle.cs
··· 32 32 private int internalHeight; 33 33 34 34 private readonly All filteringMode; 35 - private TextureWrapMode internalWrapMode; 36 35 37 36 /// <summary> 38 37 /// The total amount of times this <see cref="TextureGLAtlas"/> was bound. ··· 278 277 FrameStatistics.Add(StatisticsCounterType.Pixels, (long)vertexQuad.Area); 279 278 } 280 279 281 - private void updateWrapMode() 282 - { 283 - if (!Available) 284 - throw new ObjectDisposedException(ToString(), "Can not update wrap mode of a disposed texture."); 285 - 286 - internalWrapMode = WrapMode; 287 - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)internalWrapMode); 288 - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)internalWrapMode); 289 - } 290 - 291 280 public override void SetData(ITextureUpload upload) 292 281 { 293 282 if (!Available) ··· 327 316 328 317 if (GLWrapper.BindTexture(this, unit)) 329 318 BindCount++; 330 - 331 - if (internalWrapMode != WrapMode) 332 - updateWrapMode(); 333 319 334 320 return true; 335 321 } ··· 412 398 // It controls the amount of mipmap levels generated by GL.GenerateMipmap later on. 413 399 GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)33085, MAX_MIPMAP_LEVELS); 414 400 415 - updateWrapMode(); 401 + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp); 402 + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp); 416 403 } 417 404 else 418 405 GLWrapper.BindTexture(this);
+2
osu.Framework/Graphics/Shaders/GlobalProperty.cs
··· 21 21 DiscardInner, 22 22 InnerCornerRadius, 23 23 GammaCorrection, 24 + WrapModeS, 25 + WrapModeT, 24 26 BackbufferDraw, 25 27 } 26 28 }
+2
osu.Framework/Graphics/Shaders/GlobalPropertyManager.cs
··· 32 32 global_properties[(int)GlobalProperty.DiscardInner] = new UniformMapping<bool>("g_DiscardInner"); 33 33 global_properties[(int)GlobalProperty.InnerCornerRadius] = new UniformMapping<float>("g_InnerCornerRadius"); 34 34 global_properties[(int)GlobalProperty.GammaCorrection] = new UniformMapping<bool>("g_GammaCorrection"); 35 + global_properties[(int)GlobalProperty.WrapModeS] = new UniformMapping<int>("g_WrapModeS"); 36 + global_properties[(int)GlobalProperty.WrapModeT] = new UniformMapping<int>("g_WrapModeT"); 35 37 36 38 // Backbuffer internals 37 39 global_properties[(int)GlobalProperty.BackbufferDraw] = new UniformMapping<bool>("g_BackbufferDraw");
-1
osu.Framework/Graphics/Shapes/Box.cs
··· 76 76 base.DrawOpaqueInterior(vertexAction); 77 77 78 78 TextureShader.Bind(); 79 - Texture.TextureGL.WrapMode = WrapTexture ? TextureWrapMode.Repeat : TextureWrapMode.ClampToEdge; 80 79 81 80 if (GLWrapper.IsMaskingActive) 82 81 DrawClipped(ref conservativeScreenSpaceDrawQuad, Texture, DrawColourInfo.Colour, vertexAction: vertexAction);
-2
osu.Framework/Graphics/Sprites/SpriteDrawNode.cs
··· 54 54 if (Texture?.Available != true) 55 55 return; 56 56 57 - Texture.TextureGL.WrapMode = WrapTexture ? TextureWrapMode.Repeat : TextureWrapMode.ClampToEdge; 58 - 59 57 Shader.Bind(); 60 58 61 59 Blit(vertexAction);
-1
osu.Framework/Graphics/UserInterface/CircularProgressDrawNode.cs
··· 151 151 152 152 Shader.Bind(); 153 153 154 - texture.TextureGL.WrapMode = TextureWrapMode.ClampToEdge; 155 154 texture.TextureGL.Bind(); 156 155 157 156 updateVertexBuffer();
+1 -1
osu.Framework/Graphics/Video/VideoTexture.cs
··· 40 40 throw new ObjectDisposedException(ToString(), "Can not bind a disposed texture."); 41 41 42 42 for (int i = 0; i < textureIds.Length; i++) 43 - GLWrapper.BindTexture(textureIds[i], unit + i); 43 + GLWrapper.BindTexture(textureIds[i], 0, 0, unit + i); 44 44 45 45 return true; 46 46 }
+3 -1
osu.Framework/Resources/Shaders/sh_Texture.fs
··· 1 1 #include "sh_Utils.h" 2 + #include "sh_TextureWrapping.h" 2 3 3 4 varying lowp vec4 v_Colour; 4 5 varying mediump vec2 v_TexCoord; 6 + varying mediump vec4 v_TexRect; 5 7 6 8 uniform lowp sampler2D m_Sampler; 7 9 8 10 void main(void) 9 11 { 10 - gl_FragColor = toSRGB(v_Colour * texture2D(m_Sampler, v_TexCoord, -0.9)); 12 + gl_FragColor = toSRGB(v_Colour * texture2D(m_Sampler, wrap(v_TexCoord, v_TexRect), -0.9)); 11 13 }
+2 -1
osu.Framework/Resources/Shaders/sh_TextureRounded.fs
··· 1 1 #include "sh_Utils.h" 2 2 #include "sh_Masking.h" 3 + #include "sh_TextureWrapping.h" 3 4 4 5 uniform lowp sampler2D m_Sampler; 5 6 6 7 void main(void) 7 8 { 8 - gl_FragColor = getRoundedColor(toSRGB(texture2D(m_Sampler, v_TexCoord, -0.9))); 9 + gl_FragColor = getRoundedColor(toSRGB(texture2D(m_Sampler, wrap(v_TexCoord, v_TexRect), -0.9))); 9 10 }
+25
osu.Framework/Resources/Shaders/sh_TextureWrapping.h
··· 1 + // 0 -> None 2 + // 1 -> Clamp 3 + // 2 -> Repeat 4 + 5 + uniform int g_WrapModeS; 6 + uniform int g_WrapModeT; 7 + 8 + float wrap(float coord, int mode, float rangeMin, float rangeMax) 9 + { 10 + if (mode == 1) 11 + { 12 + return clamp(coord, rangeMin, rangeMax); 13 + } 14 + else if (mode == 2) 15 + { 16 + return mod(coord - rangeMin, rangeMax - rangeMin) + rangeMin; 17 + } 18 + 19 + return coord; 20 + } 21 + 22 + vec2 wrap(vec2 texCoord, vec4 texRect) 23 + { 24 + return vec2(wrap(texCoord.x, g_WrapModeS, texRect[0], texRect[2]), wrap(texCoord.y, g_WrapModeT, texRect[1], texRect[3])); 25 + }