Hardware sRGB texture support. OpenGL sRGB framebuffer writing implementation still missing.
This commit is contained in:
Родитель
25372fafd8
Коммит
b4599e046d
|
@ -663,6 +663,19 @@ Make sure the normal map is oriented correctly: an even surface should have the
|
|||
|
||||
Specular maps encode the specular surface color as RGB. Note that deferred rendering is only able to use monochromatic specular intensity from the G channel, while forward and light pre-pass rendering use fully colored specular. DXT1 format should suit these textures well.
|
||||
|
||||
Textures can have an accompanying XML file which specifies load-time parameters, such as addressing, mipmapping, and number of mip levels to skip on each quality level:
|
||||
|
||||
\code
|
||||
<texture>
|
||||
<address coord="u|v|w" mode="wrap|mirror|clamp|border" />
|
||||
<border color="r g b a" />
|
||||
<filter mode="nearest|bilinear|trilinear|anisotropic|default" />
|
||||
<mipmap enable="false|true" />
|
||||
<quality low="x" medium="y" high="z" />
|
||||
<srgb enable="false|true" />
|
||||
</texture>
|
||||
\endcode
|
||||
|
||||
\section Materials_Techniques Techniques and passes
|
||||
|
||||
A technique definition looks like this:
|
||||
|
@ -811,7 +824,7 @@ The render path XML definition looks like this:
|
|||
\code
|
||||
<renderpath>
|
||||
<rendertarget name="RTName" tag="TagName" active="true|false" size="x y"|sizedivisor="x y"|rtsizedivisor="x y"
|
||||
format="rgb|rgba|r32f|rgba16|rgba16f|rgba32f|rg16|rg16f|rg32f|lineardepth" filter="true|false" />
|
||||
format="rgb|rgba|r32f|rgba16|rgba16f|rgba32f|rg16|rg16f|rg32f|lineardepth" filter="true|false" srgb="true|false" />
|
||||
<command type="clear" tag="TagName" active="true|false" clearcolor="r g b a|fog" cleardepth="x" clearstencil="y" output="viewport|RTName" />
|
||||
<command type="scenepass" pass="PassName" sort="fronttoback|backtofront" marktostencil="true|false" usescissor="true|false" vertexlights="true|false">
|
||||
<output index="0" name="RTName1" />
|
||||
|
|
|
@ -720,6 +720,8 @@ template <class T> void RegisterTexture(asIScriptEngine* engine, const char* cla
|
|||
engine->RegisterObjectMethod(className, "TextureAddressMode get_addressMode(TextureCoordinate) const", asMETHOD(T, GetAddressMode), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "void set_borderColor(const Color&in)", asMETHOD(T, SetBorderColor), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "const Color& get_borderColor() const", asMETHOD(T, GetBorderColor), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "void set_sRGB(bool)", asMETHOD(T, SetSRGB), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "bool get_sRGB() const", asMETHOD(T, GetSRGB), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "void set_backupTexture(Texture@+)", asMETHOD(T, SetBackupTexture), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "Texture@+ get_backupTexture() const", asMETHOD(T, GetBackupTexture), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod(className, "bool get_dataLost() const", asMETHODPR(T, IsDataLost, () const, bool), asCALL_THISCALL);
|
||||
|
|
|
@ -174,7 +174,6 @@ static bool TextureCubeLoad(CubeMapFace face, Image* image, bool useAlpha, Textu
|
|||
|
||||
static void ConstructRenderTargetInfo(RenderTargetInfo* ptr)
|
||||
{
|
||||
// Init to zero because performance is not critical
|
||||
new(ptr) RenderTargetInfo();
|
||||
}
|
||||
|
||||
|
@ -190,7 +189,6 @@ static void DestructRenderTargetInfo(RenderTargetInfo* ptr)
|
|||
|
||||
static void ConstructRenderPathCommand(RenderPathCommand* ptr)
|
||||
{
|
||||
// Init to zero because performance is not critical
|
||||
new(ptr) RenderPathCommand();
|
||||
}
|
||||
|
||||
|
@ -293,6 +291,7 @@ static void RegisterRenderPath(asIScriptEngine* engine)
|
|||
engine->RegisterObjectProperty("RenderTargetInfo", "RenderTargetSizeMode sizeMode", offsetof(RenderTargetInfo, sizeMode_));
|
||||
engine->RegisterObjectProperty("RenderTargetInfo", "bool active", offsetof(RenderTargetInfo, active_));
|
||||
engine->RegisterObjectProperty("RenderTargetInfo", "bool filtered", offsetof(RenderTargetInfo, filtered_));
|
||||
engine->RegisterObjectProperty("RenderTargetInfo", "bool sRGB", offsetof(RenderTargetInfo, sRGB_));
|
||||
|
||||
engine->RegisterObjectType("RenderPathCommand", sizeof(RenderPathCommand), asOBJ_VALUE | asOBJ_APP_CLASS_C);
|
||||
engine->RegisterObjectBehaviour("RenderPathCommand", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructRenderPathCommand), asCALL_CDECL_OBJLAST);
|
||||
|
@ -996,6 +995,8 @@ static void RegisterGraphics(asIScriptEngine* engine)
|
|||
engine->RegisterObjectMethod("Graphics", "bool TakeScreenShot(Image@+)", asMETHOD(Graphics, TakeScreenShot), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "void set_windowTitle(const String&in)", asMETHOD(Graphics, SetWindowTitle), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "const String& get_windowTitle() const", asMETHOD(Graphics, GetWindowTitle), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "void set_sRGB(bool)", asMETHOD(Graphics, SetSRGB), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "bool get_sRGB() const", asMETHOD(Graphics, GetSRGB), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "int get_width() const", asMETHOD(Graphics, GetWidth), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "int get_height() const", asMETHOD(Graphics, GetHeight), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "int get_multiSample() const", asMETHOD(Graphics, GetMultiSample), asCALL_THISCALL);
|
||||
|
@ -1011,6 +1012,7 @@ static void RegisterGraphics(asIScriptEngine* engine)
|
|||
engine->RegisterObjectMethod("Graphics", "bool get_lightPrepassSupport() const", asMETHOD(Graphics, GetLightPrepassSupport), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "bool get_deferredSupport() const", asMETHOD(Graphics, GetDeferredSupport), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "bool get_hardwareShadowSupport() const", asMETHOD(Graphics, GetHardwareShadowSupport), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "bool get_sRGBSupport() const", asMETHOD(Graphics, GetSRGBSupport), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "void set_forceSM2(bool)", asMETHOD(Graphics, SetForceSM2), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "bool get_forceSM2() const", asMETHOD(Graphics, GetForceSM2), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Graphics", "Array<IntVector2>@ get_resolutions() const", asFUNCTION(GraphicsGetResolutions), asCALL_CDECL_OBJLAST);
|
||||
|
|
|
@ -182,11 +182,13 @@ Graphics::Graphics(Context* context) :
|
|||
resizable_(false),
|
||||
vsync_(false),
|
||||
tripleBuffer_(false),
|
||||
sRGB_(false),
|
||||
deviceLost_(false),
|
||||
lightPrepassSupport_(false),
|
||||
deferredSupport_(false),
|
||||
hardwareShadowSupport_(false),
|
||||
streamOffsetSupport_(false),
|
||||
sRGBSupport_(true),
|
||||
hasSM3_(false),
|
||||
forceSM2_(false),
|
||||
numPrimitives_(0),
|
||||
|
@ -370,7 +372,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool resizable, b
|
|||
impl_->presentParams_.hDeviceWindow = WIN_GetWindowHandle(impl_->window_);
|
||||
impl_->presentParams_.EnableAutoDepthStencil = TRUE;
|
||||
impl_->presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
impl_->presentParams_.Flags = 0;
|
||||
impl_->presentParams_.Flags = D3DPRESENT_LINEAR_CONTENT;
|
||||
impl_->presentParams_.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
||||
|
||||
if (vsync)
|
||||
|
@ -443,6 +445,11 @@ bool Graphics::SetMode(int width, int height)
|
|||
return SetMode(width, height, fullscreen_, resizable_, vsync_, tripleBuffer_, multiSample_);
|
||||
}
|
||||
|
||||
void Graphics::SetSRGB(bool enabled)
|
||||
{
|
||||
sRGB_ = enabled;
|
||||
}
|
||||
|
||||
bool Graphics::ToggleFullscreen()
|
||||
{
|
||||
return SetMode(width_, height_, !fullscreen_, resizable_, vsync_, tripleBuffer_, multiSample_);
|
||||
|
@ -1274,6 +1281,12 @@ void Graphics::SetTexture(unsigned index, Texture* texture)
|
|||
impl_->borderColors_[index] = borderColor;
|
||||
}
|
||||
}
|
||||
bool sRGB = texture->GetSRGB();
|
||||
if (sRGB != impl_->sRGBModes_[index])
|
||||
{
|
||||
impl_->device_->SetSamplerState(index, D3DSAMP_SRGBTEXTURE, sRGB ? TRUE : FALSE);
|
||||
impl_->sRGBModes_[index] = sRGB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,6 +1357,17 @@ void Graphics::SetRenderTarget(unsigned index, RenderSurface* renderTarget)
|
|||
SetTexture(i, textures_[i]->GetBackupTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// First rendertarget controls sRGB write mode
|
||||
if (!index)
|
||||
{
|
||||
bool sRGBWrite = renderTarget ? renderTarget->GetParentTexture()->GetSRGB() : sRGB_;
|
||||
if (sRGBWrite != impl_->sRGBWrite_)
|
||||
{
|
||||
impl_->device_->SetRenderState(D3DRS_SRGBWRITEENABLE, sRGBWrite ? TRUE : FALSE);
|
||||
impl_->sRGBWrite_ = sRGBWrite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::SetRenderTarget(unsigned index, Texture2D* texture)
|
||||
|
@ -2286,6 +2310,7 @@ void Graphics::ResetCachedState()
|
|||
impl_->vAddressModes_[i] = D3DTADDRESS_WRAP;
|
||||
impl_->wAddressModes_[i] = D3DTADDRESS_WRAP;
|
||||
impl_->borderColors_[i] = Color(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
impl_->sRGBModes_[i] = false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
|
||||
|
@ -2298,6 +2323,7 @@ void Graphics::ResetCachedState()
|
|||
impl_->depthStencilSurface_ = 0;
|
||||
viewTexture_ = 0;
|
||||
viewport_ = IntRect(0, 0, width_, height_);
|
||||
impl_->sRGBWrite_ = false;
|
||||
|
||||
for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
|
||||
streamFrequencies_[i] = 1;
|
||||
|
|
|
@ -87,6 +87,8 @@ public:
|
|||
bool SetMode(int width, int height, bool fullscreen, bool resizable, bool vsync, bool tripleBuffer, int multiSample);
|
||||
/// Set screen resolution only. Return true if successful.
|
||||
bool SetMode(int width, int height);
|
||||
/// Set whether the main window uses sRGB writing.
|
||||
void SetSRGB(bool enable);
|
||||
/// Toggle between full screen and windowed mode. Return true if successful.
|
||||
bool ToggleFullscreen();
|
||||
/// Close the window.
|
||||
|
@ -220,6 +222,8 @@ public:
|
|||
bool GetVSync() const { return vsync_; }
|
||||
/// Return whether triple buffering is enabled.
|
||||
bool GetTripleBuffer() const { return tripleBuffer_; }
|
||||
/// Return whether the main window is using SRGB writing.
|
||||
bool IsSRGB() const { return sRGB_; }
|
||||
/// Return whether Direct3D device is lost, and can not yet render. This happens during fullscreen resolution switching.
|
||||
bool IsDeviceLost() const { return deviceLost_; }
|
||||
/// Return number of primitives drawn this frame.
|
||||
|
@ -242,6 +246,8 @@ public:
|
|||
bool GetHardwareShadowSupport() const { return hardwareShadowSupport_; }
|
||||
/// Return whether stream offset is supported.
|
||||
bool GetStreamOffsetSupport() const { return streamOffsetSupport_; }
|
||||
/// Return whether sRGB textures are supported.
|
||||
bool GetSRGBSupport() const { return sRGBSupport_; }
|
||||
/// Return supported fullscreen resolutions.
|
||||
PODVector<IntVector2> GetResolutions() const;
|
||||
/// Return supported multisampling levels.
|
||||
|
@ -407,6 +413,8 @@ private:
|
|||
bool vsync_;
|
||||
/// Triple buffering flag.
|
||||
bool tripleBuffer_;
|
||||
/// sRGB writing flag for the main window.
|
||||
bool sRGB_;
|
||||
/// Direct3D device lost flag.
|
||||
bool deviceLost_;
|
||||
/// Light pre-pass rendering support flag.
|
||||
|
@ -417,6 +425,8 @@ private:
|
|||
bool hardwareShadowSupport_;
|
||||
/// Stream offset support flag.
|
||||
bool streamOffsetSupport_;
|
||||
/// sRGB texture support flag.
|
||||
bool sRGBSupport_;
|
||||
/// Shader Model 3 flag.
|
||||
bool hasSM3_;
|
||||
/// Force Shader Model 2 flag.
|
||||
|
|
|
@ -83,6 +83,10 @@ private:
|
|||
D3DTEXTUREADDRESS wAddressModes_[MAX_TEXTURE_UNITS];
|
||||
/// Texture border colors in use.
|
||||
Color borderColors_[MAX_TEXTURE_UNITS];
|
||||
/// sRGB mode in use.
|
||||
bool sRGBModes_[MAX_TEXTURE_UNITS];
|
||||
/// sRGB write flag.
|
||||
bool sRGBWrite_;
|
||||
/// Color surfaces in use.
|
||||
IDirect3DSurface9* colorSurfaces_[MAX_RENDERTARGETS];
|
||||
/// Depth-stencil surface in use.
|
||||
|
|
|
@ -65,7 +65,8 @@ Texture::Texture(Context* context) :
|
|||
requestedLevels_(0),
|
||||
width_(0),
|
||||
height_(0),
|
||||
filterMode_(FILTER_DEFAULT)
|
||||
filterMode_(FILTER_DEFAULT),
|
||||
sRGB_(false)
|
||||
{
|
||||
for (int i = 0; i < MAX_COORDS; ++i)
|
||||
addressMode_[i] = ADDRESS_WRAP;
|
||||
|
@ -100,6 +101,11 @@ void Texture::SetBorderColor(const Color& color)
|
|||
borderColor_ = color;
|
||||
}
|
||||
|
||||
void Texture::SetSRGB(bool enable)
|
||||
{
|
||||
sRGB_ = enable;
|
||||
}
|
||||
|
||||
void Texture::SetBackupTexture(Texture* texture)
|
||||
{
|
||||
backupTexture_ = texture;
|
||||
|
@ -261,6 +267,9 @@ void Texture::LoadParameters(const XMLElement& element)
|
|||
mipsToSkip_[i] = mipsToSkip_[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "srgb")
|
||||
SetSRGB(paramElem.GetBool("enable"));
|
||||
|
||||
paramElem = paramElem.GetNext();
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
void SetAddressMode(TextureCoordinate coord, TextureAddressMode address);
|
||||
/// Set border color for border addressing mode.
|
||||
void SetBorderColor(const Color& color);
|
||||
/// Set sRGB sampling and writing mode.
|
||||
void SetSRGB(bool enable);
|
||||
/// Set backup texture to use when rendering to this texture.
|
||||
void SetBackupTexture(Texture* texture);
|
||||
|
||||
|
@ -72,6 +74,8 @@ public:
|
|||
TextureAddressMode GetAddressMode(TextureCoordinate coord) const { return addressMode_[coord]; }
|
||||
/// Return border color.
|
||||
const Color& GetBorderColor() const { return borderColor_; }
|
||||
/// Return whether is using sRGB sampling and writing.
|
||||
bool GetSRGB() const { return sRGB_; }
|
||||
/// Return backup texture.
|
||||
Texture* GetBackupTexture() const { return backupTexture_; }
|
||||
/// Return mip level width, or 0 if level does not exist.
|
||||
|
@ -118,6 +122,8 @@ protected:
|
|||
unsigned mipsToSkip_[MAX_TEXTURE_QUALITY_LEVELS];
|
||||
/// Border color.
|
||||
Color borderColor_;
|
||||
/// sRGB sampling and writing mode flag.
|
||||
bool sRGB_;
|
||||
/// Backup texture.
|
||||
SharedPtr<Texture> backupTexture_;
|
||||
};
|
||||
|
|
|
@ -167,6 +167,7 @@ Graphics::Graphics(Context* context_) :
|
|||
dxtTextureSupport_(false),
|
||||
etcTextureSupport_(false),
|
||||
pvrtcTextureSupport_(false),
|
||||
sRGBSupport_(false),
|
||||
numPrimitives_(0),
|
||||
numBatches_(0),
|
||||
maxScratchBufferRequest_(0),
|
||||
|
@ -379,6 +380,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool resizable, b
|
|||
|
||||
dxtTextureSupport_ = GLEW_EXT_texture_compression_s3tc != 0;
|
||||
anisotropySupport_ = GLEW_EXT_texture_filter_anisotropic != 0;
|
||||
sRGBSupport_ = GLEW_EXT_texture_sRGB != 0;
|
||||
#else
|
||||
dxtTextureSupport_ = CheckExtension(extensions, "EXT_texture_compression_dxt1");
|
||||
etcTextureSupport_ = CheckExtension(extensions, "OES_compressed_ETC1_RGB8_texture");
|
||||
|
@ -439,6 +441,11 @@ bool Graphics::SetMode(int width, int height)
|
|||
return SetMode(width, height, fullscreen_, resizable_, vsync_, tripleBuffer_, multiSample_);
|
||||
}
|
||||
|
||||
void Graphics::SetSRGB(bool enabled)
|
||||
{
|
||||
sRGB_ = enabled && sRGBSupport_;
|
||||
}
|
||||
|
||||
bool Graphics::ToggleFullscreen()
|
||||
{
|
||||
return SetMode(width_, height_, !fullscreen_, resizable_, vsync_, tripleBuffer_, multiSample_);
|
||||
|
|
|
@ -92,6 +92,8 @@ public:
|
|||
bool SetMode(int width, int height, bool fullscreen, bool resizable, bool vsync, bool tripleBuffer, int multiSample);
|
||||
/// Set screen resolution only. Return true if successful.
|
||||
bool SetMode(int width, int height);
|
||||
/// Set whether the main window uses sRGB writing.
|
||||
void SetSRGB(bool enable);
|
||||
/// Toggle between full screen and windowed mode.
|
||||
bool ToggleFullscreen();
|
||||
/// Close the window.
|
||||
|
@ -229,6 +231,8 @@ public:
|
|||
bool GetVSync() const { return vsync_; }
|
||||
/// Return whether triple buffering is enabled.
|
||||
bool GetTripleBuffer() const { return tripleBuffer_; }
|
||||
/// Return whether the main window is using SRGB writing.
|
||||
bool GetSRGB() const { return sRGB_; }
|
||||
/// Return whether device is lost, and can not yet render.
|
||||
bool IsDeviceLost() const;
|
||||
/// Return number of primitives drawn this frame.
|
||||
|
@ -253,6 +257,8 @@ public:
|
|||
bool GetHardwareShadowSupport() const { return true; }
|
||||
/// Return whether stream offset is supported. Always false on OpenGL.
|
||||
bool GetStreamOffsetSupport() const { return false; }
|
||||
/// Return whether sRGB textures are supported.
|
||||
bool GetSRGBSupport() const { return sRGBSupport_; }
|
||||
/// Return supported fullscreen resolutions.
|
||||
PODVector<IntVector2> GetResolutions() const;
|
||||
/// Return supported multisampling levels.
|
||||
|
@ -416,6 +422,8 @@ private:
|
|||
bool vsync_;
|
||||
/// Triple buffering flag.
|
||||
bool tripleBuffer_;
|
||||
/// sRGB writing flag for the main window.
|
||||
bool sRGB_;
|
||||
/// Light prepass support flag.
|
||||
bool lightPrepassSupport_;
|
||||
/// Deferred rendering support flag.
|
||||
|
@ -428,6 +436,8 @@ private:
|
|||
bool etcTextureSupport_;
|
||||
/// PVRTC formats support flag.
|
||||
bool pvrtcTextureSupport_;
|
||||
/// sRGB texture support flag.
|
||||
bool sRGBSupport_;
|
||||
/// Number of primitives this frame.
|
||||
unsigned numPrimitives_;
|
||||
/// Number of batches this frame.
|
||||
|
|
|
@ -30,13 +30,13 @@
|
|||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#elif defined(IOS)
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#else
|
||||
#include <glew.h>
|
||||
#endif
|
||||
|
||||
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#else
|
||||
#include <glew.h>
|
||||
#endif
|
||||
|
||||
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83f1
|
||||
#endif
|
||||
#ifndef GL_ETC1_RGB8_OES
|
||||
|
|
|
@ -78,7 +78,8 @@ Texture::Texture(Context* context) :
|
|||
height_(0),
|
||||
shadowCompare_(false),
|
||||
parametersDirty_(true),
|
||||
filterMode_(FILTER_DEFAULT)
|
||||
filterMode_(FILTER_DEFAULT),
|
||||
sRGB_(false)
|
||||
{
|
||||
for (int i = 0; i < MAX_COORDS; ++i)
|
||||
addressMode_[i] = ADDRESS_WRAP;
|
||||
|
@ -119,6 +120,11 @@ void Texture::SetBorderColor(const Color& color)
|
|||
parametersDirty_ = true;
|
||||
}
|
||||
|
||||
void Texture::SetSRGB(bool enable)
|
||||
{
|
||||
sRGB_ = enable;
|
||||
}
|
||||
|
||||
void Texture::SetBackupTexture(Texture* texture)
|
||||
{
|
||||
backupTexture_ = texture;
|
||||
|
@ -298,17 +304,20 @@ unsigned Texture::GetRowDataSize(int width) const
|
|||
unsigned Texture::GetExternalFormat(unsigned format)
|
||||
{
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
// For DEPTH_COMPONENTxx textures DEPTH_COMPONENT needs to be returned
|
||||
if (format == GL_DEPTH_COMPONENT16 || format == GL_DEPTH_COMPONENT24 || format == GL_DEPTH_COMPONENT32)
|
||||
return GL_DEPTH_COMPONENT;
|
||||
else if (format == GL_DEPTH24_STENCIL8_EXT)
|
||||
return GL_DEPTH_STENCIL_EXT;
|
||||
else if (format == GL_LUMINANCE16F_ARB || format == GL_LUMINANCE32F_ARB)
|
||||
else if (format == GL_LUMINANCE16F_ARB || format == GL_LUMINANCE32F_ARB || format == GL_SLUMINANCE_EXT)
|
||||
return GL_LUMINANCE;
|
||||
else if (format == GL_SLUMINANCE_ALPHA_EXT)
|
||||
return GL_LUMINANCE_ALPHA;
|
||||
else if (format == GL_RG16 || format == GL_RG16F || format == GL_RG32F)
|
||||
return GL_RG;
|
||||
else if (format == GL_RGBA16 || format == GL_RGBA16F_ARB || format == GL_RGBA32F_ARB)
|
||||
else if (format == GL_RGBA16 || format == GL_RGBA16F_ARB || format == GL_RGBA32F_ARB || format == GL_SRGB_ALPHA_EXT)
|
||||
return GL_RGBA;
|
||||
else if (format == GL_SRGB_EXT)
|
||||
return GL_RGB;
|
||||
else
|
||||
return format;
|
||||
#else
|
||||
|
@ -408,10 +417,43 @@ void Texture::LoadParameters(const XMLElement& elem)
|
|||
}
|
||||
}
|
||||
|
||||
if (name == "srgb")
|
||||
SetSRGB(paramElem.GetBool("enable"));
|
||||
|
||||
paramElem = paramElem.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned Texture::GetSRGBFormat(unsigned format)
|
||||
{
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
if (!graphics_ || !graphics_->GetSRGBSupport())
|
||||
return format;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case GL_RGB:
|
||||
return GL_SRGB_EXT;
|
||||
case GL_RGBA:
|
||||
return GL_SRGB_ALPHA_EXT;
|
||||
case GL_LUMINANCE:
|
||||
return GL_SLUMINANCE_EXT;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
return GL_SLUMINANCE_ALPHA_EXT;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||
default:
|
||||
return format;
|
||||
}
|
||||
#else
|
||||
return format;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Texture::CheckTextureBudget(ShortStringHash type)
|
||||
{
|
||||
ResourceCache* cache = GetSubsystem<ResourceCache>();
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
void SetShadowCompare(bool enable);
|
||||
/// Set border color for border addressing mode.
|
||||
void SetBorderColor(const Color& color);
|
||||
/// Set sRGB sampling and writing mode.
|
||||
void SetSRGB(bool enable);
|
||||
/// Set backup texture to use when rendering to this texture.
|
||||
void SetBackupTexture(Texture* texture);
|
||||
/// Dirty the parameters.
|
||||
|
@ -84,6 +86,8 @@ public:
|
|||
bool GetShadowCompare() const { return shadowCompare_; }
|
||||
/// Return border color.
|
||||
const Color& GetBorderColor() const { return borderColor_; }
|
||||
/// Return whether is using sRGB sampling and writing.
|
||||
bool GetSRGB() const { return sRGB_; }
|
||||
/// Return backup texture.
|
||||
Texture* GetBackupTexture() const { return backupTexture_; }
|
||||
/// Return mip level width, or 0 if level does not exist.
|
||||
|
@ -107,6 +111,8 @@ public:
|
|||
void LoadParameters(XMLFile* xml);
|
||||
/// Load parameters from an XML element.
|
||||
void LoadParameters(const XMLElement& elem);
|
||||
/// Return the corresponding SRGB texture format if supported. If not supported, return format unchanged.
|
||||
unsigned GetSRGBFormat(unsigned format);
|
||||
|
||||
protected:
|
||||
/// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
|
||||
|
@ -138,6 +144,8 @@ protected:
|
|||
unsigned mipsToSkip_[MAX_TEXTURE_QUALITY_LEVELS];
|
||||
/// Border color.
|
||||
Color borderColor_;
|
||||
/// sRGB sampling and writing mode flag.
|
||||
bool sRGB_;
|
||||
/// Backup texture.
|
||||
SharedPtr<Texture> backupTexture_;
|
||||
};
|
||||
|
|
|
@ -219,19 +219,21 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
|
|||
|
||||
graphics_->SetTextureForUpdate(this);
|
||||
|
||||
unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;
|
||||
|
||||
if (!IsCompressed())
|
||||
{
|
||||
if (wholeLevel)
|
||||
glTexImage2D(target_, level, format_, width, height, 0, GetExternalFormat(format_), GetDataType(format_), data);
|
||||
glTexImage2D(target_, level, format, width, height, 0, GetExternalFormat(format_), GetDataType(format_), data);
|
||||
else
|
||||
glTexSubImage2D(target_, level, x, y, width, height, GetExternalFormat(format_), GetDataType(format_), data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wholeLevel)
|
||||
glCompressedTexImage2D(target_, level, format_, width, height, 0, GetDataSize(width, height), data);
|
||||
glCompressedTexImage2D(target_, level, format, width, height, 0, GetDataSize(width, height), data);
|
||||
else
|
||||
glCompressedTexSubImage2D(target_, level, x, y, width, height, format_, GetDataSize(width, height), data);
|
||||
glCompressedTexSubImage2D(target_, level, x, y, width, height, format, GetDataSize(width, height), data);
|
||||
}
|
||||
|
||||
graphics_->SetTexture(0, 0);
|
||||
|
@ -410,20 +412,21 @@ bool Texture2D::Create()
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;
|
||||
unsigned externalFormat = GetExternalFormat(format_);
|
||||
unsigned dataType = GetDataType(format_);
|
||||
|
||||
// Create a renderbuffer instead of a texture if depth texture is not properly supported, or if this will be a packed
|
||||
// depth stencil texture
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
if (format_ == Graphics::GetDepthStencilFormat())
|
||||
if (format == Graphics::GetDepthStencilFormat())
|
||||
#else
|
||||
if (!graphics_->GetShadowMapFormat() && externalFormat == GL_DEPTH_COMPONENT)
|
||||
#endif
|
||||
{
|
||||
if (renderSurface_)
|
||||
{
|
||||
renderSurface_->CreateRenderBuffer(width_, height_, format_);
|
||||
renderSurface_->CreateRenderBuffer(width_, height_, format);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -437,10 +440,11 @@ bool Texture2D::Create()
|
|||
|
||||
// If not compressed, create the initial level 0 texture with null data
|
||||
bool success = true;
|
||||
|
||||
if (!IsCompressed())
|
||||
{
|
||||
glGetError();
|
||||
glTexImage2D(target_, 0, format_, width_, height_, 0, externalFormat, dataType, 0);
|
||||
glTexImage2D(target_, 0, format, width_, height_, 0, externalFormat, dataType, 0);
|
||||
if (glGetError())
|
||||
{
|
||||
LOGERROR("Failed to create texture");
|
||||
|
|
|
@ -216,10 +216,12 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
|
|||
|
||||
graphics_->SetTextureForUpdate(this);
|
||||
|
||||
unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;
|
||||
|
||||
if (!IsCompressed())
|
||||
{
|
||||
if (wholeLevel)
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, format_, width, height, 0, GetExternalFormat(format_),
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, format, width, height, 0, GetExternalFormat(format_),
|
||||
GetDataType(format_), data);
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, x, y, width, height, GetExternalFormat(format_),
|
||||
|
@ -228,10 +230,10 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
|
|||
else
|
||||
{
|
||||
if (wholeLevel)
|
||||
glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, format_, width, height, 0,
|
||||
glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, format, width, height, 0,
|
||||
GetDataSize(width, height), data);
|
||||
else
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, x, y, width, height, format_,
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, x, y, width, height, format,
|
||||
GetDataSize(width, height), data);
|
||||
}
|
||||
|
||||
|
@ -528,6 +530,7 @@ bool TextureCube::Create()
|
|||
graphics_->SetTextureForUpdate(this);
|
||||
|
||||
// If not compressed, create the initial level 0 texture with null data
|
||||
unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;
|
||||
unsigned externalFormat = GetExternalFormat(format_);
|
||||
unsigned dataType = GetDataType(format_);
|
||||
|
||||
|
@ -537,7 +540,7 @@ bool TextureCube::Create()
|
|||
glGetError();
|
||||
for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format_, width_, height_, 0, externalFormat, dataType, 0);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, width_, height_, 0, externalFormat, dataType, 0);
|
||||
if (glGetError())
|
||||
success = false;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,10 @@ void RenderTargetInfo::LoadParameters(const XMLElement& element)
|
|||
|
||||
if (element.HasAttribute("filter"))
|
||||
filtered_ = element.GetBool("filter");
|
||||
|
||||
|
||||
if (element.HasAttribute("srgb"))
|
||||
sRGB_ = element.GetBool("srgb");
|
||||
|
||||
if (element.HasAttribute("size"))
|
||||
size_ = element.GetIntVector2("size");
|
||||
if (element.HasAttribute("sizedivisor"))
|
||||
|
|
|
@ -65,7 +65,8 @@ struct RenderTargetInfo
|
|||
size_(IntVector2::ZERO),
|
||||
sizeMode_(SIZE_ABSOLUTE),
|
||||
active_(true),
|
||||
filtered_(false)
|
||||
filtered_(false),
|
||||
sRGB_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -86,6 +87,8 @@ struct RenderTargetInfo
|
|||
bool active_;
|
||||
/// Filtering flag.
|
||||
bool filtered_;
|
||||
/// sRGB sampling/writing mode flag.
|
||||
bool sRGB_;
|
||||
};
|
||||
|
||||
/// Rendering path command.
|
||||
|
|
|
@ -927,15 +927,20 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
|
|||
return newShadowMap;
|
||||
}
|
||||
|
||||
Texture2D* Renderer::GetScreenBuffer(int width, int height, unsigned format, bool filtered)
|
||||
Texture2D* Renderer::GetScreenBuffer(int width, int height, unsigned format, bool filtered, bool srgb)
|
||||
{
|
||||
bool depthStencil = (format == Graphics::GetDepthStencilFormat());
|
||||
if (depthStencil)
|
||||
{
|
||||
filtered = false;
|
||||
srgb = false;
|
||||
}
|
||||
|
||||
long long searchKey = ((long long)format << 32) | (width << 16) | height;
|
||||
if (filtered)
|
||||
searchKey |= 0x8000000000000000LL;
|
||||
if (srgb)
|
||||
searchKey |= 0x4000000000000000LL;
|
||||
|
||||
// If new size or format, initialize the allocation stats
|
||||
if (screenBuffers_.Find(searchKey) == screenBuffers_.End())
|
||||
|
@ -949,6 +954,7 @@ Texture2D* Renderer::GetScreenBuffer(int width, int height, unsigned format, boo
|
|||
if (allocations >= screenBuffers_[searchKey].Size())
|
||||
{
|
||||
SharedPtr<Texture2D> newBuffer(new Texture2D(context_));
|
||||
newBuffer->SetSRGB(srgb);
|
||||
newBuffer->SetSize(width, height, format, depthStencil ? TEXTURE_DEPTHSTENCIL : TEXTURE_RENDERTARGET);
|
||||
newBuffer->SetFilterMode(filtered ? FILTER_BILINEAR : FILTER_NEAREST);
|
||||
newBuffer->ResetUseTimer();
|
||||
|
|
|
@ -307,7 +307,7 @@ public:
|
|||
/// Allocate a shadow map. If shadow map reuse is disabled, a different map is returned each time.
|
||||
Texture2D* GetShadowMap(Light* light, Camera* camera, unsigned viewWidth, unsigned viewHeight);
|
||||
/// Allocate a rendertarget or depth-stencil texture for deferred rendering or postprocessing. Should only be called during actual rendering, not before.
|
||||
Texture2D* GetScreenBuffer(int width, int height, unsigned format, bool filtered = false);
|
||||
Texture2D* GetScreenBuffer(int width, int height, unsigned format, bool filtered = false, bool srgb = false);
|
||||
/// Allocate a depth-stencil surface that does not need to be readable. Should only be called during actual rendering, not before.
|
||||
RenderSurface* GetDepthStencil(int width, int height);
|
||||
/// Allocate an occlusion buffer.
|
||||
|
|
|
@ -265,7 +265,7 @@ void UI::Render()
|
|||
return;
|
||||
|
||||
// Update quad geometry into the vertex buffer
|
||||
unsigned numVertices = vertexData_.Size() / 6;
|
||||
unsigned numVertices = vertexData_.Size() / UI_VERTEX_SIZE;
|
||||
// Resize the vertex buffer if too small or much too large
|
||||
if (vertexBuffer_->GetVertexCount() < numVertices || vertexBuffer_->GetVertexCount() > numVertices * 2)
|
||||
vertexBuffer_->SetSize(numVertices, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1, true);
|
||||
|
@ -333,7 +333,8 @@ void UI::Render()
|
|||
graphics_->SetScissorTest(true, batch.scissor_);
|
||||
graphics_->SetTexture(0, batch.texture_);
|
||||
graphics_->SetVertexBuffer(vertexBuffer_);
|
||||
graphics_->Draw(TRIANGLE_LIST, batch.vertexStart_ / 6, (batch.vertexEnd_ - batch.vertexStart_) / 6);
|
||||
graphics_->Draw(TRIANGLE_LIST, batch.vertexStart_ / UI_VERTEX_SIZE, (batch.vertexEnd_ - batch.vertexStart_) /
|
||||
UI_VERTEX_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int t
|
|||
float bottomUV = (texOffsetY + (texHeight ? texHeight : height)) * invTextureSize_.y_;
|
||||
|
||||
unsigned begin = vertexData_->Size();
|
||||
vertexData_->Resize(begin + 6 * 6);
|
||||
vertexData_->Resize(begin + 6 * UI_VERTEX_SIZE);
|
||||
float* dest = &(vertexData_->At(begin));
|
||||
vertexEnd_ = vertexData_->Size();
|
||||
|
||||
|
@ -170,7 +170,7 @@ void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int h
|
|||
float bottomUV = ((float)(texOffsetY + (texHeight ? texHeight : height))) * invTextureSize_.y_;
|
||||
|
||||
unsigned begin = vertexData_->Size();
|
||||
vertexData_->Resize(begin + 6 * 6);
|
||||
vertexData_->Resize(begin + 6 * UI_VERTEX_SIZE);
|
||||
float* dest = &(vertexData_->At(begin));
|
||||
vertexEnd_ = vertexData_->Size();
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ class ShaderVariation;
|
|||
class Texture;
|
||||
class UIElement;
|
||||
|
||||
static const unsigned UI_VERTEX_SIZE = 6;
|
||||
|
||||
/// %UI rendering draw call.
|
||||
class UIBatch
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче