Add texture format to the Texture class so that render target textures do not have to be in the bgra8 format

This commit is contained in:
Magnus Norddahl 2020-01-15 23:28:17 +01:00
parent 50668921e8
commit 6e4a02fb2b
8 changed files with 129 additions and 33 deletions

View file

@ -3243,7 +3243,7 @@ namespace CodeImp.DoomBuilder.Data
// Make custom rendertarget
const int cubemaptexsize = 1024;
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize);
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize, TextureFormat.Rgba8);
// Start rendering
General.Map.Graphics.StartRendering(true, new Color4(), rendertarget, true);

View file

@ -59,7 +59,7 @@ namespace CodeImp.DoomBuilder.Rendering
public Plotter(int width, int height)
{
// Initialize
Texture = new Texture(width, height);
Texture = new Texture(width, height, TextureFormat.Bgra8);
this.pixels = new PixelColor[width*height];
this.width = width;
this.height = height;

View file

@ -356,9 +356,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Create rendertargets textures
plotter = new Plotter(windowsize.Width, windowsize.Height);
gridplotter = new Plotter(windowsize.Width, windowsize.Height);
thingstex = new Texture(windowsize.Width, windowsize.Height);
overlaytex = new Texture(windowsize.Width, windowsize.Height);
surfacetex = new Texture(windowsize.Width, windowsize.Height);
thingstex = new Texture(windowsize.Width, windowsize.Height, TextureFormat.Rgba8);
overlaytex = new Texture(windowsize.Width, windowsize.Height, TextureFormat.Rgba8);
surfacetex = new Texture(windowsize.Width, windowsize.Height, TextureFormat.Rgba8);
// Clear rendertargets
graphics.ClearTexture(General.Colors.Background.WithAlpha(0).ToColorValue(), thingstex);

View file

@ -7,6 +7,20 @@ using System.Runtime.InteropServices;
namespace CodeImp.DoomBuilder.Rendering
{
public enum TextureFormat : int
{
Rgba8,
Bgra8,
Rg16f,
Rgba16f,
R32f,
Rg32f,
Rgb32f,
Rgba32f,
D32f_S8,
D24_S8
}
public class BaseTexture : IDisposable
{
public BaseTexture()
@ -41,26 +55,28 @@ namespace CodeImp.DoomBuilder.Rendering
protected static extern void Texture_Delete(IntPtr handle);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height);
protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height, TextureFormat format);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_SetCubeImage(IntPtr handle, int size);
protected static extern void Texture_SetCubeImage(IntPtr handle, int size, TextureFormat format);
}
public class Texture : BaseTexture
{
public Texture(int width, int height)
public Texture(int width, int height, TextureFormat format)
{
Width = width;
Height = height;
Texture_Set2DImage(Handle, Width, Height);
Format = format;
Texture_Set2DImage(Handle, Width, Height, Format);
}
public Texture(RenderDevice device, System.Drawing.Bitmap bitmap)
{
Width = bitmap.Width;
Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height);
Format = TextureFormat.Bgra8;
Texture_Set2DImage(Handle, Width, Height, Format);
device.SetPixels(this, bitmap);
}
@ -70,13 +86,15 @@ namespace CodeImp.DoomBuilder.Rendering
{
Width = bitmap.Width;
Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height);
Format = TextureFormat.Bgra8;
Texture_Set2DImage(Handle, Width, Height, Format);
device.SetPixels(this, bitmap);
}
}
public int Width { get; private set; }
public int Height { get; private set; }
public TextureFormat Format { get; private set; }
public object Tag { get; set; }
}
@ -85,7 +103,7 @@ namespace CodeImp.DoomBuilder.Rendering
{
public CubeTexture(RenderDevice device, int size)
{
Texture_SetCubeImage(Handle, size);
Texture_SetCubeImage(Handle, size, TextureFormat.Bgra8);
}
}

View file

@ -287,13 +287,13 @@ extern "C"
return Backend::Get()->DeleteTexture(tex);
}
void Texture_Set2DImage(Texture* tex, int width, int height)
void Texture_Set2DImage(Texture* tex, int width, int height, PixelFormat format)
{
tex->Set2DImage(width, height);
tex->Set2DImage(width, height, format);
}
void Texture_SetCubeImage(Texture* tex, int size)
void Texture_SetCubeImage(Texture* tex, int size, PixelFormat format)
{
tex->SetCubeImage(size);
tex->SetCubeImage(size, format);
}
}

View file

