 611bec6e44
			
		
	
	
		611bec6e44
		
			
		
	
	
	
	
		
			
			* Implement DrawTexture functionality * Non-NVIDIA support * Disable some features that should not affect draw texture (slow path) * Remove space from shader source * Match 2D engine names * Fix resolution scale and add missing XML docs * Disable transform feedback for draw texture fallback
		
			
				
	
	
		
			138 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using OpenTK.Graphics.OpenGL;
 | |
| using Ryujinx.Graphics.OpenGL.Image;
 | |
| using System;
 | |
| 
 | |
| namespace Ryujinx.Graphics.OpenGL
 | |
| {
 | |
|     class DrawTextureEmulation
 | |
|     {
 | |
|         private const string VertexShader = @"#version 430 core
 | |
| 
 | |
| uniform float srcX0;
 | |
| uniform float srcY0;
 | |
| uniform float srcX1;
 | |
| uniform float srcY1;
 | |
| 
 | |
| layout (location = 0) out vec2 texcoord;
 | |
| 
 | |
| void main()
 | |
| {
 | |
|     bool x1 = (gl_VertexID & 1) != 0;
 | |
|     bool y1 = (gl_VertexID & 2) != 0;
 | |
|     gl_Position = vec4(x1 ? 1 : -1, y1 ? -1 : 1, 0, 1);
 | |
|     texcoord = vec2(x1 ? srcX1 : srcX0, y1 ? srcY1 : srcY0);
 | |
| }";
 | |
| 
 | |
|         private const string FragmentShader = @"#version 430 core
 | |
| 
 | |
| layout (location = 0) uniform sampler2D tex;
 | |
| 
 | |
| layout (location = 0) in vec2 texcoord;
 | |
| layout (location = 0) out vec4 colour;
 | |
| 
 | |
| void main()
 | |
| {
 | |
|     colour = texture(tex, texcoord);
 | |
| }";
 | |
| 
 | |
|         private int _vsHandle;
 | |
|         private int _fsHandle;
 | |
|         private int _programHandle;
 | |
|         private int _uniformSrcX0Location;
 | |
|         private int _uniformSrcY0Location;
 | |
|         private int _uniformSrcX1Location;
 | |
|         private int _uniformSrcY1Location;
 | |
|         private bool _initialized;
 | |
| 
 | |
|         public void Draw(
 | |
|             TextureView texture,
 | |
|             Sampler sampler,
 | |
|             float x0,
 | |
|             float y0,
 | |
|             float x1,
 | |
|             float y1,
 | |
|             float s0,
 | |
|             float t0,
 | |
|             float s1,
 | |
|             float t1)
 | |
|         {
 | |
|             EnsureInitialized();
 | |
| 
 | |
|             GL.UseProgram(_programHandle);
 | |
| 
 | |
|             texture.Bind(0);
 | |
|             sampler.Bind(0);
 | |
| 
 | |
|             if (x0 > x1)
 | |
|             {
 | |
|                 float temp = s0;
 | |
|                 s0 = s1;
 | |
|                 s1 = temp;
 | |
|             }
 | |
| 
 | |
|             if (y0 > y1)
 | |
|             {
 | |
|                 float temp = t0;
 | |
|                 t0 = t1;
 | |
|                 t1 = temp;
 | |
|             }
 | |
| 
 | |
|             GL.Uniform1(_uniformSrcX0Location, s0);
 | |
|             GL.Uniform1(_uniformSrcY0Location, t0);
 | |
|             GL.Uniform1(_uniformSrcX1Location, s1);
 | |
|             GL.Uniform1(_uniformSrcY1Location, t1);
 | |
| 
 | |
|             GL.ViewportIndexed(0, MathF.Min(x0, x1), MathF.Min(y0, y1), MathF.Abs(x1 - x0), MathF.Abs(y1 - y0));
 | |
| 
 | |
|             GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
 | |
|         }
 | |
| 
 | |
|         private void EnsureInitialized()
 | |
|         {
 | |
|             if (_initialized)
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             _initialized = true;
 | |
| 
 | |
|             _vsHandle = GL.CreateShader(ShaderType.VertexShader);
 | |
|             _fsHandle = GL.CreateShader(ShaderType.FragmentShader);
 | |
| 
 | |
|             GL.ShaderSource(_vsHandle, VertexShader);
 | |
|             GL.ShaderSource(_fsHandle, FragmentShader);
 | |
| 
 | |
|             GL.CompileShader(_vsHandle);
 | |
|             GL.CompileShader(_fsHandle);
 | |
| 
 | |
|             _programHandle = GL.CreateProgram();
 | |
| 
 | |
|             GL.AttachShader(_programHandle, _vsHandle);
 | |
|             GL.AttachShader(_programHandle, _fsHandle);
 | |
| 
 | |
|             GL.LinkProgram(_programHandle);
 | |
| 
 | |
|             GL.DetachShader(_programHandle, _vsHandle);
 | |
|             GL.DetachShader(_programHandle, _fsHandle);
 | |
| 
 | |
|             _uniformSrcX0Location = GL.GetUniformLocation(_programHandle, "srcX0");
 | |
|             _uniformSrcY0Location = GL.GetUniformLocation(_programHandle, "srcY0");
 | |
|             _uniformSrcX1Location = GL.GetUniformLocation(_programHandle, "srcX1");
 | |
|             _uniformSrcY1Location = GL.GetUniformLocation(_programHandle, "srcY1");
 | |
|         }
 | |
| 
 | |
|         public void Dispose()
 | |
|         {
 | |
|             if (!_initialized)
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             GL.DeleteShader(_vsHandle);
 | |
|             GL.DeleteShader(_fsHandle);
 | |
|             GL.DeleteProgram(_programHandle);
 | |
| 
 | |
|             _initialized = false;
 | |
|         }
 | |
|     }
 | |
| }
 |