mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-05 03:15:07 -04:00
Added support for shadow maps + shaders
This commit is contained in:
parent
5da0172878
commit
0400248b37
@ -64,7 +64,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
self.sfxActive = self.config.GetBool('audio-sfx-active', 1)
|
self.sfxActive = self.config.GetBool('audio-sfx-active', 1)
|
||||||
self.musicActive = self.config.GetBool('audio-music-active', 1)
|
self.musicActive = self.config.GetBool('audio-music-active', 1)
|
||||||
self.wantFog = self.config.GetBool('want-fog', 1)
|
self.wantFog = self.config.GetBool('want-fog', 1)
|
||||||
self.wantRender2dp = self.config.GetBool('want-render2dp', 0)
|
self.wantRender2dp = self.config.GetBool('want-render2dp', 1)
|
||||||
|
|
||||||
self.screenshotExtension = self.config.GetString('screenshot-extension', 'jpg')
|
self.screenshotExtension = self.config.GetString('screenshot-extension', 'jpg')
|
||||||
self.musicManager = None
|
self.musicManager = None
|
||||||
@ -117,12 +117,14 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
self.drive = None
|
self.drive = None
|
||||||
self.trackball = None
|
self.trackball = None
|
||||||
self.cam = None
|
self.cam = None
|
||||||
self.camList = []
|
self.cam2d = None
|
||||||
self.camNode = None
|
self.cam2dp = None
|
||||||
self.camLens = None
|
|
||||||
self.camera = None
|
self.camera = None
|
||||||
self.camera2d = None
|
self.camera2d = None
|
||||||
self.camera2dp = None
|
self.camera2dp = None
|
||||||
|
self.camList = []
|
||||||
|
self.camNode = None
|
||||||
|
self.camLens = None
|
||||||
self.camFrustumVis = None
|
self.camFrustumVis = None
|
||||||
|
|
||||||
# This is used for syncing multiple PCs in a distributed cluster
|
# This is used for syncing multiple PCs in a distributed cluster
|
||||||
@ -458,6 +460,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
# preserve it for reopening the window.
|
# preserve it for reopening the window.
|
||||||
if cam == self.cam:
|
if cam == self.cam:
|
||||||
self.cam = None
|
self.cam = None
|
||||||
|
if cam == self.cam2d:
|
||||||
|
self.cam2d = None
|
||||||
|
if cam == self.cam2dp:
|
||||||
|
self.cam2dp = None
|
||||||
cam.removeNode()
|
cam.removeNode()
|
||||||
|
|
||||||
# Now we can actually close the window.
|
# Now we can actually close the window.
|
||||||
@ -813,6 +819,9 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
camera2d = self.camera2d.attachNewNode(cam2dNode)
|
camera2d = self.camera2d.attachNewNode(cam2dNode)
|
||||||
dr.setCamera(camera2d)
|
dr.setCamera(camera2d)
|
||||||
|
|
||||||
|
if self.cam2d == None:
|
||||||
|
self.cam2d = camera2d
|
||||||
|
|
||||||
return camera2d
|
return camera2d
|
||||||
|
|
||||||
def makeCamera2dp(self, win, sort = 20,
|
def makeCamera2dp(self, win, sort = 20,
|
||||||
@ -847,6 +856,9 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
camera2dp = self.camera2dp.attachNewNode(cam2dNode)
|
camera2dp = self.camera2dp.attachNewNode(cam2dNode)
|
||||||
dr.setCamera(camera2dp)
|
dr.setCamera(camera2dp)
|
||||||
|
|
||||||
|
if self.cam2dp == None:
|
||||||
|
self.cam2dp = camera2dp
|
||||||
|
|
||||||
return camera2dp
|
return camera2dp
|
||||||
|
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ create_texture_card_vdata(int x, int y)
|
|||||||
float xhi = (x * 1.0f) / xru;
|
float xhi = (x * 1.0f) / xru;
|
||||||
float yhi = (y * 1.0f) / yru;
|
float yhi = (y * 1.0f) / yru;
|
||||||
|
|
||||||
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3n3cpt2();
|
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3n3t2();
|
||||||
|
|
||||||
PT(GeomVertexData) vdata = new GeomVertexData
|
PT(GeomVertexData) vdata = new GeomVertexData
|
||||||
("card", format, Geom::UH_static);
|
("card", format, Geom::UH_static);
|
||||||
|
@ -470,6 +470,28 @@ get_supports_render_texture() const {
|
|||||||
return _supports_render_texture;
|
return _supports_render_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::get_supports_depth_texture
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if this particular GSG supports
|
||||||
|
// textures whose format is F_depth_component.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GraphicsStateGuardian::
|
||||||
|
get_supports_depth_texture() const {
|
||||||
|
return _supports_depth_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::get_supports_shadow_filter
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if this particular GSG supports
|
||||||
|
// the filter mode FT_shadow for depth textures.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GraphicsStateGuardian::
|
||||||
|
get_supports_shadow_filter() const {
|
||||||
|
return _supports_shadow_filter;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::get_color_scale_via_lighting
|
// Function: GraphicsStateGuardian::get_color_scale_via_lighting
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -145,7 +145,8 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
|||||||
_supports_multisample = false;
|
_supports_multisample = false;
|
||||||
_supports_generate_mipmap = false;
|
_supports_generate_mipmap = false;
|
||||||
_supports_render_texture = false;
|
_supports_render_texture = false;
|
||||||
|
_supports_depth_texture = false;
|
||||||
|
_supports_shadow_filter = false;
|
||||||
_supported_geom_rendering = 0;
|
_supported_geom_rendering = 0;
|
||||||
|
|
||||||
// If this is true, then we can apply a color and/or color scale by
|
// If this is true, then we can apply a color and/or color scale by
|
||||||
|
@ -109,6 +109,8 @@ PUBLISHED:
|
|||||||
virtual bool get_supports_multisample() const;
|
virtual bool get_supports_multisample() const;
|
||||||
INLINE bool get_supports_generate_mipmap() const;
|
INLINE bool get_supports_generate_mipmap() const;
|
||||||
INLINE bool get_supports_render_texture() const;
|
INLINE bool get_supports_render_texture() const;
|
||||||
|
INLINE bool get_supports_depth_texture() const;
|
||||||
|
INLINE bool get_supports_shadow_filter() const;
|
||||||
|
|
||||||
virtual int get_supported_geom_rendering() const;
|
virtual int get_supported_geom_rendering() const;
|
||||||
|
|
||||||
@ -355,6 +357,8 @@ protected:
|
|||||||
bool _supports_multisample;
|
bool _supports_multisample;
|
||||||
bool _supports_generate_mipmap;
|
bool _supports_generate_mipmap;
|
||||||
bool _supports_render_texture;
|
bool _supports_render_texture;
|
||||||
|
bool _supports_depth_texture;
|
||||||
|
bool _supports_shadow_filter;
|
||||||
int _supported_geom_rendering;
|
int _supported_geom_rendering;
|
||||||
bool _color_scale_via_lighting;
|
bool _color_scale_via_lighting;
|
||||||
|
|
||||||
|
@ -518,6 +518,16 @@ reset() {
|
|||||||
_glClientActiveTexture = null_glActiveTexture;
|
_glClientActiveTexture = null_glActiveTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_extension("GL_ARB_depth_texture")) {
|
||||||
|
_supports_depth_texture = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_supports_depth_texture &&
|
||||||
|
has_extension("GL_ARB_shadow") &&
|
||||||
|
has_extension("GL_ARB_fragment_program_shadow")) {
|
||||||
|
_supports_shadow_filter = true;
|
||||||
|
}
|
||||||
|
|
||||||
_supports_texture_combine =
|
_supports_texture_combine =
|
||||||
has_extension("GL_ARB_texture_env_combine") || is_at_least_version(1, 3);
|
has_extension("GL_ARB_texture_env_combine") || is_at_least_version(1, 3);
|
||||||
_supports_texture_saved_result =
|
_supports_texture_saved_result =
|
||||||
@ -2041,7 +2051,7 @@ release_geom(GeomContext *gc) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
ShaderContext *CLP(GraphicsStateGuardian)::
|
ShaderContext *CLP(GraphicsStateGuardian)::
|
||||||
prepare_shader(ShaderExpansion *se) {
|
prepare_shader(ShaderExpansion *se) {
|
||||||
CLP(ShaderContext) *result = new CLP(ShaderContext)(se);
|
CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
|
||||||
if (result->valid()) return result;
|
if (result->valid()) return result;
|
||||||
delete result;
|
delete result;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -3901,6 +3911,8 @@ get_texture_filter_type(Texture::FilterType ft, bool ignore_mipmaps) {
|
|||||||
case Texture::FT_nearest_mipmap_linear:
|
case Texture::FT_nearest_mipmap_linear:
|
||||||
case Texture::FT_linear_mipmap_linear:
|
case Texture::FT_linear_mipmap_linear:
|
||||||
return GL_LINEAR;
|
return GL_LINEAR;
|
||||||
|
case Texture::FT_shadow:
|
||||||
|
return GL_LINEAR;
|
||||||
case Texture::FT_invalid:
|
case Texture::FT_invalid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3919,6 +3931,8 @@ get_texture_filter_type(Texture::FilterType ft, bool ignore_mipmaps) {
|
|||||||
return GL_NEAREST_MIPMAP_LINEAR;
|
return GL_NEAREST_MIPMAP_LINEAR;
|
||||||
case Texture::FT_linear_mipmap_linear:
|
case Texture::FT_linear_mipmap_linear:
|
||||||
return GL_LINEAR_MIPMAP_LINEAR;
|
return GL_LINEAR_MIPMAP_LINEAR;
|
||||||
|
case Texture::FT_shadow:
|
||||||
|
return GL_LINEAR;
|
||||||
case Texture::FT_invalid:
|
case Texture::FT_invalid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5044,7 +5058,7 @@ update_standard_texture_bindings()
|
|||||||
|
|
||||||
GLP(MatrixMode)(GL_TEXTURE);
|
GLP(MatrixMode)(GL_TEXTURE);
|
||||||
if (_target._tex_matrix->has_stage(stage)) {
|
if (_target._tex_matrix->has_stage(stage)) {
|
||||||
GLP(LoadMatrixf)(_state._tex_matrix->get_mat(stage).get_data());
|
GLP(LoadMatrixf)(_target._tex_matrix->get_mat(stage).get_data());
|
||||||
} else {
|
} else {
|
||||||
GLP(LoadIdentity)();
|
GLP(LoadIdentity)();
|
||||||
}
|
}
|
||||||
@ -5444,6 +5458,19 @@ specify_texture(Texture *tex) {
|
|||||||
GLP(TexParameteri)(target, GL_TEXTURE_MAG_FILTER,
|
GLP(TexParameteri)(target, GL_TEXTURE_MAG_FILTER,
|
||||||
get_texture_filter_type(magfilter, true));
|
get_texture_filter_type(magfilter, true));
|
||||||
|
|
||||||
|
if (_supports_shadow_filter) {
|
||||||
|
if (tex->get_format() == Texture::F_depth_component) {
|
||||||
|
if ((tex->get_magfilter() == Texture::FT_shadow) ||
|
||||||
|
(tex->get_minfilter() == Texture::FT_shadow)) {
|
||||||
|
GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||||
|
GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_GEQUAL);
|
||||||
|
} else {
|
||||||
|
GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
|
||||||
|
GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
|||||||
// Description: xyz
|
// Description: xyz
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CLP(ShaderContext)::
|
CLP(ShaderContext)::
|
||||||
CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) {
|
CLP(ShaderContext)(ShaderExpansion *s, GSG *gsg) : ShaderContext(s) {
|
||||||
string header;
|
string header;
|
||||||
s->parse_init();
|
s->parse_init();
|
||||||
s->parse_line(header, true, true);
|
s->parse_line(header, true, true);
|
||||||
@ -73,7 +73,7 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compile the program.
|
// Compile the program.
|
||||||
try_cg_compile(s);
|
try_cg_compile(s, gsg);
|
||||||
cerr << _cg_errors;
|
cerr << _cg_errors;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ parse_cg_profile(const string &id, bool vertex)
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
bool CLP(ShaderContext)::
|
bool CLP(ShaderContext)::
|
||||||
try_cg_compile(ShaderExpansion *s)
|
try_cg_compile(ShaderExpansion *s, GSG *gsg)
|
||||||
{
|
{
|
||||||
_cg_errors = "";
|
_cg_errors = "";
|
||||||
|
|
||||||
@ -176,6 +176,78 @@ try_cg_compile(ShaderExpansion *s)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following code is present to work around a bug in the Cg compiler.
|
||||||
|
// It does not generate correct code for shadow map lookups when using arbfp1.
|
||||||
|
// This is a particularly onerous limitation, given that arbfp1 is the only
|
||||||
|
// Cg target that works on radeons. I suspect this is an intentional
|
||||||
|
// omission on nvidia's part. The following code fetches the output listing,
|
||||||
|
// detects the error, repairs the code, and resumbits the repaired code to Cg.
|
||||||
|
if ((_cg_profile[1] == CG_PROFILE_ARBFP1) && (gsg->_supports_shadow_filter)) {
|
||||||
|
bool shadowunit[32];
|
||||||
|
bool anyshadow = false;
|
||||||
|
memset(shadowunit, 0, sizeof(shadowunit));
|
||||||
|
vector_string lines;
|
||||||
|
tokenize(cgGetProgramString(_cg_program[1], CG_COMPILED_PROGRAM), lines, "\n");
|
||||||
|
// figure out which texture units contain shadow maps.
|
||||||
|
for (int lineno=0; lineno<(int)lines.size(); lineno++) {
|
||||||
|
if (lines[lineno].compare(0,21,"#var sampler2DSHADOW ")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vector_string fields;
|
||||||
|
tokenize(lines[lineno], fields, ":");
|
||||||
|
if (fields.size()!=5) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vector_string words;
|
||||||
|
tokenize(trim(fields[2]), words, " ");
|
||||||
|
if (words.size()!=2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int unit = atoi(words[1].c_str());
|
||||||
|
if ((unit < 0)||(unit >= 32)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anyshadow = true;
|
||||||
|
shadowunit[unit] = true;
|
||||||
|
}
|
||||||
|
// modify all TEX statements that use the relevant texture units.
|
||||||
|
if (anyshadow) {
|
||||||
|
for (int lineno=0; lineno<(int)lines.size(); lineno++) {
|
||||||
|
if (lines[lineno].compare(0,4,"TEX ")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vector_string fields;
|
||||||
|
tokenize(lines[lineno], fields, ",");
|
||||||
|
if ((fields.size()!=4)||(trim(fields[3]) != "2D;")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vector_string texunitf;
|
||||||
|
tokenize(trim(fields[2]), texunitf, "[]");
|
||||||
|
if ((texunitf.size()!=3)||(texunitf[0] != "texture")||(texunitf[2]!="")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int unit = atoi(texunitf[1].c_str());
|
||||||
|
if ((unit < 0) || (unit >= 32) || (shadowunit[unit]==false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lines[lineno] = fields[0]+","+fields[1]+","+fields[2]+", SHADOW2D;";
|
||||||
|
}
|
||||||
|
string result = "!!ARBfp1.0\nOPTION ARB_fragment_program_shadow;\n";
|
||||||
|
for (int lineno=1; lineno<(int)lines.size(); lineno++) {
|
||||||
|
result += (lines[lineno] + "\n");
|
||||||
|
}
|
||||||
|
cgDestroyProgram(_cg_program[1]);
|
||||||
|
_cg_program[1] =
|
||||||
|
cgCreateProgram(_cg_context, CG_OBJECT, result.c_str(),
|
||||||
|
_cg_profile[1], "fshader", (const char**)NULL);
|
||||||
|
print_cg_compile_errors(s->get_name(), _cg_context);
|
||||||
|
if (_cg_program[SHADER_type_frag]==0) {
|
||||||
|
release_resources();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
CGparameter parameter;
|
CGparameter parameter;
|
||||||
for (int progindex=0; progindex<2; progindex++) {
|
for (int progindex=0; progindex<2; progindex++) {
|
||||||
|
@ -34,10 +34,11 @@ class CLP(GraphicsStateGuardian);
|
|||||||
|
|
||||||
class EXPCL_GL CLP(ShaderContext): public ShaderContext {
|
class EXPCL_GL CLP(ShaderContext): public ShaderContext {
|
||||||
public:
|
public:
|
||||||
CLP(ShaderContext)(ShaderExpansion *s);
|
|
||||||
~CLP(ShaderContext)();
|
|
||||||
typedef CLP(GraphicsStateGuardian) GSG;
|
typedef CLP(GraphicsStateGuardian) GSG;
|
||||||
|
|
||||||
|
CLP(ShaderContext)(ShaderExpansion *s, GSG *gsg);
|
||||||
|
~CLP(ShaderContext)();
|
||||||
|
|
||||||
INLINE bool valid(void);
|
INLINE bool valid(void);
|
||||||
void bind(GSG *gsg);
|
void bind(GSG *gsg);
|
||||||
void unbind();
|
void unbind();
|
||||||
@ -116,7 +117,7 @@ private:
|
|||||||
vector <ShaderTransBind> _cg_parameter_bind;
|
vector <ShaderTransBind> _cg_parameter_bind;
|
||||||
vector <ShaderVarying> _cg_varying;
|
vector <ShaderVarying> _cg_varying;
|
||||||
|
|
||||||
bool try_cg_compile(ShaderExpansion *s);
|
bool try_cg_compile(ShaderExpansion *s, GSG *gsg);
|
||||||
void bind_cg_transform(const ShaderTransBind &stb,
|
void bind_cg_transform(const ShaderTransBind &stb,
|
||||||
CLP(GraphicsStateGuardian) *gsg);
|
CLP(GraphicsStateGuardian) *gsg);
|
||||||
void suggest_cg_profile(const string &vpro, const string &fpro);
|
void suggest_cg_profile(const string &vpro, const string &fpro);
|
||||||
|
@ -1367,7 +1367,8 @@ string_filter_type(const string &string) {
|
|||||||
return FT_linear_mipmap_linear;
|
return FT_linear_mipmap_linear;
|
||||||
} else if (cmp_nocase_uh(string, "mipmap") == 0) {
|
} else if (cmp_nocase_uh(string, "mipmap") == 0) {
|
||||||
return FT_linear_mipmap_linear;
|
return FT_linear_mipmap_linear;
|
||||||
|
} else if (cmp_nocase_uh(string, "shadow") == 0) {
|
||||||
|
return FT_shadow;
|
||||||
} else {
|
} else {
|
||||||
return FT_invalid;
|
return FT_invalid;
|
||||||
}
|
}
|
||||||
@ -1923,6 +1924,9 @@ operator << (ostream &out, Texture::FilterType ft) {
|
|||||||
case Texture::FT_linear_mipmap_linear:
|
case Texture::FT_linear_mipmap_linear:
|
||||||
return out << "linear_mipmap_linear";
|
return out << "linear_mipmap_linear";
|
||||||
|
|
||||||
|
case Texture::FT_shadow:
|
||||||
|
return out << "shadow";
|
||||||
|
|
||||||
case Texture::FT_invalid:
|
case Texture::FT_invalid:
|
||||||
return out << "invalid";
|
return out << "invalid";
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,9 @@ PUBLISHED:
|
|||||||
// two mipmap levels, and linearly blend the results.
|
// two mipmap levels, and linearly blend the results.
|
||||||
FT_linear_mipmap_linear,
|
FT_linear_mipmap_linear,
|
||||||
|
|
||||||
|
// The OpenGL ARB_shadow extension can be thought of as a kind of filtering.
|
||||||
|
FT_shadow,
|
||||||
|
|
||||||
// Returned by string_filter_type() for an invalid match.
|
// Returned by string_filter_type() for an invalid match.
|
||||||
FT_invalid
|
FT_invalid
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user