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 // Make custom rendertarget
const int cubemaptexsize = 1024; const int cubemaptexsize = 1024;
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize); Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize, TextureFormat.Rgba8);
// Start rendering // Start rendering
General.Map.Graphics.StartRendering(true, new Color4(), rendertarget, true); 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) public Plotter(int width, int height)
{ {
// Initialize // Initialize
Texture = new Texture(width, height); Texture = new Texture(width, height, TextureFormat.Bgra8);
this.pixels = new PixelColor[width*height]; this.pixels = new PixelColor[width*height];
this.width = width; this.width = width;
this.height = height; this.height = height;

View file

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

View file

@ -7,6 +7,20 @@ using System.Runtime.InteropServices;
namespace CodeImp.DoomBuilder.Rendering 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 class BaseTexture : IDisposable
{ {
public BaseTexture() public BaseTexture()
@ -41,26 +55,28 @@ namespace CodeImp.DoomBuilder.Rendering
protected static extern void Texture_Delete(IntPtr handle); protected static extern void Texture_Delete(IntPtr handle);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [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)] [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 class Texture : BaseTexture
{ {
public Texture(int width, int height) public Texture(int width, int height, TextureFormat format)
{ {
Width = width; Width = width;
Height = height; Height = height;
Texture_Set2DImage(Handle, Width, Height); Format = format;
Texture_Set2DImage(Handle, Width, Height, Format);
} }
public Texture(RenderDevice device, System.Drawing.Bitmap bitmap) public Texture(RenderDevice device, System.Drawing.Bitmap bitmap)
{ {
Width = bitmap.Width; Width = bitmap.Width;
Height = bitmap.Height; Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height); Format = TextureFormat.Bgra8;
Texture_Set2DImage(Handle, Width, Height, Format);
device.SetPixels(this, bitmap); device.SetPixels(this, bitmap);
} }
@ -70,13 +86,15 @@ namespace CodeImp.DoomBuilder.Rendering
{ {
Width = bitmap.Width; Width = bitmap.Width;
Height = bitmap.Height; Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height); Format = TextureFormat.Bgra8;
Texture_Set2DImage(Handle, Width, Height, Format);
device.SetPixels(this, bitmap); device.SetPixels(this, bitmap);
} }
} }
public int Width { get; private set; } public int Width { get; private set; }
public int Height { get; private set; } public int Height { get; private set; }
public TextureFormat Format { get; private set; }
public object Tag { get; set; } public object Tag { get; set; }
} }
@ -85,7 +103,7 @@ namespace CodeImp.DoomBuilder.Rendering
{ {
public CubeTexture(RenderDevice device, int size) 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); 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 MipmapFilter : int { None, Nearest, Linear };
enum class UniformType : int { Vec4f, Vec3f, Vec2f, Float, Mat4, Vec4i, Vec3i, Vec2i, Int, Vec4fArray, Vec3fArray, Vec2fArray }; 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 UniformName;
typedef int ShaderName; typedef int ShaderName;
@ -106,8 +122,8 @@ class Texture
{ {
public: public:
virtual ~Texture() = default; virtual ~Texture() = default;
virtual void Set2DImage(int width, int height) = 0; virtual void Set2DImage(int width, int height, PixelFormat format) = 0;
virtual void SetCubeImage(int size) = 0; virtual void SetCubeImage(int size, PixelFormat format) = 0;
}; };
class Backend class Backend

View file

@ -39,20 +39,23 @@ void GLTexture::Finalize()
Invalidate(); Invalidate();
} }
void GLTexture::Set2DImage(int width, int height) void GLTexture::Set2DImage(int width, int height, PixelFormat format)
{ {
if (width < 1) width = 1; // This really shouldn't be here. The calling code should send valid input and this should throw an error.
if (height < 1) height = 1; if (width < 1) width = 16;
if (height < 1) height = 16;
mCubeTexture = false; mCubeTexture = false;
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
mFormat = format;
} }
void GLTexture::SetCubeImage(int size) void GLTexture::SetCubeImage(int size, PixelFormat format)
{ {
mCubeTexture = true; mCubeTexture = true;
mWidth = size; mWidth = size;
mHeight = size; mHeight = size;
mFormat = format;
} }
bool GLTexture::SetPixels(GLRenderDevice* device, const void* data) 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); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, mTexture); 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) if (data != nullptr)
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
@ -103,7 +106,7 @@ bool GLTexture::SetCubePixels(GLRenderDevice* device, CubeMapFace face, const vo
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); 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) if (data != nullptr && face == CubeMapFace::NegativeZ)
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
@ -152,7 +155,7 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, mTexture); 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); glBindTexture(GL_TEXTURE_2D, oldBinding);
} }
@ -163,12 +166,12 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); 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_X, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), 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_Y, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), 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_POSITIVE_Z, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), 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_X, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), 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_Y, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), 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_NEGATIVE_Z, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glBindTexture(GL_TEXTURE_CUBE_MAP, oldBinding); glBindTexture(GL_TEXTURE_CUBE_MAP, oldBinding);
} }
@ -241,3 +244,57 @@ GLuint GLTexture::GetPBO(GLRenderDevice* device)
return mPBO; 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 Finalize();
void Set2DImage(int width, int height) override; void Set2DImage(int width, int height, PixelFormat format) override;
void SetCubeImage(int size) override; void SetCubeImage(int size, PixelFormat format) override;
bool SetPixels(GLRenderDevice* device, const void* data); bool SetPixels(GLRenderDevice* device, const void* data);
bool SetCubePixels(GLRenderDevice* device, CubeMapFace face, const void* data); bool SetCubePixels(GLRenderDevice* device, CubeMapFace face, const void* data);
@ -55,8 +55,13 @@ public:
std::list<GLTexture*>::iterator ItTexture; std::list<GLTexture*>::iterator ItTexture;
private: private:
static GLint ToInternalFormat(PixelFormat format);
static GLenum ToDataFormat(PixelFormat format);
static GLenum ToDataType(PixelFormat format);
int mWidth = 0; int mWidth = 0;
int mHeight = 0; int mHeight = 0;
PixelFormat mFormat = {};
bool mCubeTexture = false; bool mCubeTexture = false;
bool mPBOTexture = false; bool mPBOTexture = false;
GLuint mTexture = 0; GLuint mTexture = 0;