mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-08-15 14:43:32 -07:00
More programmable pipeline updates
This was SVN commit r1280.
This commit is contained in:
parent
2cf79ca6cf
commit
955ddcf9a1
14 changed files with 143 additions and 50 deletions
|
|
@ -18,30 +18,56 @@
|
|||
#include "Color.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
class CMapWriter;
|
||||
class CMapReader;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CLightEnv: description of a lighting environment - contains all the
|
||||
// necessary parameters for representation of the lighting within a scenario
|
||||
class CLightEnv
|
||||
class CLightEnv
|
||||
{
|
||||
friend class CMapWriter;
|
||||
friend class CMapReader;
|
||||
// wierd accessor order to preserve memory layout of the class
|
||||
public:
|
||||
RGBColor m_SunColor;
|
||||
private:
|
||||
float m_Elevation;
|
||||
float m_Rotation;
|
||||
public:
|
||||
RGBColor m_TerrainAmbientColor;
|
||||
RGBColor m_UnitsAmbientColor;
|
||||
CVector3D m_SunDir;
|
||||
|
||||
// get sun direction from a rotation and elevation; defined such that:
|
||||
// 0 rotation = (0,0,1)
|
||||
// PI/2 rotation = (-1,0,0)
|
||||
// 0 elevation = (0,0,0)
|
||||
// PI/2 elevation = (0,-1,0)
|
||||
void GetSunDirection(CVector3D& lightdir) const {
|
||||
lightdir.Y=-float(sin(m_Elevation));
|
||||
float scale=1+lightdir.Y;
|
||||
lightdir.X=scale*float(sin(m_Rotation));
|
||||
lightdir.Z=scale*float(cos(m_Rotation));
|
||||
lightdir.Normalize();
|
||||
}
|
||||
|
||||
float GetElevation() { return m_Elevation; }
|
||||
float GetRotation() { return m_Rotation; }
|
||||
|
||||
void SetElevation(float f)
|
||||
{
|
||||
m_Elevation = f;
|
||||
CalculateSunDirection();
|
||||
}
|
||||
|
||||
void SetRotation(float f)
|
||||
{
|
||||
m_Rotation = f;
|
||||
CalculateSunDirection();
|
||||
}
|
||||
|
||||
void CalculateSunDirection()
|
||||
{
|
||||
m_SunDir.Y=-float(sin(m_Elevation));
|
||||
float scale=1+m_SunDir.Y;
|
||||
m_SunDir.X=scale*float(sin(m_Rotation));
|
||||
m_SunDir.Z=scale*float(cos(m_Rotation));
|
||||
m_SunDir.Normalize();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ void CMapReader::UnpackLightEnv(CFileUnpacker& unpacker)
|
|||
unpacker.UnpackRaw(&m_LightEnv.m_Rotation,sizeof(m_LightEnv.m_Rotation));
|
||||
unpacker.UnpackRaw(&m_LightEnv.m_TerrainAmbientColor,sizeof(m_LightEnv.m_TerrainAmbientColor));
|
||||
unpacker.UnpackRaw(&m_LightEnv.m_UnitsAmbientColor,sizeof(m_LightEnv.m_UnitsAmbientColor));
|
||||
m_LightEnv.CalculateSunDirection();
|
||||
}
|
||||
|
||||
// UnpackObjects: unpack world objects from input stream
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ bool CMaterial::operator ==(const CMaterial &material)
|
|||
|
||||
void CMaterial::Bind()
|
||||
{
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, &m_Diffuse.data[0]);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, &m_Ambient.data[0]);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, &m_Specular.data[0]);
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, &m_Emissive.data[0]);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, &m_Diffuse.r);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, &m_Ambient.r);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, &m_Specular.r);
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, &m_Emissive.r);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, m_SpecularPower);
|
||||
|
||||
oglCheck();
|
||||
|
|
@ -100,6 +100,18 @@ void CMaterial::SetTexture(const CStr &texture)
|
|||
ComputeHash();
|
||||
}
|
||||
|
||||
void CMaterial::SetVertexProgram(const CStr &prog)
|
||||
{
|
||||
m_VertexProgram = prog;
|
||||
ComputeHash();
|
||||
}
|
||||
|
||||
void CMaterial::SetFragmentProgram(const CStr &prog)
|
||||
{
|
||||
m_FragmentProgram = prog;
|
||||
ComputeHash();
|
||||
}
|
||||
|
||||
void CMaterial::SetDiffuse(const SMaterialColor &color)
|
||||
{
|
||||
m_Diffuse = color;
|
||||
|
|
@ -144,5 +156,7 @@ void CMaterial::ComputeHash()
|
|||
m_Specular.Sum() +
|
||||
m_Emissive.Sum() +
|
||||
m_SpecularPower +
|
||||
(float)m_Texture.GetHashCode();
|
||||
(float)m_Texture.GetHashCode() +
|
||||
(float)m_VertexProgram.GetHashCode() +
|
||||
(float)m_FragmentProgram.GetHashCode();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@
|
|||
struct SMaterialColor
|
||||
{
|
||||
public:
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
|
||||
SMaterialColor() { r = 0.0f; g = 0.0f; b = 0.0f; a = 1.0f; }
|
||||
SMaterialColor(float _r, float _g, float _b, float _a)
|
||||
{
|
||||
|
|
@ -20,19 +25,7 @@ public:
|
|||
g = color.g;
|
||||
b = color.b;
|
||||
a = color.a;
|
||||
}
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
float data[4];
|
||||
};
|
||||
}
|
||||
|
||||
void operator =(const SMaterialColor color)
|
||||
{
|
||||
|
|
@ -69,6 +62,8 @@ public:
|
|||
float GetHash() { return m_Hash; }
|
||||
|
||||
CStr GetTexture() { return m_Texture; }
|
||||
CStr GetVertexProgram() { return m_VertexProgram; }
|
||||
CStr GetFragmentProgram() { return m_FragmentProgram; }
|
||||
SMaterialColor GetDiffuse();
|
||||
SMaterialColor GetAmbient();
|
||||
SMaterialColor GetSpecular();
|
||||
|
|
@ -77,6 +72,8 @@ public:
|
|||
bool UsesAlpha() { return m_Alpha; }
|
||||
|
||||
void SetTexture(const CStr &texture);
|
||||
void SetVertexProgram(const CStr &prog);
|
||||
void SetFragmentProgram(const CStr &prog);
|
||||
void SetDiffuse(const SMaterialColor &color);
|
||||
void SetAmbient(const SMaterialColor &color);
|
||||
void SetSpecular(const SMaterialColor &color);
|
||||
|
|
@ -101,6 +98,10 @@ protected:
|
|||
// Path to the materials texture
|
||||
CStr m_Texture;
|
||||
|
||||
// Paths to vertex/fragment programs
|
||||
CStr m_VertexProgram;
|
||||
CStr m_FragmentProgram;
|
||||
|
||||
// Alpha required flag
|
||||
bool m_Alpha;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@ CMaterial &CMaterialManager::LoadMaterial(const char *file)
|
|||
#define EL(x) int el_##x = xeroFile.getElementID(#x)
|
||||
#define AT(x) int at_##x = xeroFile.getAttributeID(#x)
|
||||
EL(texture);
|
||||
EL(vertexprogram);
|
||||
EL(fragmentprogram);
|
||||
|
||||
EL(colors);
|
||||
AT(diffuse);
|
||||
|
|
@ -218,6 +220,16 @@ CMaterial &CMaterialManager::LoadMaterial(const char *file)
|
|||
CStr value(node.getText());
|
||||
material->SetTexture(value);
|
||||
|
||||
}
|
||||
else if(token == el_vertexprogram)
|
||||
{
|
||||
CStr value(node.getText());
|
||||
material->SetVertexProgram(value);
|
||||
}
|
||||
else if(token == el_fragmentprogram)
|
||||
{
|
||||
CStr value(node.getText());
|
||||
material->SetFragmentProgram(value);
|
||||
}
|
||||
else if(token == el_colors)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@
|
|||
#include "SkeletonAnim.h"
|
||||
#include "SkeletonAnimDef.h"
|
||||
#include "SkeletonAnimManager.h"
|
||||
#include "ProgramManager.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
CModel::CModel()
|
||||
: m_pModelDef(0), m_Flags(0), m_Anim(0), m_AnimTime(0),
|
||||
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false)
|
||||
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false),
|
||||
m_VertexProgram(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -347,3 +349,13 @@ void CModel::SetTransform(const CMatrix3D& transform)
|
|||
prop.m_Model->SetTransform(proptransform);
|
||||
}
|
||||
}
|
||||
|
||||
void CModel::SetMaterial(const CMaterial &material)
|
||||
{
|
||||
m_Material = material;
|
||||
if(m_Material.GetTexture().Trim(PS_TRIM_BOTH).Length() > 0)
|
||||
{
|
||||
}
|
||||
if(m_Material.GetVertexProgram().Trim(PS_TRIM_BOTH).Length() > 0)
|
||||
m_VertexProgram = g_ProgramManager.FindVertexProgram(m_Material.GetVertexProgram().Trim(PS_TRIM_BOTH).c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "RenderableObject.h"
|
||||
#include "SkeletonAnim.h"
|
||||
#include "Material.h"
|
||||
#include "renderer/VertexProgram.h"
|
||||
|
||||
#define MODELFLAG_CASTSHADOWS (1<<0)
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ public:
|
|||
// set the model's texture
|
||||
void SetTexture(const CTexture& tex) { m_Texture=tex; }
|
||||
// set the model's material
|
||||
void SetMaterial(const CMaterial &material) { m_Material = material; }
|
||||
void SetMaterial(const CMaterial &material);
|
||||
// get the model's texture
|
||||
CTexture* GetTexture() { return &m_Texture; }
|
||||
// get the models material
|
||||
|
|
@ -121,6 +122,8 @@ private:
|
|||
u32 m_Flags;
|
||||
// texture used by model
|
||||
CTexture m_Texture;
|
||||
// vertex program
|
||||
CVertexProgram *m_VertexProgram;
|
||||
// model's material
|
||||
CMaterial m_Material;
|
||||
// pointer to the model's raw 3d data
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#include "precompiled.h"
|
||||
#include "graphics/ProgramManager.h"
|
||||
|
||||
#define SAFE_DELETE(x) \
|
||||
if((x)) { delete (x); (x) = NULL; }
|
||||
|
||||
CProgramManager::CProgramManager()
|
||||
{
|
||||
#ifdef BUILD_CG
|
||||
|
|
@ -31,7 +34,9 @@ CVertexProgram *CProgramManager::FindVertexProgram(const char *file)
|
|||
if(prog && prog->IsValid())
|
||||
m_VertexProgs[std::string(file)] = prog;
|
||||
else
|
||||
prog = NULL;
|
||||
{
|
||||
SAFE_DELETE(prog);
|
||||
}
|
||||
}
|
||||
|
||||
return prog;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public:
|
|||
|
||||
void WritePPInfo(FILE *file);
|
||||
#ifdef BUILD_CG
|
||||
CGprofile GetVPProfile() { return m_VPProfile; }
|
||||
CGprofile GetFPProfile() { return m_FPProfile; }
|
||||
CGcontext GetContext() { return m_Context; }
|
||||
#endif
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1000,8 +1000,8 @@ PREVTSC=CURTSC;
|
|||
// lighting environment through a pointer, this has to be done before
|
||||
// the first Frame.
|
||||
g_LightEnv.m_SunColor=RGBColor(1,1,1);
|
||||
g_LightEnv.m_Rotation=DEGTORAD(270);
|
||||
g_LightEnv.m_Elevation=DEGTORAD(45);
|
||||
g_LightEnv.SetRotation(DEGTORAD(270));
|
||||
g_LightEnv.SetElevation(DEGTORAD(45));
|
||||
g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0);
|
||||
g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f);
|
||||
g_Renderer.SetLightEnv(&g_LightEnv);
|
||||
|
|
|
|||
|
|
@ -276,11 +276,8 @@ void CRenderer::BeginFrame()
|
|||
m_SHCoeffsTerrain.Clear();
|
||||
|
||||
if (m_LightEnv) {
|
||||
CVector3D dirlight;
|
||||
m_LightEnv->GetSunDirection(dirlight);
|
||||
|
||||
m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor);
|
||||
m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor);
|
||||
m_SHCoeffsUnits.AddDirectionalLight(m_LightEnv->m_SunDir, m_LightEnv->m_SunColor);
|
||||
m_SHCoeffsTerrain.AddDirectionalLight(m_LightEnv->m_SunDir, m_LightEnv->m_SunColor);
|
||||
|
||||
m_SHCoeffsUnits.AddAmbientLight(m_LightEnv->m_UnitsAmbientColor);
|
||||
m_SHCoeffsTerrain.AddAmbientLight(m_LightEnv->m_TerrainAmbientColor);
|
||||
|
|
@ -377,15 +374,11 @@ void CRenderer::CalcShadowMatrices()
|
|||
bounds.GetCentre(centre);
|
||||
|
||||
// get sunlight direction
|
||||
CVector3D lightdir;
|
||||
// ??? RC using matrix rotation to get sun direction?
|
||||
m_LightEnv->GetSunDirection(lightdir);
|
||||
|
||||
// ??? RC more optimal light placement?
|
||||
CVector3D lightpos=centre-(lightdir*1000);
|
||||
CVector3D lightpos=centre-(m_LightEnv->m_SunDir * 1000);
|
||||
|
||||
// make light transformation matrix
|
||||
ConstructLightTransform(lightpos,lightdir,m_LightTransform);
|
||||
ConstructLightTransform(lightpos,m_LightEnv->m_SunDir,m_LightTransform);
|
||||
|
||||
// transform shadow bounds to light space, calculate near and far bounds
|
||||
CVector3D vp[8];
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ public:
|
|||
// return stats accumulated for current frame
|
||||
const Stats& GetStats() { return m_Stats; }
|
||||
|
||||
// return the current light environment
|
||||
const CLightEnv &GetLightEnv() { return *m_LightEnv; }
|
||||
protected:
|
||||
friend class CVertexBuffer;
|
||||
friend class CPatchRData;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
#include "res/mem.h"
|
||||
#include "renderer/VertexProgram.h"
|
||||
#include "graphics/ProgramManager.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "maths/Vector3D.h"
|
||||
#include "graphics/LightEnv.h"
|
||||
#include "CLogger.h"
|
||||
|
||||
#define LOG_CATEGORY "shaders"
|
||||
|
|
@ -35,12 +38,8 @@ void CVertexProgram::Bind()
|
|||
if(!IsValid())
|
||||
return;
|
||||
|
||||
CGparameter param = cgGetFirstParameter(m_Program, CG_PROGRAM);
|
||||
while(param)
|
||||
{
|
||||
PushParameter(param);
|
||||
param = cgGetNextParameter(param);
|
||||
}
|
||||
EnumParameters(CG_GLOBAL);
|
||||
EnumParameters(CG_PROGRAM);
|
||||
|
||||
if(!cgGLIsProgramLoaded(m_Program))
|
||||
cgGLLoadProgram(m_Program);
|
||||
|
|
@ -53,7 +52,7 @@ void CVertexProgram::Load(const char *file)
|
|||
{
|
||||
#ifdef BUILD_CG
|
||||
m_Program = NULL;
|
||||
if(!file || !vfs_exists(file))
|
||||
if(!file || !vfs_exists(file) || g_ProgramManager.GetVPProfile() == CG_PROFILE_UNKNOWN)
|
||||
return;
|
||||
|
||||
void *data;
|
||||
|
|
@ -72,7 +71,7 @@ void CVertexProgram::Load(const char *file)
|
|||
g_ProgramManager.GetContext(),
|
||||
CG_SOURCE,
|
||||
src.c_str(),
|
||||
CG_PROFILE_ARBVP1,
|
||||
g_ProgramManager.GetVPProfile(),
|
||||
"main",
|
||||
NULL
|
||||
);
|
||||
|
|
@ -86,6 +85,16 @@ void CVertexProgram::Load(const char *file)
|
|||
|
||||
#ifdef BUILD_CG
|
||||
|
||||
void CVertexProgram::EnumParameters(CGenum ns)
|
||||
{
|
||||
CGparameter param = cgGetFirstParameter(m_Program, ns);
|
||||
while(param)
|
||||
{
|
||||
PushParameter(param);
|
||||
param = cgGetNextParameter(param);
|
||||
}
|
||||
}
|
||||
|
||||
void CVertexProgram::PushParameter(CGparameter param)
|
||||
{
|
||||
assert(param);
|
||||
|
|
@ -99,6 +108,18 @@ void CVertexProgram::PushParameter(CGparameter param)
|
|||
cgGLSetStateMatrixParameter(param, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
else if(name == "Texture")
|
||||
cgGLSetStateMatrixParameter(param, CG_GL_TEXTURE_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
else if(name == "SunDir")
|
||||
{
|
||||
cgGLSetParameterPointer(
|
||||
param, sizeof(CVector3D), GL_FLOAT, sizeof(float), &g_Renderer.GetLightEnv().m_SunDir.X
|
||||
);
|
||||
}
|
||||
else if(name == "SunColor")
|
||||
{
|
||||
cgGLSetParameterPointer(
|
||||
param, sizeof(CVector3D), GL_FLOAT, sizeof(float), &g_Renderer.GetLightEnv().m_SunColor.X
|
||||
);
|
||||
}
|
||||
else
|
||||
LOG(WARNING, LOG_CATEGORY, "CVertexShader::LoadShader: Unknown parameter name: %s", name.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ private:
|
|||
void Bind();
|
||||
void Load(const char *file);
|
||||
#ifdef BUILD_CG
|
||||
void EnumParameters(CGenum ns);
|
||||
void PushParameter(CGparameter param);
|
||||
CGprogram m_Program;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue