Hardware sRGB texture support. OpenGL sRGB framebuffer writing implementation still missing.

This commit is contained in:
Lasse Öörni 2013-03-24 20:05:08 +00:00
Родитель 25372fafd8
Коммит b4599e046d
22 изменённых файлов: 195 добавлений и 34 удалений

Просмотреть файл

@ -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
{