1
0
forked from 0ad/0ad

Changing sky manager to render sky using cubemaps, to avoid duplication of sky textures in memory.

This was SVN commit r12727.
This commit is contained in:
myconid 2012-10-03 12:40:01 +00:00
parent 5cff74f4e7
commit 9e328e6b9f
8 changed files with 144 additions and 114 deletions

View File

@ -1,5 +1,27 @@
!!ARBfp1.0
TEX result.color, fragment.texcoord[0], texture[0], 2D;
# cgc version 3.1.0013, build date Apr 24 2012
# command line args: -oglsl -profile arbfp1
# source file: sky.fs
#vendor NVIDIA Corporation
#version 3.1.0.13
#profile arbfp1
#program main
#semantic baseTex
#var float4 gl_FragColor : $vout.COLOR : COL : -1 : 1
#var samplerCUBE baseTex : : texunit 0 : -1 : 1
#var float3 v_tex : $vin.TEX0 : TEX0 : -1 : 1
#const c[0] = 0.25 0 1 4
PARAM c[1] = { { 0.25, 0, 1, 4 } };
TEMP R0;
TEMP R1;
TEMP R2;
SLT R2.x, c[0].y, fragment.texcoord[0].y;
ABS R2.x, R2;
TEX R0, fragment.texcoord[0], texture[0], CUBE;
ADD R1.x, -fragment.texcoord[0].y, c[0];
MUL R1, R0, R1.x;
MUL R1, R1, c[0].w;
CMP R2.x, -R2, c[0].y, c[0].z;
CMP result.color, -R2.x, R0, R1;
END
# 8 instructions, 3 R-regs

View File

@ -6,7 +6,7 @@
</vertex>
<fragment file="arb/sky.fp">
<uniform name="baseTex" loc="0" type="sampler2D"/>
<uniform name="baseTex" loc="0" type="samplerCube"/>
</fragment>
</program>

View File

@ -1,9 +1,16 @@
#version 110
uniform sampler2D baseTex;
varying vec2 v_tex;
uniform samplerCube baseTex;
varying vec3 v_tex;
void main()
{
gl_FragColor = texture2D(baseTex, v_tex);
vec4 tex = textureCube(baseTex, v_tex);
float m = (1.0 - v_tex.y) - 0.75;
m *= 4.0;
gl_FragColor = (v_tex.y > 0.0) ? (tex * m) : tex;
}

View File

@ -1,11 +1,11 @@
#version 110
varying vec2 v_tex;
varying vec3 v_tex;
attribute vec3 a_vertex;
attribute vec2 a_uv0;
attribute vec3 a_uv0;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(a_vertex, 1.0);
v_tex = gl_MultiTexCoord0.xy;
v_tex = gl_MultiTexCoord0.xyz;
}

View File

@ -175,7 +175,7 @@ bool CShaderManager::NewProgram(const char* name, const CShaderDefines& baseDefi
VfsPath fragmentFile;
CShaderDefines defines = baseDefines;
std::map<CStrIntern, int> vertexUniforms;
std::map<CStrIntern, int> fragmentUniforms;
std::map<CStrIntern, CShaderProgram::frag_index_pair_t> fragmentUniforms;
std::map<CStrIntern, int> vertexAttribs;
int streamFlags = 0;
@ -240,7 +240,22 @@ bool CShaderManager::NewProgram(const char* name, const CShaderDefines& baseDefi
if (Param.GetNodeName() == el_uniform)
{
fragmentUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] = Attrs.GetNamedItem(at_loc).ToInt();
// A somewhat incomplete listing, missing "shadow" and "rect" versions
// which are interpreted as 2D (NB: our shadowmaps may change
// type based on user config).
GLenum type = GL_TEXTURE_2D;
CStr t = Attrs.GetNamedItem(at_type);
if (t == "sampler1D")
type = GL_TEXTURE_1D;
else if (t == "sampler2D")
type = GL_TEXTURE_2D;
else if (t == "sampler3D")
type = GL_TEXTURE_3D;
else if (t == "samplerCube")
type = GL_TEXTURE_CUBE_MAP;
fragmentUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] =
std::make_pair(Attrs.GetNamedItem(at_loc).ToInt(), type);
}
}
}