@ -39,6 +39,22 @@ enum class TextureFilter : int { Nearest, Linear };
enum class MipmapFilter : int { None, Nearest, Linear };
enum class UniformType : int { Vec4f, Vec3f, Vec2f, Float, Mat4, Vec4i, Vec3i, Vec2i, Int, Vec4fArray, Vec3fArray, Vec2fArray };
enum class PixelFormat : int
{
Rgba8,
Bgra8,
Rg16f,
Rgba16f,
R32f,
Rg32f,
Rgb32f,
Rgba32f,
D32f_S8,
D24_S8,
A2Bgr10,
A2Rgb10_snorm
};
typedef int UniformName;
typedef int ShaderName;
@ -106,8 +122,8 @@ class Texture
{
public:
virtual ~Texture() = default;
virtual void Set2DImage(int width, int height) = 0;
virtual void SetCubeImage(int size) = 0;
virtual void Set2DImage(int width, int height, PixelFormat format) = 0;
virtual void SetCubeImage(int size, PixelFormat format) = 0;
};
class Backend

View file

@ -39,20 +39,23 @@ void GLTexture::Finalize()
Invalidate();
}
void GLTexture::Set2DImage(int width, int height)
void GLTexture::Set2DImage(int width, int height, PixelFormat format)
{
if (width < 1) width = 1;
if (height < 1) height = 1;
// This really shouldn't be here. The calling code should send valid input and this should throw an error.
if (width < 1) width = 16;
if (height < 1) height = 16;
mCubeTexture = false;
mWidth = width;
mHeight = height;
mFormat = format;
}
void GLTexture::SetCubeImage(int size)
void GLTexture::SetCubeImage(int size, PixelFormat format)
{
mCubeTexture = true;
mWidth = size;
mHeight = size;
mFormat = format;
}
bool GLTexture::SetPixels(GLRenderDevice* device, const void* data)
@ -70,7 +73,7 @@ bool GLTexture::SetPixels(GLRenderDevice* device, const void* data)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
glTexImage2D(GL_TEXTURE_2D, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), data);
if (data != nullptr)
glGenerateMipmap(GL_TEXTURE_2D);
@ -103,7 +106,7 @@ bool GLTexture::SetCubePixels(GLRenderDevice* device, CubeMapFace face, const vo
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
glTexImage2D(cubeMapFaceToGL[(int)face], 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
glTexImage2D(cubeMapFaceToGL[(int)face], 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), data);
if (data != nullptr && face == CubeMapFace::NegativeZ)
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
@ -152,7 +155,7 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glBindTexture(GL_TEXTURE_2D, oldBinding);
}
@ -163,12 +166,12 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glBindTexture(GL_TEXTURE_CUBE_MAP, oldBinding);
}
@ -241,3 +244,57 @@ GLuint GLTexture::GetPBO(GLRenderDevice* device)
return mPBO;
}
GLint GLTexture::ToInternalFormat(PixelFormat format)
{
static GLint cvt[] =
{
GL_RGBA8,
GL_RGBA8,
GL_RG16F,
GL_RGBA16F,
GL_R32F,
GL_RG32F,
GL_RGB32F,
GL_RGBA32F,
GL_DEPTH32F_STENCIL8,
GL_DEPTH24_STENCIL8
};
return cvt[(int)format];
}
GLenum GLTexture::ToDataFormat(PixelFormat format)
{
static GLint cvt[] =
{
GL_RGBA,
GL_BGRA,
GL_RG,
GL_RGBA,
GL_RED,
GL_RG,
GL_RGB,
GL_RGBA,
GL_DEPTH_STENCIL,
GL_DEPTH_STENCIL
};
return cvt[(int)format];
}
GLenum GLTexture::ToDataType(PixelFormat format)
{
static GLint cvt[] =
{
GL_UNSIGNED_BYTE,
GL_UNSIGNED_BYTE,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
GL_UNSIGNED_INT_24_8
};
return cvt[(int)format];
}

View file

@ -34,8 +34,8 @@ public:
void Finalize();
void Set2DImage(int width, int height) override;
void SetCubeImage(int size) override;
void Set2DImage(int width, int height, PixelFormat format) override;
void SetCubeImage(int size, PixelFormat format) override;
bool SetPixels(GLRenderDevice* device, const void* data);
bool SetCubePixels(GLRenderDevice* device, CubeMapFace face, const void* data);
@ -55,8 +55,13 @@ public:
std::list<GLTexture*>::iterator ItTexture;
private:
static GLint ToInternalFormat(PixelFormat format);
static GLenum ToDataFormat(PixelFormat format);
static GLenum ToDataType(PixelFormat format);
int mWidth = 0;
int mHeight = 0;
PixelFormat mFormat = {};
bool mCubeTexture = false;
bool mPBOTexture = false;
GLuint mTexture = 0;