Added shader flags

Renamed ShaderBuilder enum to ShaderFlags


Former-commit-id: b3440bac5491f0a0a90cbd7f9ed8e396c16c0864
This commit is contained in:
Lynix 2013-03-01 21:54:41 +01:00
parent d0a6a75f14
commit 347b267d43
7 changed files with 84 additions and 58 deletions

View File

@ -29,6 +29,9 @@
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci /// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
// Le nombre maximum d'instances pouvant être géré par le Renderer
#define NAZARA_RENDERER_INSTANCING_MAX 8192
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) // Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0 #define NAZARA_RENDERER_MEMORYLEAKTRACKER 0

View File

@ -73,6 +73,7 @@ enum nzRendererCap
nzRendererCap_AnisotropicFilter, nzRendererCap_AnisotropicFilter,
nzRendererCap_FP64, nzRendererCap_FP64,
nzRendererCap_HardwareBuffer, nzRendererCap_HardwareBuffer,
nzRendererCap_Instancing,
nzRendererCap_MultipleRenderTargets, nzRendererCap_MultipleRenderTargets,
nzRendererCap_OcclusionQuery, nzRendererCap_OcclusionQuery,
nzRendererCap_PixelBufferObject, nzRendererCap_PixelBufferObject,
@ -143,17 +144,18 @@ enum nzSamplerWrap
nzSamplerWrap_Max = nzSamplerWrap_Repeat nzSamplerWrap_Max = nzSamplerWrap_Repeat
}; };
enum nzShaderBuilderFlags enum nzShaderFlags
{ {
nzShaderBuilder_None = 0, nzShaderFlags_None = 0,
nzShaderBuilder_Deferred = 0x01, nzShaderFlags_Deferred = 0x01,
nzShaderBuilder_DiffuseMapping = 0x02, nzShaderFlags_DiffuseMapping = 0x02,
nzShaderBuilder_Instancing = 0x04, nzShaderFlags_FlipUVs = 0x04,
nzShaderBuilder_Lighting = 0x08, nzShaderFlags_Instancing = 0x08,
nzShaderBuilder_NormalMapping = 0x10, nzShaderFlags_Lighting = 0x10,
nzShaderBuilder_ParallaxMapping = 0x20, nzShaderFlags_NormalMapping = 0x20,
nzShaderBuilder_SpecularMapping = 0x40 nzShaderFlags_ParallaxMapping = 0x40,
nzShaderFlags_SpecularMapping = 0x80
}; };
enum nzShaderLanguage enum nzShaderLanguage

View File

