Turned on OpenGL 2.0 / GLSL render path.
parent
466aa30856
commit
6f8031d387
|
@ -37,6 +37,7 @@ OBJS=\
|
|||
$(INTDIR)\galaxy.obj \
|
||||
$(INTDIR)\glcontext.obj \
|
||||
$(INTDIR)\glext.obj \
|
||||
$(INTDIR)\glshader.obj \
|
||||
$(INTDIR)\image.obj \
|
||||
$(INTDIR)\jpleph.obj \
|
||||
$(INTDIR)\location.obj \
|
||||
|
@ -60,6 +61,7 @@ OBJS=\
|
|||
$(INTDIR)\rendcontext.obj \
|
||||
$(INTDIR)\samporbit.obj \
|
||||
$(INTDIR)\selection.obj \
|
||||
$(INTDIR)\shadermanager.obj \
|
||||
$(INTDIR)\simulation.obj \
|
||||
$(INTDIR)\solarsys.obj \
|
||||
$(INTDIR)\spheremesh.obj \
|
||||
|
|
|
@ -131,6 +131,7 @@ bool GLContext::setRenderPath(GLRenderPath path)
|
|||
case GLPath_NvCombiner_ARBVP:
|
||||
case GLPath_ARBFP_ARBVP:
|
||||
case GLPath_NV30:
|
||||
case GLPath_GLSL:
|
||||
vertexPath = VPath_ARB;
|
||||
break;
|
||||
default:
|
||||
|
@ -156,7 +157,13 @@ bool GLContext::renderPathSupported(GLRenderPath path) const
|
|||
extensionSupported("GL_ARB_texture_env_combine")) );
|
||||
|
||||
case GLPath_NvCombiner:
|
||||
return false;
|
||||
/*
|
||||
// No longer supported; all recent NVIDIA drivers also support
|
||||
// the vertex_program extension, so the combiners-only path
|
||||
// isn't necessary.
|
||||
return extensionSupported("GL_NV_register_combiners");
|
||||
*/
|
||||
|
||||
case GLPath_DOT3_ARBVP:
|
||||
return (extensionSupported("GL_ARB_texture_env_dot3") &&
|
||||
|
@ -188,6 +195,11 @@ bool GLContext::renderPathSupported(GLRenderPath path) const
|
|||
return (extensionSupported("GL_ARB_vertex_program") &&
|
||||
extensionSupported("GL_NV_fragment_program"));
|
||||
|
||||
case GLPath_GLSL:
|
||||
return (extensionSupported("GL_ARB_shader_objects") &&
|
||||
extensionSupported("GL_ARB_shading_language_100") &&
|
||||
extensionSupported("GL_ARB_vertex_shader"));
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -200,7 +212,7 @@ GLContext::GLRenderPath GLContext::nextRenderPath()
|
|||
|
||||
do {
|
||||
newPath = (GLRenderPath) ((int) newPath + 1);;
|
||||
if (newPath > GLPath_NV30)
|
||||
if (newPath > GLPath_GLSL)
|
||||
newPath = GLPath_Basic;
|
||||
} while (newPath != renderPath && !renderPathSupported(newPath));
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class GLContext
|
|||
GLPath_NvCombiner_ARBVP = 5,
|
||||
GLPath_ARBFP_ARBVP = 6,
|
||||
GLPath_NV30 = 7,
|
||||
GLPath_GLSL = 8,
|
||||
};
|
||||
|
||||
enum VertexPath
|
||||
|
|
|
@ -68,18 +68,18 @@ GLShader::~GLShader()
|
|||
|
||||
//************* GLxxxProperty **********
|
||||
|
||||
FloatShaderProperty::FloatShaderProperty() :
|
||||
FloatShaderParameter::FloatShaderParameter() :
|
||||
slot(-1)
|
||||
{
|
||||
}
|
||||
|
||||
FloatShaderProperty::FloatShaderProperty(int obj, const char* name)
|
||||
FloatShaderParameter::FloatShaderParameter(int obj, const char* name)
|
||||
{
|
||||
slot = glx::glGetUniformLocationARB(obj, name);
|
||||
}
|
||||
|
||||
FloatShaderProperty&
|
||||
FloatShaderProperty::operator=(float f)
|
||||
FloatShaderParameter&
|
||||
FloatShaderParameter::operator=(float f)
|
||||
{
|
||||
if (slot != -1)
|
||||
glx::glUniform1fARB(slot, f);
|
||||
|
@ -87,26 +87,26 @@ FloatShaderProperty::operator=(float f)
|
|||
}
|
||||
|
||||
|
||||
Vec3ShaderProperty::Vec3ShaderProperty() :
|
||||
Vec3ShaderParameter::Vec3ShaderParameter() :
|
||||
slot(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3ShaderProperty::Vec3ShaderProperty(int obj, const char* name)
|
||||
Vec3ShaderParameter::Vec3ShaderParameter(int obj, const char* name)
|
||||
{
|
||||
slot = glx::glGetUniformLocationARB(obj, name);
|
||||
}
|
||||
|
||||
Vec3ShaderProperty&
|
||||
Vec3ShaderProperty::operator=(const Vec3f& v)
|
||||
Vec3ShaderParameter&
|
||||
Vec3ShaderParameter::operator=(const Vec3f& v)
|
||||
{
|
||||
if (slot != -1)
|
||||
glx::glUniform3fARB(slot, v.x, v.y, v.z);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3ShaderProperty&
|
||||
Vec3ShaderProperty::operator=(const Point3f& p)
|
||||
Vec3ShaderParameter&
|
||||
Vec3ShaderParameter::operator=(const Point3f& p)
|
||||
{
|
||||
if (slot != -1)
|
||||
glx::glUniform3fARB(slot, p.x, p.y, p.z);
|
||||
|
@ -114,18 +114,18 @@ Vec3ShaderProperty::operator=(const Point3f& p)
|
|||
}
|
||||
|
||||
|
||||
Vec4ShaderProperty::Vec4ShaderProperty() :
|
||||
Vec4ShaderParameter::Vec4ShaderParameter() :
|
||||
slot(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4ShaderProperty::Vec4ShaderProperty(int obj, const char* name)
|
||||
Vec4ShaderParameter::Vec4ShaderParameter(int obj, const char* name)
|
||||
{
|
||||
slot = glx::glGetUniformLocationARB(obj, name);
|
||||
}
|
||||
|
||||
Vec4ShaderProperty&
|
||||
Vec4ShaderProperty::operator=(const Vec4f& v)
|
||||
Vec4ShaderParameter&
|
||||
Vec4ShaderParameter::operator=(const Vec4f& v)
|
||||
{
|
||||
if (slot != -1)
|
||||
glx::glUniform4fARB(slot, v.x, v.y, v.z, v.w);
|
||||
|
@ -170,7 +170,11 @@ GLProgram::link()
|
|||
glx::glGetObjectParameterivARB(id, GL_OBJECT_LINK_STATUS_ARB,
|
||||
&linkSuccess);
|
||||
if (linkSuccess == GL_FALSE)
|
||||
{
|
||||
cout << "Error linking shader program:\n";
|
||||
cout << GetInfoLog(getID());
|
||||
return ShaderStatus_LinkError;
|
||||
}
|
||||
|
||||
return ShaderStatus_OK;
|
||||
}
|
||||
|
@ -262,14 +266,6 @@ GLShaderLoader::CreateProgram(const GLVertexShader& vs,
|
|||
prog->attach(vs);
|
||||
prog->attach(fs);
|
||||
|
||||
GLShaderStatus status = prog->link();
|
||||
if (status != ShaderStatus_OK)
|
||||
{
|
||||
cout << "Error linking shader program:\n";
|
||||
cout << GetInfoLog(prog->getID());
|
||||
return status;
|
||||
}
|
||||
|
||||
*progOut = prog;
|
||||
|
||||
return ShaderStatus_OK;
|
||||
|
|
|
@ -67,11 +67,12 @@ class GLProgram
|
|||
GLProgram(int _id);
|
||||
|
||||
void attach(const GLShader&);
|
||||
GLShaderStatus link();
|
||||
|
||||
public:
|
||||
virtual ~GLProgram();
|
||||
|
||||
GLShaderStatus link();
|
||||
|
||||
void use() const;
|
||||
int getID() const { return id; }
|
||||
|
||||
|
@ -82,40 +83,40 @@ class GLProgram
|
|||
};
|
||||
|
||||
|
||||
class FloatShaderProperty
|
||||
class FloatShaderParameter
|
||||
{
|
||||
public:
|
||||
FloatShaderProperty();
|
||||
FloatShaderProperty(int _obj, const char* name);
|
||||
FloatShaderParameter();
|
||||
FloatShaderParameter(int _obj, const char* name);
|
||||
|
||||
FloatShaderProperty& operator=(float);
|
||||
FloatShaderParameter& operator=(float);
|
||||
|
||||
private:
|
||||
int slot;
|
||||
};
|
||||
|
||||
|
||||
class Vec3ShaderProperty
|
||||
class Vec3ShaderParameter
|
||||
{
|
||||
public:
|
||||
Vec3ShaderProperty();
|
||||
Vec3ShaderProperty(int _obj, const char* name);
|
||||
Vec3ShaderParameter();
|
||||
Vec3ShaderParameter(int _obj, const char* name);
|
||||
|
||||
Vec3ShaderProperty& operator=(const Vec3f&);
|
||||
Vec3ShaderProperty& operator=(const Point3f&);
|
||||
Vec3ShaderParameter& operator=(const Vec3f&);
|
||||
Vec3ShaderParameter& operator=(const Point3f&);
|
||||
|
||||
private:
|
||||
int slot;
|
||||
};
|
||||
|
||||
|
||||
class Vec4ShaderProperty
|
||||
class Vec4ShaderParameter
|
||||
{
|
||||
public:
|
||||
Vec4ShaderProperty();
|
||||
Vec4ShaderProperty(int _obj, const char* name);
|
||||
Vec4ShaderParameter();
|
||||
Vec4ShaderParameter(int _obj, const char* name);
|
||||
|
||||
Vec4ShaderProperty& operator=(const Vec4f&);
|
||||
Vec4ShaderParameter& operator=(const Vec4f&);
|
||||
|
||||
private:
|
||||
int slot;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "astro.h"
|
||||
#include "glext.h"
|
||||
#include "vecgl.h"
|
||||
#include "glshader.h"
|
||||
#include "shadermanager.h"
|
||||
#include "spheremesh.h"
|
||||
#include "lodspheremesh.h"
|
||||
#include "model.h"
|
||||
|
@ -94,12 +96,6 @@ static Texture* eclipseShadowTextures[4];
|
|||
static Texture* shadowMaskTexture = NULL;
|
||||
static Texture* penumbraFunctionTexture = NULL;
|
||||
|
||||
static ResourceHandle starTexB = InvalidResource;
|
||||
static ResourceHandle starTexA = InvalidResource;
|
||||
static ResourceHandle starTexG = InvalidResource;
|
||||
static ResourceHandle starTexM = InvalidResource;
|
||||
static ResourceHandle starTexL = InvalidResource;
|
||||
|
||||
static const Color compassColor(0.4f, 0.4f, 1.0f);
|
||||
|
||||
static const float CoronaHeight = 0.2f;
|
||||
|
@ -444,12 +440,6 @@ bool Renderer::init(GLContext* _context,
|
|||
PenumbraFunctionEval,
|
||||
Texture::EdgeClamp);
|
||||
|
||||
starTexB = GetTextureManager()->getHandle(TextureInfo("bstar.jpg", 0));
|
||||
starTexA = GetTextureManager()->getHandle(TextureInfo("astar.jpg", 0));
|
||||
starTexG = GetTextureManager()->getHandle(TextureInfo("gstar.jpg", 0));
|
||||
starTexM = GetTextureManager()->getHandle(TextureInfo("mstar.jpg", 0));
|
||||
starTexL = GetTextureManager()->getHandle(TextureInfo("browndwarf.jpg", 0));
|
||||
|
||||
if (context->extensionSupported("GL_EXT_texture_cube_map"))
|
||||
{
|
||||
// normalizationTex = CreateNormalizationCubeMap(64);
|
||||
|
@ -3482,6 +3472,117 @@ static void renderSphere_FP_VP(const RenderInfo& ri,
|
|||
}
|
||||
|
||||
|
||||
static void renderSphere_GLSL(const RenderInfo& ri,
|
||||
const LightingState& ls,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
{
|
||||
Texture* textures[4] = { NULL, NULL, NULL, NULL };
|
||||
unsigned int nTextures = 0;
|
||||
VertexProcessor* vproc = context.getVertexProcessor();
|
||||
assert(vproc != NULL);
|
||||
|
||||
bool perFragmentLighting = (ri.bumpTex != NULL);
|
||||
|
||||
vproc->disable();
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
ShaderProperties shadprop;
|
||||
shadprop.nLights = ls.nLights;
|
||||
|
||||
// Set up the textures used by this object
|
||||
shadprop.texUsage = ShaderProperties::DiffuseTexture;
|
||||
textures[nTextures++] = ri.baseTex;
|
||||
|
||||
if (ri.bumpTex != NULL)
|
||||
{
|
||||
shadprop.texUsage |= ShaderProperties::NormalTexture;
|
||||
textures[nTextures++] = ri.bumpTex;
|
||||
}
|
||||
|
||||
if (ri.specularColor != Color::Black)
|
||||
{
|
||||
shadprop.lightModel = ShaderProperties::SpecularModel;
|
||||
if (ri.glossTex == NULL)
|
||||
{
|
||||
shadprop.texUsage |= ShaderProperties::SpecularInDiffuseAlpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadprop.texUsage |= ShaderProperties::SpecularTexture;
|
||||
textures[nTextures++] = ri.glossTex;
|
||||
}
|
||||
}
|
||||
|
||||
if (ri.nightTex != NULL)
|
||||
{
|
||||
shadprop.texUsage |= ShaderProperties::NightTexture;
|
||||
textures[nTextures++] = ri.nightTex;
|
||||
}
|
||||
|
||||
// Get a shader for the current rendering configuration
|
||||
CelestiaGLProgram* prog = GetShaderManager().getShader(shadprop);
|
||||
if (prog == NULL)
|
||||
return;
|
||||
|
||||
prog->use();
|
||||
|
||||
Vec3f diffuseColor(ri.color.red(),
|
||||
ri.color.green(),
|
||||
ri.color.blue());
|
||||
Vec3f specularColor(ri.specularColor.red(),
|
||||
ri.specularColor.green(),
|
||||
ri.specularColor.blue());
|
||||
|
||||
for (unsigned int i = 0; i < ls.nLights; i++)
|
||||
{
|
||||
const DirectionalLight& light = ls.lights[i];
|
||||
|
||||
Vec3f lightColor = Vec3f(light.color.red(),
|
||||
light.color.green(),
|
||||
light.color.blue()) * light.irradiance;
|
||||
prog->lights[i].direction = light.direction_obj;
|
||||
|
||||
if (perFragmentLighting)
|
||||
{
|
||||
prog->fragLightColor[i] = Vec3f(lightColor.x * diffuseColor.x,
|
||||
lightColor.y * diffuseColor.y,
|
||||
lightColor.z * diffuseColor.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
prog->lights[i].diffuse = Vec3f(lightColor.x * diffuseColor.x,
|
||||
lightColor.y * diffuseColor.y,
|
||||
lightColor.z * diffuseColor.z);
|
||||
}
|
||||
prog->lights[i].specular = Vec3f(lightColor.x * specularColor.x,
|
||||
lightColor.y * specularColor.y,
|
||||
lightColor.z * specularColor.z);
|
||||
|
||||
Vec3f halfAngle_obj = ri.eyeDir_obj + light.direction_obj;
|
||||
if (halfAngle_obj.length() != 0.0f)
|
||||
halfAngle_obj.normalize();
|
||||
prog->lights[i].halfVector = halfAngle_obj;
|
||||
}
|
||||
|
||||
prog->shininess = ri.specularPower;
|
||||
prog->ambientColor = Vec3f(ri.ambientColor.red(), ri.ambientColor.green(),
|
||||
ri.ambientColor.blue());
|
||||
|
||||
glColor(ri.color);
|
||||
|
||||
unsigned int attributes = LODSphereMesh::Normals;
|
||||
if (ri.bumpTex != NULL)
|
||||
attributes |= LODSphereMesh::Tangents;
|
||||
lodSphere->render(context,
|
||||
attributes,
|
||||
frustum, ri.pixWidth,
|
||||
textures[0], textures[1], textures[2], textures[3]);
|
||||
|
||||
glx::glUseProgramObjectARB(0);
|
||||
}
|
||||
|
||||
|
||||
static void texGenPlane(GLenum coord, GLenum mode, const Vec4f& plane)
|
||||
{
|
||||
float f[4];
|
||||
|
@ -4634,6 +4735,10 @@ void Renderer::renderObject(Point3f pos,
|
|||
{
|
||||
switch (context->getRenderPath())
|
||||
{
|
||||
case GLContext::GLPath_GLSL:
|
||||
renderSphere_GLSL(ri, ls, viewFrustum, *context);
|
||||
break;
|
||||
|
||||
case GLContext::GLPath_NV30:
|
||||
renderSphere_FP_VP(ri, viewFrustum, *context);
|
||||
break;
|
||||
|
@ -5173,39 +5278,7 @@ void Renderer::renderStar(const Star& star,
|
|||
RenderProperties rp;
|
||||
|
||||
surface.color = color;
|
||||
#if 0
|
||||
ResourceHandle tex;
|
||||
|
||||
switch (star.getStellarClass().getSpectralClass())
|
||||
{
|
||||
case StellarClass::Spectral_O:
|
||||
case StellarClass::Spectral_B:
|
||||
tex = starTexB;
|
||||
break;
|
||||
case StellarClass::Spectral_A:
|
||||
case StellarClass::Spectral_F:
|
||||
tex = starTexA;
|
||||
break;
|
||||
case StellarClass::Spectral_G:
|
||||
case StellarClass::Spectral_K:
|
||||
tex = starTexG;
|
||||
break;
|
||||
case StellarClass::Spectral_M:
|
||||
case StellarClass::Spectral_R:
|
||||
case StellarClass::Spectral_S:
|
||||
case StellarClass::Spectral_N:
|
||||
case StellarClass::Spectral_C:
|
||||
tex = starTexM;
|
||||
break;
|
||||
case StellarClass::Spectral_L:
|
||||
case StellarClass::Spectral_T:
|
||||
tex = starTexL;
|
||||
break;
|
||||
default:
|
||||
tex = starTexA;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
MultiResTexture mtex = star.getTexture();
|
||||
if (mtex.tex[textureResolution] != InvalidResource)
|
||||
{
|
||||
|
|
|
@ -113,7 +113,8 @@ CelestiaGLProgram::CelestiaGLProgram(GLProgram& _program,
|
|||
const ShaderProperties& props) :
|
||||
program(&_program)
|
||||
{
|
||||
initProperties(props);
|
||||
initParameters(props);
|
||||
initSamplers(props);
|
||||
};
|
||||
|
||||
|
||||
|
@ -123,24 +124,24 @@ CelestiaGLProgram::~CelestiaGLProgram()
|
|||
}
|
||||
|
||||
|
||||
FloatShaderProperty
|
||||
CelestiaGLProgram::floatProperty(const string& propertyName)
|
||||
FloatShaderParameter
|
||||
CelestiaGLProgram::floatParam(const string& paramName)
|
||||
{
|
||||
return FloatShaderProperty(program->getID(), propertyName.c_str());
|
||||
return FloatShaderParameter(program->getID(), paramName.c_str());
|
||||
}
|
||||
|
||||
|
||||
Vec3ShaderProperty
|
||||
CelestiaGLProgram::vec3Property(const string& propertyName)
|
||||
Vec3ShaderParameter
|
||||
CelestiaGLProgram::vec3Param(const string& paramName)
|
||||
{
|
||||
return Vec3ShaderProperty(program->getID(), propertyName.c_str());
|
||||
return Vec3ShaderParameter(program->getID(), paramName.c_str());
|
||||
}
|
||||
|
||||
|
||||
Vec4ShaderProperty
|
||||
CelestiaGLProgram::vec4Property(const string& propertyName)
|
||||
Vec4ShaderParameter
|
||||
CelestiaGLProgram::vec4Param(const string& paramName)
|
||||
{
|
||||
return Vec4ShaderProperty(program->getID(), propertyName.c_str());
|
||||
return Vec4ShaderParameter(program->getID(), paramName.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,20 +154,69 @@ LightProperty(unsigned int i, char* property)
|
|||
}
|
||||
|
||||
|
||||
static string
|
||||
FragLightProperty(unsigned int i, char* property)
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, "light%s%d", property, i);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CelestiaGLProgram::initProperties(const ShaderProperties& props)
|
||||
CelestiaGLProgram::initParameters(const ShaderProperties& props)
|
||||
{
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
lights[i].direction = vec3Property(LightProperty(i, "direction"));
|
||||
lights[i].diffuse = vec3Property(LightProperty(i, "diffuse"));
|
||||
lights[i].specular = vec3Property(LightProperty(i, "specular"));
|
||||
lights[i].halfVector = vec3Property(LightProperty(i, "halfVector"));
|
||||
lights[i].direction = vec3Param(LightProperty(i, "direction"));
|
||||
lights[i].diffuse = vec3Param(LightProperty(i, "diffuse"));
|
||||
lights[i].specular = vec3Param(LightProperty(i, "specular"));
|
||||
lights[i].halfVector = vec3Param(LightProperty(i, "halfVector"));
|
||||
|
||||
fragLightColor[i] = vec3Param(FragLightProperty(i, "color"));
|
||||
}
|
||||
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
{
|
||||
shininess = floatProperty("shininess");
|
||||
shininess = floatParam("shininess");
|
||||
}
|
||||
|
||||
ambientColor = vec3Param("ambientColor");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CelestiaGLProgram::initSamplers(const ShaderProperties& props)
|
||||
{
|
||||
program->use();
|
||||
|
||||
unsigned int nSamplers = 0;
|
||||
if (props.texUsage & ShaderProperties::DiffuseTexture)
|
||||
{
|
||||
int slot = glx::glGetUniformLocationARB(program->getID(), "diffTex");
|
||||
if (slot != -1)
|
||||
glx::glUniform1iARB(slot, nSamplers++);
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::SpecularTexture)
|
||||
{
|
||||
int slot = glx::glGetUniformLocationARB(program->getID(), "specTex");
|
||||
if (slot != -1)
|
||||
glx::glUniform1iARB(slot, nSamplers++);
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
int slot = glx::glGetUniformLocationARB(program->getID(), "normTex");
|
||||
if (slot != -1)
|
||||
glx::glUniform1iARB(slot, nSamplers++);
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
int slot = glx::glGetUniformLocationARB(program->getID(), "nightTex");
|
||||
if (slot != -1)
|
||||
glx::glUniform1iARB(slot, nSamplers++);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,14 +242,48 @@ DeclareLights(const ShaderProperties& props)
|
|||
|
||||
|
||||
static string
|
||||
DirectionalLight(unsigned int i)
|
||||
TexCoord2D(unsigned int i)
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, "gl_MultiTexCoord%d.st", i);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
static string
|
||||
LightDir(unsigned int i)
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "lightDir%d", i);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
static string
|
||||
DirectionalLight(unsigned int i, const ShaderProperties& props)
|
||||
{
|
||||
string source;
|
||||
|
||||
source += "nDotVP = max(0.0, dot(gl_Normal, vec3(" +
|
||||
LightProperty(i, "direction") + ")));\n";
|
||||
source += "nDotVP = max(0.0, dot(gl_Normal, " +
|
||||
LightProperty(i, "direction") + "));\n";
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
{
|
||||
source += "nDotHV = max(0.0, dot(gl_Normal, " +
|
||||
LightProperty(i, "halfVector") + "));\n";
|
||||
}
|
||||
|
||||
source += "diff += vec4(" + LightProperty(i, "diffuse") + " * nDotVP, 1);\n";
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
{
|
||||
source += "spec += vec4(" + LightProperty(i, "specular") +
|
||||
" * (pow(nDotHV, shininess) * nDotVP), 1);\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
source += "totalLight += nDotVP;\n";
|
||||
}
|
||||
|
||||
|
||||
return source;
|
||||
}
|
||||
|
@ -231,12 +315,30 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
source += DeclareLights(props);
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
source += "uniform float shininess;\n";
|
||||
source += "uniform vec3 ambientColor;\n";
|
||||
|
||||
source += "varying vec4 diff;\n";
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
source += "varying vec4 spec;\n";
|
||||
|
||||
if (props.texUsage & ShaderProperties::DiffuseTexture)
|
||||
source += "varying vec2 diffTexCoord;\n";
|
||||
if (props.texUsage & ShaderProperties::SpecularTexture)
|
||||
source += "varying vec2 specTexCoord;\n";
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
source += "varying vec2 normTexCoord;\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
source += "varying vec3 " + LightDir(i) + ";\n";
|
||||
}
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
source += "varying vec2 nightTexCoord;\n";
|
||||
source += "varying float totalLight;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
source += "attribute vec3 tangent;\n";
|
||||
|
||||
source += "\nvoid main(void)\n{\n";
|
||||
source += "float nDotVP;\n";
|
||||
|
@ -245,18 +347,53 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
source += "float nDotHV;\n";
|
||||
}
|
||||
|
||||
source += "diff = 0;\n";
|
||||
source += "diff = vec4(ambientColor, 1);\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
source += DirectionalLightSpecular(i);
|
||||
else
|
||||
source += DirectionalLight(i);
|
||||
source += DirectionalLight(i, props);
|
||||
}
|
||||
|
||||
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
// Output the blend factor for night lights textures
|
||||
source += "totalLight = 1 - totalLight;\n";
|
||||
source += "totalLight = totalLight * totalLight * totalLight * totalLight;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
source += "vec3 bitangent = cross(gl_Normal, tangent);\n";
|
||||
for (unsigned int j = 0; j < props.nLights; j++)
|
||||
{
|
||||
source += LightDir(j) + ".x = dot(tangent, " + LightProperty(j, "direction") + ");\n";
|
||||
source += LightDir(j) + ".y = dot(-bitangent, " + LightProperty(j, "direction") + ");\n";
|
||||
source += LightDir(j) + ".z = dot(gl_Normal, " + LightProperty(j, "direction") + ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int nTexCoords = 0;
|
||||
if (props.texUsage & ShaderProperties::DiffuseTexture)
|
||||
{
|
||||
source += "diffTexCoord = vec2(gl_MultiTexCoord0);\n";
|
||||
source += "diffTexCoord = " + TexCoord2D(nTexCoords) + ";\n";
|
||||
nTexCoords++;
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
source += "normTexCoord = " + TexCoord2D(nTexCoords) + ";\n";
|
||||
nTexCoords++;
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::SpecularTexture)
|
||||
{
|
||||
source += "specTexCoord = " + TexCoord2D(nTexCoords) + ";\n";
|
||||
nTexCoords++;
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
source += "nightTexCoord = " + TexCoord2D(nTexCoords) + ";\n";
|
||||
nTexCoords++;
|
||||
}
|
||||
|
||||
source += "gl_Position = ftransform();\n";
|
||||
|
@ -278,8 +415,19 @@ GLFragmentShader*
|
|||
ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
||||
{
|
||||
string source;
|
||||
bool perFragmentLighting = ((props.texUsage & ShaderProperties::NormalTexture) != 0);
|
||||
|
||||
if (perFragmentLighting)
|
||||
{
|
||||
source += "vec4 diff = vec4(0, 0, 0, 1);\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
source += "uniform vec3 " + FragLightProperty(i, "color") + ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
source += "varying vec4 diff;\n";
|
||||
}
|
||||
|
||||
source += "varying vec4 diff;\n";
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
source += "varying vec4 spec;\n";
|
||||
|
||||
|
@ -289,9 +437,42 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
source += "uniform sampler2D diffTex;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
source += "varying vec2 normTexCoord;\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
source += "varying vec3 " + LightDir(i) + ";\n";
|
||||
source += "uniform sampler2D normTex;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::SpecularTexture)
|
||||
{
|
||||
source += "varying vec2 specTexCoord;\n";
|
||||
source += "uniform sampler2D specTex;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
source += "varying vec2 nightTexCoord;\n";
|
||||
source += "uniform sampler2D nightTex;\n";
|
||||
source += "varying float totalLight;\n";
|
||||
}
|
||||
|
||||
source += "\nvoid main(void)\n{\n";
|
||||
source += "vec4 color;\n";
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
source += "vec3 n = texture2D(normTex, normTexCoord.st).xyz * 2 - vec3(1, 1, 1);\n";
|
||||
source += "float l;\n";
|
||||
for (unsigned i = 0; i < props.nLights; i++)
|
||||
{
|
||||
// Bump mapping with self shadowing
|
||||
source += "l = max(0, dot(" + LightDir(i) + ", n)) * clamp(" + LightDir(i) + ".z * 8, 0, 1);\n";
|
||||
source += "diff += vec4(l * " + FragLightProperty(i, "color") + ", 0);\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::DiffuseTexture)
|
||||
source += "color = texture2D(diffTex, diffTexCoord.st);\n";
|
||||
else
|
||||
|
@ -308,6 +489,14 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
{
|
||||
source += "gl_FragColor = color * diff;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NightTexture)
|
||||
{
|
||||
source += "gl_FragColor += texture2D(nightTex, nightTexCoord.st) * totalLight;\n";
|
||||
}
|
||||
|
||||
//source += "gl_FragColor = vec4(lightcolor0, 1);\n";
|
||||
|
||||
source += "}\n";
|
||||
|
||||
*logFile << "Fragment shader source:\n";
|
||||
|
@ -333,6 +522,16 @@ ShaderManager::buildProgram(const ShaderProperties& props)
|
|||
if (vs != NULL && fs != NULL)
|
||||
{
|
||||
status = GLShaderLoader::CreateProgram(*vs, *fs, &prog);
|
||||
if (status == ShaderStatus_OK)
|
||||
{
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
// Tangents always in attribute 6 (should be a constant
|
||||
// someplace)
|
||||
glx::glBindAttribLocationARB(prog->getID(), 6, "tangent");
|
||||
}
|
||||
status = prog->link();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -44,10 +44,10 @@ class ShaderProperties
|
|||
static const int MaxShaderLights = 4;
|
||||
struct CelestiaGLProgramLight
|
||||
{
|
||||
Vec3ShaderProperty direction;
|
||||
Vec3ShaderProperty diffuse;
|
||||
Vec3ShaderProperty specular;
|
||||
Vec3ShaderProperty halfVector;
|
||||
Vec3ShaderParameter direction;
|
||||
Vec3ShaderParameter diffuse;
|
||||
Vec3ShaderParameter specular;
|
||||
Vec3ShaderParameter halfVector;
|
||||
};
|
||||
|
||||
class CelestiaGLProgram
|
||||
|
@ -60,14 +60,18 @@ class CelestiaGLProgram
|
|||
|
||||
public:
|
||||
CelestiaGLProgramLight lights[MaxShaderLights];
|
||||
Vec3ShaderProperty eyePosition;
|
||||
FloatShaderProperty shininess;
|
||||
Vec3ShaderParameter fragLightColor[MaxShaderLights];
|
||||
Vec3ShaderParameter eyePosition;
|
||||
FloatShaderParameter shininess;
|
||||
Vec3ShaderParameter ambientColor;
|
||||
|
||||
private:
|
||||
void initProperties(const ShaderProperties&);
|
||||
FloatShaderProperty floatProperty(const std::string&);
|
||||
Vec3ShaderProperty vec3Property(const std::string&);
|
||||
Vec4ShaderProperty vec4Property(const std::string&);
|
||||
void initParameters(const ShaderProperties&);
|
||||
void initSamplers(const ShaderProperties&);
|
||||
|
||||
FloatShaderParameter floatParam(const std::string&);
|
||||
Vec3ShaderParameter vec3Param(const std::string&);
|
||||
Vec4ShaderParameter vec4Param(const std::string&);
|
||||
|
||||
GLProgram* program;
|
||||
};
|
||||
|
|
|
@ -1369,6 +1369,9 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers)
|
|||
case GLContext::GLPath_NV30:
|
||||
flash("Render path: NVIDIA GeForce FX");
|
||||
break;
|
||||
case GLContext::GLPath_GLSL:
|
||||
flash("Render path: OpenGL 2.0");
|
||||
break;
|
||||
}
|
||||
context->setRenderPath(newPath);
|
||||
notifyWatchers(RenderFlagsChanged);
|
||||
|
|
Loading…
Reference in New Issue