View File

@ -36,7 +36,7 @@ class CShaderProgramARB : public CShaderProgram
public:
CShaderProgramARB(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const CShaderDefines& defines,
const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, int>& fragmentIndexes,
const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, frag_index_pair_t>& fragmentIndexes,
int streamflags) :
CShaderProgram(streamflags),
m_VertexFile(vertexFile), m_FragmentFile(fragmentFile),
@ -147,42 +147,45 @@ public:
return it->second;
}
int GetUniformFragmentIndex(CStrIntern id)
frag_index_pair_t GetUniformFragmentIndex(CStrIntern id)
{
std::map<CStrIntern, int>::iterator it = m_FragmentIndexes.find(id);
std::map<CStrIntern, frag_index_pair_t>::iterator it = m_FragmentIndexes.find(id);
if (it == m_FragmentIndexes.end())
return -1;
return std::make_pair(-1, 0);
return it->second;
}
virtual Binding GetTextureBinding(texture_id_t id)
{
int index = GetUniformFragmentIndex(CStrIntern(id));
frag_index_pair_t fPair = GetUniformFragmentIndex(CStrIntern(id));
int index = fPair.first;
if (index == -1)
return Binding();
else
return Binding((int)GL_TEXTURE_2D, index);
return Binding((int)fPair.second, index);
}
virtual void BindTexture(texture_id_t id, Handle tex)
{
int index = GetUniformFragmentIndex(CStrIntern(id));
frag_index_pair_t fPair = GetUniformFragmentIndex(CStrIntern(id));
int index = fPair.first;
if (index != -1)
{
GLuint h;
ogl_tex_get_texture_id(tex, &h);
pglActiveTextureARB(GL_TEXTURE0+index);
glBindTexture(GL_TEXTURE_2D, h);
glBindTexture(fPair.second, h);
}
}
virtual void BindTexture(texture_id_t id, GLuint tex)
{
int index = GetUniformFragmentIndex(CStrIntern(id));
frag_index_pair_t fPair = GetUniformFragmentIndex(CStrIntern(id));
int index = fPair.first;
if (index != -1)
{
pglActiveTextureARB(GL_TEXTURE0+index);
glBindTexture(GL_TEXTURE_2D, tex);
glBindTexture(fPair.second, tex);
}
}
@ -196,12 +199,12 @@ public:
virtual Binding GetUniformBinding(uniform_id_t id)
{
CStrIntern idIntern(id);
return Binding(GetUniformVertexIndex(idIntern), GetUniformFragmentIndex(idIntern));
return Binding(GetUniformVertexIndex(idIntern), GetUniformFragmentIndex(idIntern).first);
}
virtual Binding GetUniformBinding(CStrIntern id)
{
return Binding(GetUniformVertexIndex(id), GetUniformFragmentIndex(id));
return Binding(GetUniformVertexIndex(id), GetUniformFragmentIndex(id).first);
}
virtual void Uniform(Binding id, float v0, float v1, float v2, float v3)
@ -247,7 +250,9 @@ private:
GLuint m_FragmentProgram;
std::map<CStrIntern, int> m_VertexIndexes;
std::map<CStrIntern, int> m_FragmentIndexes;
// pair contains <index, gltype>
std::map<CStrIntern, frag_index_pair_t> m_FragmentIndexes;
};
#endif // #if !CONFIG2_GLES
@ -680,7 +685,7 @@ CShaderProgram::CShaderProgram(int streamflags)
#else
/*static*/ CShaderProgram* CShaderProgram::ConstructARB(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const CShaderDefines& defines,
const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, int>& fragmentIndexes,
const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, frag_index_pair_t>& fragmentIndexes,
int streamflags)
{
return new CShaderProgramARB(vertexFile, fragmentFile, defines, vertexIndexes, fragmentIndexes, streamflags);

View File

@ -67,12 +67,17 @@ class CShaderProgram
NONCOPYABLE(CShaderProgram);
public:
typedef const char* attrib_id_t;
typedef const char* texture_id_t;
typedef const char* uniform_id_t;
typedef std::pair<int, GLenum> frag_index_pair_t;
/**
* Construct based on ARB vertex/fragment program files.
*/
static CShaderProgram* ConstructARB(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const CShaderDefines& defines,
const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, int>& fragmentIndexes,
const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, frag_index_pair_t>& fragmentIndexes,
int streamflags);
/**
@ -87,11 +92,7 @@ public:
* Construct an instance of a pre-defined fixed-function pipeline setup.
*/
static CShaderProgram* ConstructFFP(const std::string& id, const CShaderDefines& defines);
typedef const char* attrib_id_t;
typedef const char* texture_id_t;
typedef const char* uniform_id_t;
/**
* Represents a uniform attribute or texture binding.
* For uniforms:

View File

@ -76,7 +76,7 @@ SkyManager::SkyManager()
// Load all sky textures
void SkyManager::LoadSkyTextures()
{
for (size_t i = 0; i < ARRAY_SIZE(m_SkyTexture); ++i)
/*for (size_t i = 0; i < ARRAY_SIZE(m_SkyTexture); ++i)
{
VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(s_imageNames[i])+L".dds");
@ -85,7 +85,7 @@ void SkyManager::LoadSkyTextures()
CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
texture->Prefetch();
m_SkyTexture[i] = texture;
}
}*/
///////////////////////////////////////////////////////////////////////////
// HACK: THE HORRIBLENESS HERE IS OVER 9000. The following code is a HUGE hack and will be removed completely
@ -245,11 +245,12 @@ void SkyManager::RenderSky()
// put the horizon at a fixed height regardless of camera Y
const CCamera& camera = g_Renderer.GetViewCamera();
CVector3D pos = camera.m_Orientation.GetTranslation();
glTranslatef( pos.X, m_HorizonHeight, pos.Z );
// Rotate so that the "left" face, which contains the brightest part of each
// skymap, is in the direction of the sun from our light environment
glRotatef( 90.0f + RADTODEG(g_Renderer.GetLightEnv().GetRotation()), 0.0f, 1.0f, 0.0f );
glRotatef( 180.0f /*+ 45.0f*/ + RADTODEG(g_Renderer.GetLightEnv().GetRotation()), 0.0f, 1.0f, 0.0f );
// Distance to draw the faces at
const float D = 2000.0;
@ -262,96 +263,75 @@ void SkyManager::RenderSky()
skytech = g_Renderer.GetShaderManager().LoadEffect("sky_simple");
skytech->BeginPass();
shader = skytech->GetShader();
shader->BindTexture("baseTex", m_SkyCubeMap);
}
else
{
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap);
}
// Front face (positive Z)
if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
shader->BindTexture("baseTex", m_SkyTexture[FRONT]);
else
m_SkyTexture[FRONT]->Bind();
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );
glVertex3f( -D, -D, +D );
glTexCoord2f( 1, 1 );
glVertex3f( +D, -D, +D );
glTexCoord2f( 1, 0 );
glVertex3f( +D, +D, +D );
glTexCoord2f( 0, 0 );
glVertex3f( -D, +D, +D );
// GL_TEXTURE_CUBE_MAP_NEGATIVE_X
glBegin(GL_QUADS);
glTexCoord3f( +1, +1, +1 ); glVertex3f( -D, -D, -D );
glTexCoord3f( +1, +1, -1 ); glVertex3f( -D, -D, +D );
glTexCoord3f( +1, -1, -1 ); glVertex3f( -D, +D, +D );
glTexCoord3f( +1, -1, +1 ); glVertex3f( -D, +D, -D );
glEnd();
// Back face (negative Z)
if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
shader->BindTexture("baseTex", m_SkyTexture[BACK]);
else
m_SkyTexture[BACK]->Bind();
// GL_TEXTURE_CUBE_MAP_POSITIVE_X
glBegin(GL_QUADS);
glTexCoord3f( -1, +1, -1 ); glVertex3f( +D, -D, +D );
glTexCoord3f( -1, +1, +1 ); glVertex3f( +D, -D, -D );
glTexCoord3f( -1, -1, +1 ); glVertex3f( +D, +D, -D );
glTexCoord3f( -1, -1, -1 ); glVertex3f( +D, +D, +D );
glEnd();
glBegin( GL_QUADS );
glTexCoord2f( 1, 1 );
glVertex3f( -D, -D, -D );
glTexCoord2f( 1, 0 );
glVertex3f( -D, +D, -D );
glTexCoord2f( 0, 0 );
glVertex3f( +D, +D, -D );
glTexCoord2f( 0, 1 );
glVertex3f( +D, -D, -D );
// GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
glBegin(GL_QUADS);
glTexCoord3f( -1, +1, +1 ); glVertex3f( +D, -D, -D );
glTexCoord3f( -1, +1, -1 ); glVertex3f( +D, -D, +D );
glTexCoord3f( +1, +1, -1 ); glVertex3f( -D, -D, +D );
glTexCoord3f( +1, +1, +1 ); glVertex3f( -D, -D, -D );
glEnd();
// GL_TEXTURE_CUBE_MAP_POSITIVE_Y
glBegin(GL_QUADS);
glTexCoord3f( +1, -1, +1 ); glVertex3f( -D, +D, -D );
glTexCoord3f( +1, -1, -1 ); glVertex3f( -D, +D, +D );
glTexCoord3f( -1, -1, -1 ); glVertex3f( +D, +D, +D );
glTexCoord3f( -1, -1, +1 ); glVertex3f( +D, +D, -D );
glEnd();
// GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
glBegin(GL_QUADS);
glTexCoord3f( -1, +1, +1 ); glVertex3f( +D, -D, -D );
glTexCoord3f( +1, +1, +1 ); glVertex3f( -D, -D, -D );
glTexCoord3f( +1, -1, +1 ); glVertex3f( -D, +D, -D );
glTexCoord3f( -1, -1, +1 ); glVertex3f( +D, +D, -D );
glEnd();
// Right face (negative X)
if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
shader->BindTexture("baseTex", m_SkyTexture[RIGHT]);
else
m_SkyTexture[RIGHT]->Bind();
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );
glVertex3f( -D, -D, -D );
glTexCoord2f( 1, 1 );
glVertex3f( -D, -D, +D );
glTexCoord2f( 1, 0 );
glVertex3f( -D, +D, +D );
glTexCoord2f( 0, 0 );
glVertex3f( -D, +D, -D );
// GL_TEXTURE_CUBE_MAP_POSITIVE_Z
glBegin(GL_QUADS);
glTexCoord3f( +1, +1, -1 ); glVertex3f( -D, -D, +D );
glTexCoord3f( -1, +1, -1 ); glVertex3f( +D, -D, +D );
glTexCoord3f( -1, -1, -1 ); glVertex3f( +D, +D, +D );
glTexCoord3f( +1, -1, -1 ); glVertex3f( -D, +D, +D );
glEnd();
// Left face (positive X)
if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
shader->BindTexture("baseTex", m_SkyTexture[LEFT]);
else
m_SkyTexture[LEFT]->Bind();
glBegin( GL_QUADS );
glTexCoord2f( 1, 1 );
glVertex3f( +D, -D, -D );
glTexCoord2f( 1, 0 );
glVertex3f( +D, +D, -D );
glTexCoord2f( 0, 0 );
glVertex3f( +D, +D, +D );
glTexCoord2f( 0, 1 );
glVertex3f( +D, -D, +D );
glEnd();
// Top face (positive Y)
if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
shader->BindTexture("baseTex", m_SkyTexture[TOP]);
else
m_SkyTexture[TOP]->Bind();
glBegin( GL_QUADS );
glTexCoord2f( 1, 0 );
glVertex3f( +D, +D, -D );
glTexCoord2f( 0, 0 );
glVertex3f( -D, +D, -D );
glTexCoord2f( 0, 1 );
glVertex3f( -D, +D, +D );
glTexCoord2f( 1, 1 );
glVertex3f( +D, +D, +D );
glEnd();
if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
{
skytech->EndPass();
}
else
{
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glDisable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_TEXTURE_2D);
}
glPopMatrix();
glDepthMask( GL_TRUE );