2018-04-08 21:17:35 +02:00
|
|
|
using OpenTK.Graphics.OpenGL;
|
|
|
|
|
|
|
|
namespace Ryujinx.Graphics.Gal.OpenGL
|
|
|
|
{
|
|
|
|
class OGLTexture
|
|
|
|
{
|
|
|
|
private int[] Textures;
|
|
|
|
|
|
|
|
public OGLTexture()
|
|
|
|
{
|
|
|
|
Textures = new int[80];
|
|
|
|
}
|
|
|
|
|
2018-04-10 21:50:32 +02:00
|
|
|
public void Set(int Index, GalTexture Texture)
|
2018-04-08 21:17:35 +02:00
|
|
|
{
|
|
|
|
GL.ActiveTexture(TextureUnit.Texture0 + Index);
|
|
|
|
|
2018-04-13 20:12:58 +02:00
|
|
|
Bind(Index);
|
2018-04-08 21:17:35 +02:00
|
|
|
|
2018-04-13 20:12:58 +02:00
|
|
|
const int Level = 0; //TODO: Support mipmap textures.
|
2018-04-10 21:50:32 +02:00
|
|
|
const int Border = 0;
|
2018-04-08 21:17:35 +02:00
|
|
|
|
2018-04-10 21:50:32 +02:00
|
|
|
if (IsCompressedTextureFormat(Texture.Format))
|
2018-04-08 21:17:35 +02:00
|
|
|
{
|
2018-04-10 21:50:32 +02:00
|
|
|
PixelInternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);
|
|
|
|
|
|
|
|
GL.CompressedTexImage2D(
|
|
|
|
TextureTarget.Texture2D,
|
2018-04-13 20:12:58 +02:00
|
|
|
Level,
|
2018-04-10 21:50:32 +02:00
|
|
|
InternalFmt,
|
|
|
|
Texture.Width,
|
|
|
|
Texture.Height,
|
|
|
|
Border,
|
|
|
|
Texture.Data.Length,
|
|
|
|
Texture.Data);
|
2018-04-08 21:17:35 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-10 21:50:32 +02:00
|
|
|
const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
|
|
|
|
|
2018-04-13 20:12:58 +02:00
|
|
|
(PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);
|
2018-04-10 21:50:32 +02:00
|
|
|
|
|
|
|
GL.TexImage2D(
|
|
|
|
TextureTarget.Texture2D,
|
2018-04-13 20:12:58 +02:00
|
|
|
Level,
|
2018-04-10 21:50:32 +02:00
|
|
|
InternalFmt,
|
|
|
|
Texture.Width,
|
|
|
|
Texture.Height,
|
|
|
|
Border,
|
2018-04-13 20:12:58 +02:00
|
|
|
Format,
|
|
|
|
Type,
|
2018-04-10 21:50:32 +02:00
|
|
|
Texture.Data);
|
2018-04-08 21:17:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-13 20:12:58 +02:00
|
|
|
public void Bind(int Index)
|
2018-04-08 21:17:35 +02:00
|
|
|
{
|
|
|
|
int Handle = EnsureTextureInitialized(Index);
|
|
|
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
2018-04-13 20:12:58 +02:00
|
|
|
}
|
2018-04-08 21:17:35 +02:00
|
|
|
|
2018-04-13 20:12:58 +02:00
|
|
|
public static void Set(GalTextureSampler Sampler)
|
|
|
|
{
|
2018-04-08 21:17:35 +02:00
|
|
|
int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
|
|
|
|
int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
|
|
|
|
|
|
|
|
int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter);
|
|
|
|
int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter);
|
|
|
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, WrapS);
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, WrapT);
|
|
|
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
|
|
|
|
|
|
|
|
float[] Color = new float[]
|
|
|
|
{
|
|
|
|
Sampler.BorderColor.Red,
|
|
|
|
Sampler.BorderColor.Green,
|
|
|
|
Sampler.BorderColor.Blue,
|
|
|
|
Sampler.BorderColor.Alpha
|
|
|
|
};
|
|
|
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static bool IsCompressedTextureFormat(GalTextureFormat Format)
|
|
|
|
{
|
2018-04-10 23:54:50 +02:00
|
|
|
switch (Format)
|
|
|
|
{
|
|
|
|
case GalTextureFormat.BC1:
|
|
|
|
case GalTextureFormat.BC2:
|
|
|
|
case GalTextureFormat.BC3:
|
|
|
|
case GalTextureFormat.BC4:
|
|
|
|
case GalTextureFormat.BC5:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2018-04-08 21:17:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private int EnsureTextureInitialized(int TexIndex)
|
|
|
|
{
|
|
|
|
int Handle = Textures[TexIndex];
|
|
|
|
|
|
|
|
if (Handle == 0)
|
|
|
|
{
|
|
|
|
Handle = Textures[TexIndex] = GL.GenTexture();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Handle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|