15 #include "eggRenderState.h"
16 #include "eggRenderMode.h"
19 #include "textureAttrib.h"
20 #include "renderAttrib.h"
21 #include "eggTexture.h"
22 #include "texGenAttrib.h"
23 #include "internalName.h"
25 #include "eggSurface.h"
26 #include "cullBinAttrib.h"
27 #include "cullFaceAttrib.h"
28 #include "shadeModelAttrib.h"
29 #include "transparencyAttrib.h"
30 #include "depthWriteAttrib.h"
31 #include "depthTestAttrib.h"
32 #include "depthOffsetAttrib.h"
33 #include "texMatrixAttrib.h"
34 #include "renderModeAttrib.h"
36 #include "materialAttrib.h"
37 #include "materialPool.h"
38 #include "config_gobj.h"
39 #include "config_egg2pg.h"
55 EggRenderMode::AlphaMode am = EggRenderMode::AM_unspecified;
56 EggRenderMode::DepthWriteMode dwm = EggRenderMode::DWM_unspecified;
57 EggRenderMode::DepthTestMode dtm = EggRenderMode::DTM_unspecified;
58 EggRenderMode::VisibilityMode vm = EggRenderMode::VM_unspecified;
59 bool implicit_alpha =
false;
60 bool binary_alpha_only =
true;
61 bool has_draw_order =
false;
63 bool has_depth_offset =
false;
87 has_draw_order =
true;
92 has_depth_offset =
true;
108 for (
int i = 0; i < num_textures; i++) {
111 const TextureDef &def = _loader._textures[egg_tex];
114 texture_attrib = def._texture;
116 texture_attrib = texture_attrib->compose(def._texture);
119 if (egg_tex->affects_polygon_alpha()) {
122 nassertv(tex != (
Texture *)NULL);
127 binary_alpha_only =
false;
130 if (am == EggRenderMode::AM_unspecified) {
136 if (egg_tex->has_alpha_channel(num_components)) {
137 implicit_alpha =
true;
143 bool has_tex_gen =
false;
144 if (egg_tex->get_tex_gen() != EggTexture::TG_unspecified) {
147 tex_gen_attrib = TexGenAttrib::make();
150 add_stage(def._stage, get_tex_gen(egg_tex));
157 CPT(InternalName) uv_name;
158 if (egg_tex->has_uv_name() && egg_tex->get_uv_name() != string(
"default")) {
159 uv_name = InternalName::get_texcoord_name(egg_tex->get_uv_name());
161 uv_name = InternalName::get_texcoord();
169 tex_mat_attrib = apply_tex_mat(tex_mat_attrib, def._stage, egg_tex);
182 tex_mats[uv_name][egg_tex->get_transform3d()].push_back(&def);
191 bool needs_tex_mat = (egg_prim->
is_of_type(EggCurve::get_class_type()) ||
192 egg_prim->
is_of_type(EggSurface::get_class_type()));
197 TexMats::const_iterator tmi;
198 for (tmi = tex_mats.begin(); tmi != tex_mats.end(); ++tmi) {
199 const InternalName *uv_name = (*tmi).first;
202 if (tmt.size() == 1 && !needs_tex_mat) {
209 nassertv(!tmtex.empty());
210 TexMatTextures::const_iterator tmtexi = tmtex.begin();
211 const EggTexture *egg_tex = (*tmtexi)->_egg_tex;
216 _bake_in_uvs[uv_name] = egg_tex;
223 TexMatTransforms::const_iterator tmti;
224 for (tmti = tmt.begin(); tmti != tmt.end(); ++tmti) {
226 TexMatTextures::const_iterator tmtexi;
227 for (tmtexi = tmtex.begin(); tmtexi != tmtex.end(); ++tmtexi) {
228 const EggTexture *egg_tex = (*tmtexi)->_egg_tex;
231 tex_mat_attrib = apply_tex_mat(tex_mat_attrib, stage, egg_tex);
255 if (material->has_diff() && material->get_diff()[3] != 1.0) {
256 implicit_alpha =
true;
257 binary_alpha_only =
false;
264 if (am == EggRenderMode::AM_unspecified) {
265 if (egg_prim->has_color()) {
267 implicit_alpha =
true;
268 binary_alpha_only =
false;
271 EggPrimitive::const_iterator vi;
272 for (vi = egg_prim->begin();
273 !implicit_alpha && vi != egg_prim->end();
275 if ((*vi)->has_color()) {
276 if ((*vi)->get_color()[3] != 1.0) {
277 implicit_alpha =
true;
278 binary_alpha_only =
false;
283 if (implicit_alpha) {
284 am = EggRenderMode::AM_on;
289 case EggRenderMode::AM_on:
291 if (binary_alpha_only) {
292 am = EggRenderMode::AM_binary;
293 }
else if (egg_alpha_mode != EggRenderMode::AM_unspecified) {
298 case EggRenderMode::AM_blend:
299 case EggRenderMode::AM_ms:
300 case EggRenderMode::AM_ms_mask:
301 case EggRenderMode::AM_dual:
302 if (egg_implicit_alpha_binary) {
306 if (binary_alpha_only) {
307 am = EggRenderMode::AM_binary;
317 case EggRenderMode::AM_on:
318 case EggRenderMode::AM_blend:
319 add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
322 case EggRenderMode::AM_blend_no_occlude:
323 add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
324 add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_off));
327 case EggRenderMode::AM_ms:
328 add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_multisample));
331 case EggRenderMode::AM_ms_mask:
332 add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_multisample_mask));
335 case EggRenderMode::AM_binary:
336 add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_binary));
339 case EggRenderMode::AM_dual:
340 add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_dual));
348 case EggRenderMode::DWM_on:
349 add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_on));
352 case EggRenderMode::DWM_off:
353 add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_off));
361 case EggRenderMode::DTM_on:
362 add_attrib(DepthTestAttrib::make(DepthTestAttrib::M_less));
365 case EggRenderMode::DTM_off:
366 add_attrib(DepthTestAttrib::make(DepthTestAttrib::M_none));
374 case EggRenderMode::VM_hidden:
378 case EggRenderMode::VM_normal:
388 add_attrib(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
391 if (egg_prim->
is_of_type(EggLine::get_class_type())) {
392 _primitive_type = Geom::PT_lines;
395 add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_unchanged,
398 }
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
399 _primitive_type = Geom::PT_points;
402 add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_unchanged,
407 _primitive_type = Geom::PT_polygons;
411 add_attrib(CullBinAttrib::make(bin, draw_order));
413 }
else if (has_draw_order) {
414 add_attrib(CullBinAttrib::make(
"fixed", draw_order));
416 if (has_depth_offset) {
417 add_attrib(DepthOffsetAttrib::make(depth_offset));
424 add_attrib(CullFaceAttrib::make(CullFaceAttrib::M_cull_none));
437 if (_state != other._state) {
438 int c = _state->compare_to(*other._state);
443 if (_hidden != other._hidden) {
444 return (
int)_hidden - (int)other._hidden;
446 if (_flat_shaded != other._flat_shaded) {
447 return (
int)_flat_shaded - (int)other._flat_shaded;
449 if (_primitive_type != other._primitive_type) {
450 return (
int)_primitive_type - (int)other._primitive_type;
453 if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
454 return (
int)_bake_in_uvs.size() - (int)other._bake_in_uvs.size();
457 BakeInUVs::const_iterator ai, bi;
458 ai = _bake_in_uvs.begin();
459 bi = other._bake_in_uvs.begin();
460 while (ai != _bake_in_uvs.end()) {
461 nassertr(bi != other._bake_in_uvs.end(),
false);
462 if ((*ai).first != (*bi).first) {
463 return (*ai).first < (*bi).first ? -1 : 1;
465 if ((*ai).second != (*bi).second) {
466 return (*ai).second < (*bi).second ? -1 : 1;
471 nassertr(bi == other._bake_in_uvs.end(),
false);
484 get_material_attrib(const
EggMaterial *egg_mat,
bool bface) {
485 Materials &materials =
486 bface ? _loader._materials_bface : _loader._materials;
489 Materials::const_iterator mi;
490 mi = materials.find(egg_mat);
491 if (mi != materials.end()) {
498 if (egg_mat->has_diff()) {
499 mat->set_diffuse(egg_mat->get_diff());
502 mat->set_ambient(egg_mat->get_diff());
504 if (egg_mat->has_amb()) {
505 mat->set_ambient(egg_mat->get_amb());
507 if (egg_mat->has_emit()) {
508 mat->set_emission(egg_mat->get_emit());
510 if (egg_mat->has_spec()) {
511 mat->set_specular(egg_mat->get_spec());
513 if (egg_mat->has_shininess()) {
514 mat->set_shininess(egg_mat->get_shininess());
516 if (egg_mat->has_local()) {
517 mat->set_local(egg_mat->get_local());
520 mat->set_twoside(bface);
527 materials.insert(Materials::value_type(egg_mat, mt));
540 switch (egg_tex->get_tex_gen()) {
541 case EggTexture::TG_unspecified:
542 return TexGenAttrib::M_off;
544 case EggTexture::TG_eye_sphere_map:
545 return TexGenAttrib::M_eye_sphere_map;
547 case EggTexture::TG_world_cube_map:
548 return TexGenAttrib::M_world_cube_map;
550 case EggTexture::TG_eye_cube_map:
551 return TexGenAttrib::M_eye_cube_map;
553 case EggTexture::TG_world_normal:
554 return TexGenAttrib::M_world_normal;
556 case EggTexture::TG_eye_normal:
557 return TexGenAttrib::M_eye_normal;
559 case EggTexture::TG_world_position:
560 return TexGenAttrib::M_world_position;
562 case EggTexture::TG_eye_position:
563 return TexGenAttrib::M_eye_position;
565 case EggTexture::TG_point_sprite:
566 return TexGenAttrib::M_point_sprite;
569 return TexGenAttrib::M_off;
582 if (egg_tex->has_transform()) {
583 CPT(TransformState) transform = _loader.make_transform(egg_tex);
586 tex_mat_attrib = TexMatrixAttrib::make();
589 add_stage(stage, transform);
592 return tex_mat_attrib;
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
VisibilityMode get_visibility_mode() const
Returns the visibility mode that was set, or VM_unspecified if nothing was set.
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
static Material * get_material(Material *temp)
Returns a Material pointer that represents the same material described by temp, except that it is a s...
This is our own Panda specialization on the default STL map.
virtual EggRenderMode * determine_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
A line segment, or a series of connected line segments, defined by a <Line> entry.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
LColor get_color() const
Returns the color set on this particular attribute.
bool get_bface_flag() const
Retrieves the backfacing flag of the polygon.
Indicates which, if any, material should be applied to geometry.
DepthWriteMode get_depth_write_mode() const
Returns the depth_write mode that was set, or DWM_unspecified if nothing was set. ...
Defines a texture map that may be applied to geometry.
int get_draw_order() const
Returns the "draw-order" flag as set for this particular object.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
virtual EggRenderMode * determine_alpha_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
EggTexture * get_texture() const
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
A single point, or a collection of points as defined by a single <PointLight> entry.
void fill_state(EggPrimitive *egg_prim)
Sets up the state as appropriate for the indicated primitive.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
This is our own Panda specialization on the default STL vector.
This class is used within this package only to record the render state that should be assigned to eac...
bool get_perspective() const
Returns the perspective flag set on this particular point.
This class stores miscellaneous rendering properties that is associated with geometry, and which may be set on the geometry primitive level, on the group above it, or indirectly via a texture.
virtual EggRenderMode * determine_depth_test_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
double get_thick() const
Returns the thickness set on this particular point.
EggMaterial * get_material() const
Returns a pointer to the applied material, or NULL if there is no material applied.
static bool has_alpha(Format format)
Returns true if the indicated format includes alpha, false otherwise.
int get_num_components() const
Returns the number of color components for each texel of the texture image.
void add_attrib(const RenderAttrib *attrib)
A convenience function to add the indicated render attribute to the aggregate state.
virtual EggRenderMode * determine_depth_offset()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
int get_num_textures() const
Returns the number of textures applied to the primitive.
string get_bin() const
Returns the bin name that has been set for this particular object, if any.
Defines the way an object appears in the presence of lighting.
virtual EggRenderMode * determine_draw_order()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
DepthTestMode get_depth_test_mode() const
Returns the depth_test mode that was set, or DTM_unspecified if nothing was set.
int compare_to(const EggRenderState &other) const
Provides a unique ordering for different EggRenderState objects, so that primitives of similar state ...
Applies a transform matrix to UV's before they are rendered.
AlphaMode get_alpha_mode() const
Returns the alpha mode that was set, or AM_unspecified if nothing was set.
bool has_material() const
Returns true if the primitive is materiald (and get_material() will return a real pointer)...
Shading get_connected_shading() const
Determines what sort of shading properties this primitive's connected neighbors have.
double get_thick() const
Returns the thickness set on this particular line.
virtual EggRenderMode * determine_visibility_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Defines the properties of a named stage of the multitexture pipeline.
static bool has_binary_alpha(Format format)
Returns true if the indicated format includes a binary alpha only, false otherwise.
Computes texture coordinates for geometry automatically based on vertex position and/or normal...
Texture * get_texture() const
If the TextureAttrib is not an 'off' TextureAttrib, returns the base-level texture that is associated...
virtual EggRenderMode * determine_depth_write_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
int get_depth_offset() const
Returns the "depth-offset" flag as set for this particular object.