@ -37,7 +37,7 @@ class NAZARA_API NzMaterial : public NzResource
NzMaterial(NzMaterial&& material); NzMaterial(NzMaterial&& material);
~NzMaterial(); ~NzMaterial();
void Apply() const; void Apply(const NzShader* shader) const;
void EnableAlphaBlending(bool alphaBlending); void EnableAlphaBlending(bool alphaBlending);
void EnableFaceCulling(bool faceCulling); void EnableFaceCulling(bool faceCulling);
@ -46,6 +46,7 @@ class NAZARA_API NzMaterial : public NzResource
void EnableZWrite(bool zWrite); void EnableZWrite(bool zWrite);
NzColor GetAmbientColor() const; NzColor GetAmbientColor() const;
const NzShader* GetCustomShader() const;
NzColor GetDiffuseColor() const; NzColor GetDiffuseColor() const;
NzTexture* GetDiffuseMap() const; NzTexture* GetDiffuseMap() const;
NzTextureSampler& GetDiffuseSampler(); NzTextureSampler& GetDiffuseSampler();
@ -55,7 +56,7 @@ class NAZARA_API NzMaterial : public NzResource
nzFaceFilling GetFaceFilling() const; nzFaceFilling GetFaceFilling() const;
NzTexture* GetHeightMap() const; NzTexture* GetHeightMap() const;
NzTexture* GetNormalMap() const; NzTexture* GetNormalMap() const;
const NzShader* GetShader() const; nzUInt32 GetShaderFlags() const;
float GetShininess() const; float GetShininess() const;
NzColor GetSpecularColor() const; NzColor GetSpecularColor() const;
NzTexture* GetSpecularMap() const; NzTexture* GetSpecularMap() const;
@ -64,6 +65,8 @@ class NAZARA_API NzMaterial : public NzResource
nzBlendFunc GetSrcBlend() const; nzBlendFunc GetSrcBlend() const;
nzRendererComparison GetZTestCompare() const; nzRendererComparison GetZTestCompare() const;
bool HasCustomShader() const;
bool IsAlphaBlendingEnabled() const; bool IsAlphaBlendingEnabled() const;
bool IsFaceCullingEnabled() const; bool IsFaceCullingEnabled() const;
bool IsLightingEnabled() const; bool IsLightingEnabled() const;
@ -85,7 +88,7 @@ class NAZARA_API NzMaterial : public NzResource
void SetFaceFilling(nzFaceFilling filling); void SetFaceFilling(nzFaceFilling filling);
void SetHeightMap(NzTexture* map); void SetHeightMap(NzTexture* map);
void SetNormalMap(NzTexture* map); void SetNormalMap(NzTexture* map);
void SetShader(const NzShader* shader); void SetCustomShader(const NzShader* shader);
void SetShininess(float shininess); void SetShininess(float shininess);
void SetSpecularColor(const NzColor& specular); void SetSpecularColor(const NzColor& specular);
void SetSpecularMap(NzTexture* map); void SetSpecularMap(NzTexture* map);
@ -99,25 +102,23 @@ class NAZARA_API NzMaterial : public NzResource
static NzMaterial* GetDefault(); static NzMaterial* GetDefault();
private: private:
void UpdateShader() const;
nzBlendFunc m_dstBlend; nzBlendFunc m_dstBlend;
nzBlendFunc m_srcBlend; nzBlendFunc m_srcBlend;
nzFaceCulling m_faceCulling; nzFaceCulling m_faceCulling;
nzFaceFilling m_faceFilling; nzFaceFilling m_faceFilling;
nzRendererComparison m_zTestCompareFunc; nzRendererComparison m_zTestCompareFunc;
nzUInt32 m_shaderFlags;
NzColor m_ambientColor; NzColor m_ambientColor;
NzColor m_diffuseColor; NzColor m_diffuseColor;
NzColor m_specularColor; NzColor m_specularColor;
NzTextureSampler m_diffuseSampler; NzTextureSampler m_diffuseSampler;
NzTextureSampler m_specularSampler; NzTextureSampler m_specularSampler;
mutable const NzShader* m_shader; mutable const NzShader* m_customShader;
NzTexture* m_diffuseMap; NzTexture* m_diffuseMap;
NzTexture* m_heightMap; NzTexture* m_heightMap;
NzTexture* m_normalMap; NzTexture* m_normalMap;
NzTexture* m_specularMap; NzTexture* m_specularMap;
bool m_alphaBlendingEnabled; bool m_alphaBlendingEnabled;
bool m_autoShader;
bool m_faceCullingEnabled; bool m_faceCullingEnabled;
bool m_lightingEnabled; bool m_lightingEnabled;
bool m_zTestEnabled; bool m_zTestEnabled;

View File

@ -22,7 +22,6 @@ class NzMaterial;
class NzRenderTarget; class NzRenderTarget;
class NzShader; class NzShader;
class NzVertexBuffer; class NzVertexBuffer;
class NzVertexDeclaration;
class NAZARA_API NzRenderer class NAZARA_API NzRenderer
{ {
@ -94,7 +93,7 @@ class NAZARA_API NzRenderer
static void Uninitialize(); static void Uninitialize();
private: private:
static bool EnsureStateUpdate(); static bool EnsureStateUpdate(bool instancing);
static unsigned int s_moduleReferenceCounter; static unsigned int s_moduleReferenceCounter;
}; };

View File

@ -36,6 +36,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
void Destroy(); void Destroy();
nzUInt32 GetFlags() const;
NzString GetLog() const; NzString GetLog() const;
nzShaderLanguage GetLanguage() const; nzShaderLanguage GetLanguage() const;
NzString GetSourceCode(nzShaderType type) const; NzString GetSourceCode(nzShaderType type) const;
@ -67,6 +68,8 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
bool SendVector(int location, const NzVector4d& vector) const; bool SendVector(int location, const NzVector4d& vector) const;
bool SendVector(int location, const NzVector4f& vector) const; bool SendVector(int location, const NzVector4f& vector) const;
void SetFlags(nzUInt32 flags);
void Unlock(); void Unlock();
NzShader& operator=(NzShader&& shader); NzShader& operator=(NzShader&& shader);
@ -75,6 +78,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
static bool IsTypeSupported(nzShaderType type); static bool IsTypeSupported(nzShaderType type);
private: private:
nzUInt32 m_flags = nzShaderFlags_None;
NzShaderImpl* m_impl = nullptr; NzShaderImpl* m_impl = nullptr;
bool m_compiled = false; bool m_compiled = false;
}; };

View File

@ -93,6 +93,11 @@ void NzShader::Destroy()
} }
} }
nzUInt32 NzShader::GetFlags() const
{
return m_flags;
}
NzString NzShader::GetLog() const NzString NzShader::GetLog() const
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE
@ -602,6 +607,11 @@ bool NzShader::SendVector(int location, const NzVector4f& vector) const
return m_impl->SendVector(location, vector); return m_impl->SendVector(location, vector);
} }
void NzShader::SetFlags(nzUInt32 flags)
{
m_flags = flags;
}
void NzShader::Unlock() void NzShader::Unlock()
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE

View File

@ -35,7 +35,7 @@ namespace
sourceCode += '\n'; sourceCode += '\n';
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
sourceCode += "#define LIGHT_DIRECTIONAL 0\n" sourceCode += "#define LIGHT_DIRECTIONAL 0\n"
"#define LIGHT_POINT 1\n" "#define LIGHT_POINT 1\n"
@ -47,7 +47,7 @@ namespace
sourceCode += '\n'; sourceCode += '\n';
/********************Uniformes********************/ /********************Uniformes********************/
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
sourceCode += "struct Light\n" sourceCode += "struct Light\n"
"{\n" "{\n"
@ -63,7 +63,7 @@ namespace
"\n"; "\n";
} }
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
sourceCode += "uniform vec3 CameraPosition;\n" sourceCode += "uniform vec3 CameraPosition;\n"
"uniform int LightCount;\n" "uniform int LightCount;\n"
@ -71,21 +71,21 @@ namespace
"uniform vec4 MaterialAmbient;\n"; "uniform vec4 MaterialAmbient;\n";
} }
if ((flags & nzShaderBuilder_DiffuseMapping) == 0 || flags & nzShaderBuilder_Lighting) if ((flags & nzShaderFlags_DiffuseMapping) == 0 || flags & nzShaderFlags_Lighting)
sourceCode += "uniform vec4 MaterialDiffuse;\n"; sourceCode += "uniform vec4 MaterialDiffuse;\n";
if (flags & nzShaderBuilder_DiffuseMapping) if (flags & nzShaderFlags_DiffuseMapping)
sourceCode += "uniform sampler2D MaterialDiffuseMap;\n"; sourceCode += "uniform sampler2D MaterialDiffuseMap;\n";
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
if (flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_NormalMapping)
sourceCode += "uniform sampler2D MaterialNormalMap;\n"; sourceCode += "uniform sampler2D MaterialNormalMap;\n";
sourceCode += "uniform float MaterialShininess;\n" sourceCode += "uniform float MaterialShininess;\n"
"uniform vec4 MaterialSpecular;\n"; "uniform vec4 MaterialSpecular;\n";
if (flags & nzShaderBuilder_SpecularMapping) if (flags & nzShaderFlags_SpecularMapping)
sourceCode += "uniform sampler2D MaterialSpecularMap;\n"; sourceCode += "uniform sampler2D MaterialSpecularMap;\n";
sourceCode += "uniform vec4 SceneAmbient;\n"; sourceCode += "uniform vec4 SceneAmbient;\n";
@ -94,18 +94,18 @@ namespace
sourceCode += '\n'; sourceCode += '\n';
/********************Entrant********************/ /********************Entrant********************/
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
if (flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_NormalMapping)
sourceCode += inKW + " mat3 vLightToWorld;\n"; sourceCode += inKW + " mat3 vLightToWorld;\n";
else else
sourceCode += inKW + " vec3 vNormal;\n"; sourceCode += inKW + " vec3 vNormal;\n";
} }
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_DiffuseMapping || flags & nzShaderFlags_NormalMapping)
sourceCode += inKW + " vec2 vTexCoord;\n"; sourceCode += inKW + " vec2 vTexCoord;\n";
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
sourceCode += inKW + " vec3 vWorldPos;\n"; sourceCode += inKW + " vec3 vWorldPos;\n";
sourceCode += '\n'; sourceCode += '\n';
@ -120,14 +120,14 @@ namespace
sourceCode += "void main()\n" sourceCode += "void main()\n"
"{\n"; "{\n";
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
sourceCode += "vec3 light = vec3(0.0, 0.0, 0.0);\n"; sourceCode += "vec3 light = vec3(0.0, 0.0, 0.0);\n";
if (flags & nzShaderBuilder_SpecularMapping) if (flags & nzShaderFlags_SpecularMapping)
sourceCode += "vec3 si = vec3(0.0, 0.0, 0.0);\n"; sourceCode += "vec3 si = vec3(0.0, 0.0, 0.0);\n";
if (flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_NormalMapping)
sourceCode += "vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture2D(MaterialNormalMap, vTexCoord)) - 1.0));\n"; sourceCode += "vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture2D(MaterialNormalMap, vTexCoord)) - 1.0));\n";
else else
sourceCode += "vec3 normal = normalize(vNormal);\n"; sourceCode += "vec3 normal = normalize(vNormal);\n";
@ -160,7 +160,7 @@ namespace
"\n" "\n"
"float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n"; "float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n";
if (flags & nzShaderBuilder_SpecularMapping) if (flags & nzShaderFlags_SpecularMapping)
sourceCode += "si"; sourceCode += "si";
else else
sourceCode += "light"; sourceCode += "light";
@ -197,7 +197,7 @@ namespace
"\n" "\n"
"float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n"; "float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n";
if (flags & nzShaderBuilder_SpecularMapping) if (flags & nzShaderFlags_SpecularMapping)
sourceCode += "si"; sourceCode += "si";
else else
sourceCode += "light"; sourceCode += "light";
@ -241,7 +241,7 @@ namespace
"\n" "\n"
"float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n"; "float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n";
if (flags & nzShaderBuilder_SpecularMapping) if (flags & nzShaderFlags_SpecularMapping)
sourceCode += "si"; sourceCode += "si";
else else
sourceCode += "light"; sourceCode += "light";
@ -265,15 +265,15 @@ namespace
sourceCode += fragmentColorKW + " = vec4(light, MaterialDiffuse.a)"; sourceCode += fragmentColorKW + " = vec4(light, MaterialDiffuse.a)";
if (flags & nzShaderBuilder_DiffuseMapping) if (flags & nzShaderFlags_DiffuseMapping)
sourceCode += "*texture2D(MaterialDiffuseMap, vTexCoord)"; sourceCode += "*texture2D(MaterialDiffuseMap, vTexCoord)";
if (flags & nzShaderBuilder_SpecularMapping) if (flags & nzShaderFlags_SpecularMapping)
sourceCode += " + vec4(si, MaterialDiffuse.a)*texture2D(MaterialSpecularMap, vTexCoord)"; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens sourceCode += " + vec4(si, MaterialDiffuse.a)*texture2D(MaterialSpecularMap, vTexCoord)"; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens
sourceCode += ";\n"; sourceCode += ";\n";
} }
else if (flags & nzShaderBuilder_DiffuseMapping) else if (flags & nzShaderFlags_DiffuseMapping)
sourceCode += fragmentColorKW + " = texture2D(MaterialDiffuseMap, vTexCoord);\n"; sourceCode += fragmentColorKW + " = texture2D(MaterialDiffuseMap, vTexCoord);\n";
else else
sourceCode += fragmentColorKW + " = MaterialDiffuse;\n"; sourceCode += fragmentColorKW + " = MaterialDiffuse;\n";
@ -303,11 +303,11 @@ namespace
sourceCode += '\n'; sourceCode += '\n';
/********************Uniformes********************/ /********************Uniformes********************/
if (flags & nzShaderBuilder_Instancing) if (flags & nzShaderFlags_Instancing)
sourceCode += "uniform mat4 ViewProjMatrix;\n"; sourceCode += "uniform mat4 ViewProjMatrix;\n";
else else
{ {
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
sourceCode += "uniform mat4 WorldMatrix;\n"; sourceCode += "uniform mat4 WorldMatrix;\n";
sourceCode += "uniform mat4 WorldViewProjMatrix;\n"; sourceCode += "uniform mat4 WorldViewProjMatrix;\n";
@ -316,35 +316,35 @@ namespace
sourceCode += '\n'; sourceCode += '\n';
/********************Entrant********************/ /********************Entrant********************/
if (flags & nzShaderBuilder_Instancing) if (flags & nzShaderFlags_Instancing)
sourceCode += inKW + " mat4 InstanceMatrix;\n"; sourceCode += inKW + " mat4 InstanceMatrix;\n";
sourceCode += inKW + " vec3 VertexPosition;\n"; sourceCode += inKW + " vec3 VertexPosition;\n";
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
sourceCode += inKW + " vec3 VertexNormal;\n"; sourceCode += inKW + " vec3 VertexNormal;\n";
sourceCode += inKW + " vec3 VertexTangent;\n"; sourceCode += inKW + " vec3 VertexTangent;\n";
} }
if (flags & nzShaderBuilder_DiffuseMapping) if (flags & nzShaderFlags_DiffuseMapping)
sourceCode += inKW + " vec2 VertexTexCoord0;\n"; sourceCode += inKW + " vec2 VertexTexCoord0;\n";
sourceCode += '\n'; sourceCode += '\n';
/********************Sortant********************/ /********************Sortant********************/
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
if (flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_NormalMapping)
sourceCode += outKW + " mat3 vLightToWorld;\n"; sourceCode += outKW + " mat3 vLightToWorld;\n";
else else
sourceCode += outKW + " vec3 vNormal;\n"; sourceCode += outKW + " vec3 vNormal;\n";
} }
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_DiffuseMapping || flags & nzShaderFlags_NormalMapping)
sourceCode += outKW + " vec2 vTexCoord;\n"; sourceCode += outKW + " vec2 vTexCoord;\n";
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
sourceCode += outKW + " vec3 vWorldPos;\n"; sourceCode += outKW + " vec3 vWorldPos;\n";
sourceCode += '\n'; sourceCode += '\n';
@ -353,19 +353,19 @@ namespace
sourceCode += "void main()\n" sourceCode += "void main()\n"
"{\n"; "{\n";
if (flags & nzShaderBuilder_Instancing) if (flags & nzShaderFlags_Instancing)
sourceCode += "gl_Position = InstanceMatrix * ViewProjMatrix * vec4(VertexPosition, 1.0);\n"; sourceCode += "gl_Position = ViewProjMatrix * InstanceMatrix * vec4(VertexPosition, 1.0);\n";
else else
sourceCode += "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n"; sourceCode += "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n";
if (flags & nzShaderBuilder_Lighting) if (flags & nzShaderFlags_Lighting)
{ {
if (flags & nzShaderBuilder_Instancing) if (flags & nzShaderFlags_Instancing)
sourceCode += "mat3 rotationMatrix = mat3(InstanceMatrix);\n"; sourceCode += "mat3 rotationMatrix = mat3(InstanceMatrix);\n";
else else
sourceCode += "mat3 rotationMatrix = mat3(WorldMatrix);\n"; sourceCode += "mat3 rotationMatrix = mat3(WorldMatrix);\n";
if (flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_NormalMapping)
{ {
sourceCode += "\n" sourceCode += "\n"
"vec3 binormal = cross(VertexNormal, VertexTangent);\n" "vec3 binormal = cross(VertexNormal, VertexTangent);\n"
@ -378,12 +378,17 @@ namespace
sourceCode += "vNormal = normalize(rotationMatrix * VertexNormal);\n"; sourceCode += "vNormal = normalize(rotationMatrix * VertexNormal);\n";
} }
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping) if (flags & nzShaderFlags_DiffuseMapping || flags & nzShaderFlags_NormalMapping || flags & nzShaderFlags_SpecularMapping)
sourceCode += "vTexCoord = VertexTexCoord0;\n";
if (flags & nzShaderBuilder_Lighting)
{ {
if (flags & nzShaderBuilder_Instancing) if (flags & nzShaderFlags_FlipUVs)
sourceCode += "vTexCoord = vec2(VertexTexCoord0.x, 1.0 - VertexTexCoord0.y);\n";
else
sourceCode += "vTexCoord = VertexTexCoord0;\n";
}
if (flags & nzShaderFlags_Lighting)
{
if (flags & nzShaderFlags_Instancing)
sourceCode += "vWorldPos = vec3(InstanceMatrix * vec4(VertexPosition, 1.0));\n"; sourceCode += "vWorldPos = vec3(InstanceMatrix * vec4(VertexPosition, 1.0));\n";
else else
sourceCode += "vWorldPos = vec3(WorldMatrix * vec4(VertexPosition, 1.0));\n"; sourceCode += "vWorldPos = vec3(WorldMatrix * vec4(VertexPosition, 1.0));\n";
@ -434,6 +439,8 @@ namespace
return nullptr; return nullptr;
} }
shader->SetFlags(flags);
return shader.release(); return shader.release();
} }
} }