Merge branch 'master' into deploy-ng
This commit is contained in:
commit
e13ad8e146
|
|
@ -50,6 +50,10 @@ class Actor(DirectObject, NodePath):
|
|||
def __repr__(self):
|
||||
return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
|
||||
|
||||
|
||||
#snake_case alias:
|
||||
get_bundle = getBundle
|
||||
|
||||
class AnimDef:
|
||||
|
||||
"""Instances of this class are stored within the
|
||||
|
|
@ -72,6 +76,10 @@ class Actor(DirectObject, NodePath):
|
|||
def __repr__(self):
|
||||
return 'Actor.AnimDef(%s)' % (repr(self.filename))
|
||||
|
||||
|
||||
#snake_case alias:
|
||||
make_copy = makeCopy
|
||||
|
||||
class SubpartDef:
|
||||
|
||||
"""Instances of this class are stored within the SubpartDict
|
||||
|
|
@ -2549,3 +2557,89 @@ class Actor(DirectObject, NodePath):
|
|||
for partBundleDict in self.__partBundleDict.values():
|
||||
partDef = partBundleDict.get(subpartDef.truePartName)
|
||||
partDef.getBundle().setName(newBundleName)
|
||||
|
||||
#snake_case alias:
|
||||
control_joint = controlJoint
|
||||
set_lod_animation = setLODAnimation
|
||||
get_anim_control_dict = getAnimControlDict
|
||||
get_actor_info = getActorInfo
|
||||
clear_lod_animation = clearLODAnimation
|
||||
reset_lod = resetLOD
|
||||
fix_bounds = fixBounds
|
||||
get_anim_filename = getAnimFilename
|
||||
get_subparts_complete = getSubpartsComplete
|
||||
verify_subparts_complete = verifySubpartsComplete
|
||||
get_play_rate = getPlayRate
|
||||
clear_python_data = clearPythonData
|
||||
load_anims = loadAnims
|
||||
set_subparts_complete = setSubpartsComplete
|
||||
draw_in_front = drawInFront
|
||||
get_lod_node = getLODNode
|
||||
hide_part = hidePart
|
||||
get_joint_transform_state = getJointTransformState
|
||||
set_control_effect = setControlEffect
|
||||
get_anim_controls = getAnimControls
|
||||
release_joint = releaseJoint
|
||||
print_anim_blends = printAnimBlends
|
||||
get_lod = getLOD
|
||||
disable_blend = disableBlend
|
||||
show_part = showPart
|
||||
get_joint_transform = getJointTransform
|
||||
face_away_from_viewer = faceAwayFromViewer
|
||||
set_lod = setLOD
|
||||
osd_anim_blends = osdAnimBlends
|
||||
get_current_frame = getCurrentFrame
|
||||
set_play_rate = setPlayRate
|
||||
bind_all_anims = bindAllAnims
|
||||
unload_anims = unloadAnims
|
||||
remove_part = removePart
|
||||
use_lod = useLOD
|
||||
get_anim_blends = getAnimBlends
|
||||
get_lod_index = getLODIndex
|
||||
get_num_frames = getNumFrames
|
||||
post_flatten = postFlatten
|
||||
get_lod_names = getLODNames
|
||||
list_joints = listJoints
|
||||
make_subpart = makeSubpart
|
||||
get_anim_control = getAnimControl
|
||||
get_part_bundle = getPartBundle
|
||||
get_part_bundle_dict = getPartBundleDict
|
||||
get_duration = getDuration
|
||||
has_lod = hasLOD
|
||||
print_lod = printLOD
|
||||
fix_bounds_old = fixBounds_old
|
||||
get_anim_names = getAnimNames
|
||||
get_part_bundles = getPartBundles
|
||||
anim_panel = animPanel
|
||||
stop_joint = stopJoint
|
||||
actor_interval = actorInterval
|
||||
hide_all_bounds = hideAllBounds
|
||||
show_all_bounds = showAllBounds
|
||||
init_anims_on_all_lods = initAnimsOnAllLODs
|
||||
get_part = getPart
|
||||
add_lod = addLOD
|
||||
show_all_parts = showAllParts
|
||||
get_joints = getJoints
|
||||
get_overlapping_joints = getOverlappingJoints
|
||||
enable_blend = enableBlend
|
||||
face_towards_viewer = faceTowardsViewer
|
||||
bind_anim = bindAnim
|
||||
set_blend = setBlend
|
||||
get_frame_time = getFrameTime
|
||||
remove_node = removeNode
|
||||
wait_pending = waitPending
|
||||
expose_joint = exposeJoint
|
||||
set_lod_node = setLODNode
|
||||
get_frame_rate = getFrameRate
|
||||
get_current_anim = getCurrentAnim
|
||||
get_part_names = getPartNames
|
||||
freeze_joint = freezeJoint
|
||||
set_center = setCenter
|
||||
rename_part_bundles = renamePartBundles
|
||||
get_geom_node = getGeomNode
|
||||
set_geom_node = setGeomNode
|
||||
load_model = loadModel
|
||||
copy_actor = copyActor
|
||||
get_base_frame_rate = getBaseFrameRate
|
||||
remove_anim_control_dict = removeAnimControlDict
|
||||
load_anims_on_all_lods = loadAnimsOnAllLODs
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ class InputStateToken:
|
|||
def __hash__(self):
|
||||
return self._hash
|
||||
|
||||
#snake_case alias:
|
||||
is_valid = isValid
|
||||
|
||||
class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
|
||||
def release(self):
|
||||
self._inputState._ignore(self)
|
||||
|
|
@ -39,6 +42,9 @@ class InputStateTokenGroup:
|
|||
token.release()
|
||||
self._tokens = []
|
||||
|
||||
#snake_case alias:
|
||||
add_token = addToken
|
||||
|
||||
class InputState(DirectObject.DirectObject):
|
||||
"""
|
||||
InputState is for tracking the on/off state of some events.
|
||||
|
|
@ -235,3 +241,10 @@ class InputState(DirectObject.DirectObject):
|
|||
"""for debugging"""
|
||||
return self.notify.debug(
|
||||
"%s (%s) %s"%(id(self), len(self._state), message))
|
||||
|
||||
#snake_case alias:
|
||||
watch_with_modifiers = watchWithModifiers
|
||||
is_set = isSet
|
||||
get_event_name = getEventName
|
||||
debug_print = debugPrint
|
||||
release_inputs = releaseInputs
|
||||
|
|
|
|||
|
|
@ -537,3 +537,24 @@ class CommonFilters:
|
|||
del self.configuration["GammaAdjust"]
|
||||
return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
|
||||
return True
|
||||
|
||||
#snake_case alias:
|
||||
del_cartoon_ink = delCartoonInk
|
||||
set_half_pixel_shift = setHalfPixelShift
|
||||
del_half_pixel_shift = delHalfPixelShift
|
||||
set_inverted = setInverted
|
||||
del_inverted = delInverted
|
||||
del_view_glow = delViewGlow
|
||||
set_volumetric_lighting = setVolumetricLighting
|
||||
del_gamma_adjust = delGammaAdjust
|
||||
set_bloom = setBloom
|
||||
set_view_glow = setViewGlow
|
||||
set_ambient_occlusion = setAmbientOcclusion
|
||||
set_cartoon_ink = setCartoonInk
|
||||
del_bloom = delBloom
|
||||
del_ambient_occlusion = delAmbientOcclusion
|
||||
load_shader = loadShader
|
||||
set_blur_sharpen = setBlurSharpen
|
||||
del_blur_sharpen = delBlurSharpen
|
||||
del_volumetric_lighting = delVolumetricLighting
|
||||
set_gamma_adjust = setGammaAdjust
|
||||
|
|
|
|||
|
|
@ -349,3 +349,15 @@ class FilterManager(DirectObject):
|
|||
self.nextsort = self.win.getSort() - 1000
|
||||
self.basex = 0
|
||||
self.basey = 0
|
||||
|
||||
#snake_case alias:
|
||||
is_fullscreen = isFullscreen
|
||||
resize_buffers = resizeBuffers
|
||||
set_stacked_clears = setStackedClears
|
||||
render_scene_into = renderSceneInto
|
||||
get_scaled_size = getScaledSize
|
||||
render_quad_into = renderQuadInto
|
||||
get_clears = getClears
|
||||
set_clears = setClears
|
||||
create_buffer = createBuffer
|
||||
window_event = windowEvent
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ void vshader(float4 vtx_position : POSITION,
|
|||
l_position=mul(mat_modelproj, vtx_position);
|
||||
float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
|
||||
float offset = texpix_src.x;
|
||||
l_texcoord0 = float4(c.x-offset* -4, c.x-offset* -3, c.x-offset* -2, c.y);
|
||||
l_texcoord1 = float4(c.x-offset* -1, c.x-offset* 0, c.x-offset* 1, c.y);
|
||||
float pad = texpad_src.x * 2;
|
||||
l_texcoord0 = float4(min(c.x-offset* -4, pad), min(c.x-offset* -3, pad), min(c.x-offset* -2, pad), c.y);
|
||||
l_texcoord1 = float4(min(c.x-offset* -1, pad), c.x-offset* 0, c.x-offset* 1, c.y);
|
||||
l_texcoord2 = float4(c.x-offset* 2, c.x-offset* 3, c.x-offset* 4, c.y);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ void vshader(float4 vtx_position : POSITION,
|
|||
l_position=mul(mat_modelproj, vtx_position);
|
||||
float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
|
||||
float offset = texpix_src.y;
|
||||
l_texcoord0 = float4(c.y-offset* -4, c.y-offset* -3, c.y-offset* -2, c.x);
|
||||
l_texcoord1 = float4(c.y-offset* -1, c.y-offset* 0, c.y-offset* 1, c.x);
|
||||
float pad = texpad_src.y * 2;
|
||||
l_texcoord0 = float4(min(c.y-offset* -4, pad), min(c.y-offset* -3, pad), min(c.y-offset* -2, pad), c.x);
|
||||
l_texcoord1 = float4(min(c.y-offset* -1, pad), c.y-offset* 0, c.y-offset* 1, c.x);
|
||||
l_texcoord2 = float4(c.y-offset* 2, c.y-offset* 3, c.y-offset* 4, c.x);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,16 +18,18 @@ void vshader(float4 vtx_position : POSITION,
|
|||
void fshader(float2 l_texcoord0 : TEXCOORD0,
|
||||
out float4 o_color : COLOR,
|
||||
uniform float2 texpix_src,
|
||||
uniform float4 texpad_src,
|
||||
uniform sampler2D k_src : TEXUNIT0)
|
||||
{
|
||||
float pad = texpad_src.x * 2;
|
||||
float3 offset = float3(1.0*texpix_src.x, 2.0*texpix_src.x, 3.0*texpix_src.x);
|
||||
o_color = tex2D(k_src, l_texcoord0);
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x - offset.z, l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x - offset.y, l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x - offset.x, l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x + offset.x, l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x + offset.y, l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x + offset.z, l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.x, pad), l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.y, pad), l_texcoord0.y));
|
||||
o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.z, pad), l_texcoord0.y));
|
||||
o_color /= 7;
|
||||
o_color.w = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,16 +18,18 @@ void vshader(float4 vtx_position : POSITION,
|
|||
void fshader(float2 l_texcoord0 : TEXCOORD0,
|
||||
out float4 o_color : COLOR,
|
||||
uniform float2 texpix_src,
|
||||
uniform float4 texpad_src,
|
||||
uniform sampler2D k_src : TEXUNIT0)
|
||||
{
|
||||
float pad = texpad_src.y * 2;
|
||||
float3 offset = float3(1.0*texpix_src.y, 2.0*texpix_src.y, 3.0*texpix_src.y);
|
||||
o_color = tex2D(k_src, l_texcoord0);
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.z));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.x));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.x));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.y));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.z));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.x, pad)));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.y, pad)));
|
||||
o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.z, pad)));
|
||||
o_color /= 7;
|
||||
o_color.w = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,3 +289,27 @@ class Audio3DManager:
|
|||
for sound in self.sound_dict[object]:
|
||||
self.detachSound(sound)
|
||||
|
||||
#snake_case alias:
|
||||
get_doppler_factor = getDopplerFactor
|
||||
set_listener_velocity_auto = setListenerVelocityAuto
|
||||
attach_listener = attachListener
|
||||
set_distance_factor = setDistanceFactor
|
||||
attach_sound_to_object = attachSoundToObject
|
||||
get_drop_off_factor = getDropOffFactor
|
||||
set_doppler_factor = setDopplerFactor
|
||||
get_sounds_on_object = getSoundsOnObject
|
||||
set_sound_velocity_auto = setSoundVelocityAuto
|
||||
get_sound_max_distance = getSoundMaxDistance
|
||||
load_sfx = loadSfx
|
||||
get_distance_factor = getDistanceFactor
|
||||
set_listener_velocity = setListenerVelocity
|
||||
set_sound_max_distance = setSoundMaxDistance
|
||||
get_sound_velocity = getSoundVelocity
|
||||
get_listener_velocity = getListenerVelocity
|
||||
set_sound_velocity = setSoundVelocity
|
||||
set_sound_min_distance = setSoundMinDistance
|
||||
get_sound_min_distance = getSoundMinDistance
|
||||
detach_listener = detachListener
|
||||
set_drop_off_factor = setDropOffFactor
|
||||
detach_sound = detachSound
|
||||
|
||||
|
|
|
|||
|
|
@ -101,3 +101,15 @@ class DirectObject:
|
|||
func = choice(getRepository()._crashOnProactiveLeakDetect,
|
||||
self.notify.error, self.notify.warning)
|
||||
func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
|
||||
|
||||
#snake_case alias:
|
||||
add_task = addTask
|
||||
do_method_later = doMethodLater
|
||||
detect_leaks = detectLeaks
|
||||
accept_once = acceptOnce
|
||||
ignore_all = ignoreAll
|
||||
get_all_accepting = getAllAccepting
|
||||
is_ignoring = isIgnoring
|
||||
remove_all_tasks = removeAllTasks
|
||||
remove_task = removeTask
|
||||
is_accepting = isAccepting
|
||||
|
|
|
|||
|
|
@ -635,3 +635,16 @@ class Messenger:
|
|||
str = str + '='*50 + '\n'
|
||||
return str
|
||||
|
||||
#snake_case alias:
|
||||
get_events = getEvents
|
||||
is_ignoring = isIgnoring
|
||||
who_accepts = whoAccepts
|
||||
find_all = findAll
|
||||
replace_method = replaceMethod
|
||||
ignore_all = ignoreAll
|
||||
is_accepting = isAccepting
|
||||
is_empty = isEmpty
|
||||
detailed_repr = detailedRepr
|
||||
get_all_accepting = getAllAccepting
|
||||
toggle_verbose = toggleVerbose
|
||||
|
||||
|
|
|
|||
|
|
@ -835,13 +835,16 @@ if (COMPILER=="GCC"):
|
|||
# Needed when linking ffmpeg statically on Linux.
|
||||
LibName("FFMPEG", "-Wl,-Bsymbolic")
|
||||
|
||||
cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV")
|
||||
if cv_lib == "opencv_core":
|
||||
OPENCV_VER_23 = True
|
||||
SmartPkgEnable("OPENCV", "opencv", ("opencv_core", "opencv_highgui"), ("opencv2/core/core.hpp"))
|
||||
if PkgSkip("FFMPEG") or GetTarget() == "darwin":
|
||||
cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV")
|
||||
if cv_lib == "opencv_core":
|
||||
OPENCV_VER_23 = True
|
||||
SmartPkgEnable("OPENCV", "opencv", ("opencv_core", "opencv_highgui"), ("opencv2/core/core.hpp"))
|
||||
else:
|
||||
SmartPkgEnable("OPENCV", "opencv", ("cv", "highgui", "cvaux", "ml", "cxcore"),
|
||||
("opencv", "opencv/cv.h", "opencv/cxcore.h", "opencv/highgui.h"))
|
||||
else:
|
||||
SmartPkgEnable("OPENCV", "opencv", ("cv", "highgui", "cvaux", "ml", "cxcore"),
|
||||
("opencv", "opencv/cv.h", "opencv/cxcore.h", "opencv/highgui.h"))
|
||||
PkgDisable("OPENCV")
|
||||
|
||||
rocket_libs = ("RocketCore", "RocketControls")
|
||||
if (GetOptimize() <= 3):
|
||||
|
|
|
|||
|
|
@ -1849,16 +1849,6 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
|||
CPT(TransformState) cs_world_transform = cs_transform->compose(world_transform);
|
||||
scene_setup->set_cs_world_transform(cs_world_transform);
|
||||
|
||||
// Make sure that the GSG has a ShaderGenerator for the munger to use. We
|
||||
// have to do this here because the ShaderGenerator needs a host window
|
||||
// pointer. Hopefully we'll be able to eliminate that requirement in the
|
||||
// future.
|
||||
#ifdef HAVE_CG
|
||||
if (gsg->get_shader_generator() == NULL) {
|
||||
gsg->set_shader_generator(new ShaderGenerator(gsg, window));
|
||||
}
|
||||
#endif
|
||||
|
||||
return scene_setup;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -344,11 +344,11 @@ munge_state_impl(const RenderState *state) {
|
|||
#ifdef HAVE_CG
|
||||
if (_auto_shader) {
|
||||
CPT(RenderState) shader_state = munged_state->get_auto_shader_state();
|
||||
ShaderGenerator *shader_generator = get_gsg()->get_shader_generator();
|
||||
if (shader_generator == NULL) {
|
||||
pgraph_cat.error()
|
||||
<< "auto_shader enabled, but GSG has no shader generator assigned!\n";
|
||||
return munged_state;
|
||||
GraphicsStateGuardian *gsg = get_gsg();
|
||||
ShaderGenerator *shader_generator = gsg->get_shader_generator();
|
||||
if (shader_generator == nullptr) {
|
||||
shader_generator = new ShaderGenerator(gsg);
|
||||
gsg->set_shader_generator(shader_generator);
|
||||
}
|
||||
if (shader_state->_generated_shader == NULL) {
|
||||
// Cache the generated ShaderAttrib on the shader state.
|
||||
|
|
|
|||
|
|
@ -56,12 +56,12 @@ PUBLISHED:
|
|||
BLOCKING void ls(ostream &out = cout) const;
|
||||
BLOCKING void ls_all(ostream &out = cout) const;
|
||||
|
||||
EXTENSION(BLOCKING PyObject *read_file(bool auto_unwrap) const);
|
||||
EXTENSION(PyObject *read_file(bool auto_unwrap) const);
|
||||
BLOCKING virtual istream *open_read_file(bool auto_unwrap) const;
|
||||
BLOCKING virtual void close_read_file(istream *stream) const;
|
||||
virtual bool was_read_successful() const;
|
||||
|
||||
EXTENSION(BLOCKING PyObject *write_file(PyObject *data, bool auto_wrap));
|
||||
EXTENSION(PyObject *write_file(PyObject *data, bool auto_wrap));
|
||||
BLOCKING virtual ostream *open_write_file(bool auto_wrap, bool truncate);
|
||||
BLOCKING virtual ostream *open_append_file();
|
||||
BLOCKING virtual void close_write_file(ostream *stream);
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@ PUBLISHED:
|
|||
|
||||
static VirtualFileSystem *get_global_ptr();
|
||||
|
||||
EXTENSION(BLOCKING PyObject *read_file(const Filename &filename, bool auto_unwrap) const);
|
||||
EXTENSION(PyObject *read_file(const Filename &filename, bool auto_unwrap) const);
|
||||
BLOCKING istream *open_read_file(const Filename &filename, bool auto_unwrap) const;
|
||||
BLOCKING static void close_read_file(istream *stream);
|
||||
|
||||
EXTENSION(BLOCKING PyObject *write_file(const Filename &filename, PyObject *data, bool auto_wrap));
|
||||
EXTENSION(PyObject *write_file(const Filename &filename, PyObject *data, bool auto_wrap));
|
||||
BLOCKING ostream *open_write_file(const Filename &filename, bool auto_wrap, bool truncate);
|
||||
BLOCKING ostream *open_append_file(const Filename &filename);
|
||||
BLOCKING static void close_write_file(ostream *stream);
|
||||
|
|
|
|||
|
|
@ -26,9 +26,22 @@
|
|||
*/
|
||||
PyObject *Extension<VirtualFileSystem>::
|
||||
read_file(const Filename &filename, bool auto_unwrap) const {
|
||||
// Release the GIL while we do this potentially slow operation.
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
PyThreadState *_save;
|
||||
Py_UNBLOCK_THREADS
|
||||
#endif
|
||||
|
||||
vector_uchar pv;
|
||||
bool okflag = _this->read_file(filename, pv, auto_unwrap);
|
||||
nassertr(okflag, NULL);
|
||||
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
Py_BLOCK_THREADS
|
||||
#endif
|
||||
|
||||
if (!okflag) {
|
||||
return PyErr_Format(PyExc_IOError, "Failed to read file: '%s'", filename.c_str());
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (pv.empty()) {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,23 @@
|
|||
*/
|
||||
PyObject *Extension<VirtualFile>::
|
||||
read_file(bool auto_unwrap) const {
|
||||
// Release the GIL while we do this potentially slow operation.
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
PyThreadState *_save;
|
||||
Py_UNBLOCK_THREADS
|
||||
#endif
|
||||
|
||||
vector_uchar pv;
|
||||
bool okflag = _this->read_file(pv, auto_unwrap);
|
||||
nassertr(okflag, NULL);
|
||||
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
Py_BLOCK_THREADS
|
||||
#endif
|
||||
|
||||
if (!okflag) {
|
||||
Filename fn = _this->get_filename();
|
||||
return PyErr_Format(PyExc_IOError, "Failed to read file: '%s'", fn.c_str());
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (pv.empty()) {
|
||||
|
|
@ -68,7 +82,18 @@ write_file(PyObject *data, bool auto_wrap) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Release the GIL while we do this potentially slow operation.
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
PyThreadState *_save;
|
||||
Py_UNBLOCK_THREADS
|
||||
#endif
|
||||
|
||||
bool result = _this->write_file((const unsigned char *)buffer, length, auto_wrap);
|
||||
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
Py_BLOCK_THREADS
|
||||
#endif
|
||||
|
||||
return PyBool_FromLong(result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,19 +127,7 @@ PUBLISHED:
|
|||
MAKE_PROPERTY(local, get_local, set_local);
|
||||
MAKE_PROPERTY(twoside, get_twoside, set_twoside);
|
||||
|
||||
private:
|
||||
LColor _base_color;
|
||||
LColor _ambient;
|
||||
LColor _diffuse;
|
||||
LColor _specular;
|
||||
LColor _emission;
|
||||
PN_stdfloat _shininess;
|
||||
PN_stdfloat _roughness;
|
||||
PN_stdfloat _metallic;
|
||||
PN_stdfloat _refractive_index;
|
||||
|
||||
static PT(Material) _default;
|
||||
|
||||
public:
|
||||
enum Flags {
|
||||
F_ambient = 0x001,
|
||||
F_diffuse = 0x002,
|
||||
|
|
@ -153,8 +141,24 @@ private:
|
|||
F_base_color = 0x200,
|
||||
F_refractive_index = 0x400,
|
||||
};
|
||||
|
||||
private:
|
||||
LColor _base_color;
|
||||
LColor _ambient;
|
||||
LColor _diffuse;
|
||||
LColor _specular;
|
||||
LColor _emission;
|
||||
PN_stdfloat _shininess;
|
||||
PN_stdfloat _roughness;
|
||||
PN_stdfloat _metallic;
|
||||
PN_stdfloat _refractive_index;
|
||||
|
||||
static PT(Material) _default;
|
||||
|
||||
int _flags;
|
||||
|
||||
friend class MaterialAttrib;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
|
|
|
|||
|
|
@ -428,7 +428,9 @@ cp_dependency(ShaderMatInput inp) {
|
|||
(inp == SMO_view_to_apiclip_x)) {
|
||||
dep |= SSD_shaderinputs;
|
||||
|
||||
if ((inp == SMO_alight_x) ||
|
||||
if ((inp == SMO_texpad_x) ||
|
||||
(inp == SMO_texpix_x) ||
|
||||
(inp == SMO_alight_x) ||
|
||||
(inp == SMO_dlight_x) ||
|
||||
(inp == SMO_plight_x) ||
|
||||
(inp == SMO_slight_x) ||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "auxBitplaneAttrib.h"
|
||||
|
||||
TypeHandle AlphaTestAttrib::_type_handle;
|
||||
int AlphaTestAttrib::_attrib_slot;
|
||||
|
|
@ -98,7 +99,15 @@ get_hash_impl() const {
|
|||
*/
|
||||
CPT(RenderAttrib) AlphaTestAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
return this;
|
||||
// This is only important if the shader subsumes the alpha test, which only
|
||||
// happens if there is an AuxBitplaneAttrib with ABO_glow.
|
||||
const AuxBitplaneAttrib *aux;
|
||||
if (!state->get_attrib(aux) ||
|
||||
(aux->get_outputs() & AuxBitplaneAttrib::ABO_glow) == 0) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "geom.h"
|
||||
#include "geomTransformer.h"
|
||||
#include "sceneGraphReducer.h"
|
||||
#include "stateMunger.h"
|
||||
#include "accumulatedAttribs.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
|
|
@ -391,33 +392,32 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
|
|||
((GeomPrimitive *)prim.p())->prepare(prepared_objects);
|
||||
}
|
||||
|
||||
if (munger->is_of_type(StateMunger::get_class_type())) {
|
||||
StateMunger *state_munger = (StateMunger *)munger.p();
|
||||
geom_state = state_munger->munge_state(geom_state);
|
||||
}
|
||||
|
||||
// And now prepare each of the textures.
|
||||
const RenderAttrib *attrib =
|
||||
geom_state->get_attrib(TextureAttrib::get_class_slot());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const TextureAttrib *ta;
|
||||
DCAST_INTO_V(ta, attrib);
|
||||
const TextureAttrib *ta;
|
||||
if (geom_state->get_attrib(ta)) {
|
||||
int num_stages = ta->get_num_on_stages();
|
||||
for (int i = 0; i < num_stages; ++i) {
|
||||
Texture *texture = ta->get_on_texture(ta->get_on_stage(i));
|
||||
// TODO: prepare the sampler states, if specified.
|
||||
if (texture != (Texture *)NULL) {
|
||||
if (texture != nullptr) {
|
||||
texture->prepare(prepared_objects);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// As well as the shaders.
|
||||
attrib = geom_state->get_attrib(ShaderAttrib::get_class_slot());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const ShaderAttrib *sa;
|
||||
DCAST_INTO_V(sa, attrib);
|
||||
const ShaderAttrib *sa;
|
||||
if (geom_state->get_attrib(sa)) {
|
||||
Shader *shader = (Shader *)sa->get_shader();
|
||||
if (shader != (Shader *)NULL) {
|
||||
if (shader != nullptr) {
|
||||
shader->prepare(prepared_objects);
|
||||
}
|
||||
// TODO: prepare the shader inputs. TODO: Invoke the shader generator
|
||||
// if enabled.
|
||||
// TODO: prepare the shader inputs.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* Use MaterialAttrib::make() to construct a new MaterialAttrib object.
|
||||
*/
|
||||
INLINE MaterialAttrib::
|
||||
MaterialAttrib() {
|
||||
MaterialAttrib() : _flags(0) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -24,7 +24,7 @@ MaterialAttrib() {
|
|||
*/
|
||||
INLINE bool MaterialAttrib::
|
||||
is_off() const {
|
||||
return _material == (const Material *)NULL;
|
||||
return _flags == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -35,3 +35,11 @@ INLINE Material *MaterialAttrib::
|
|||
get_material() const {
|
||||
return _material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to get_material()->get_flags().
|
||||
*/
|
||||
INLINE int MaterialAttrib::
|
||||
get_material_flags() const {
|
||||
return _flags;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ make(Material *material) {
|
|||
MaterialAttrib *attrib = new MaterialAttrib;
|
||||
attrib->_material = material;
|
||||
material->set_attrib_lock();
|
||||
attrib->_flags = material->_flags;
|
||||
nassertr(attrib->_flags & Material::F_attrib_lock, nullptr);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
|
|
@ -58,10 +60,34 @@ make_default() {
|
|||
void MaterialAttrib::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << ":";
|
||||
if (is_off()) {
|
||||
if (_material != nullptr) {
|
||||
out << *_material;
|
||||
} else if (is_off()) {
|
||||
out << "(off)";
|
||||
} else {
|
||||
out << *_material;
|
||||
// This is a state returned from get_auto_shader_attrib().
|
||||
out << "(on";
|
||||
#ifndef NDEBUG
|
||||
if (_flags & Material::F_ambient) {
|
||||
out << " amb";
|
||||
}
|
||||
if (_flags & Material::F_diffuse) {
|
||||
out << " diff";
|
||||
}
|
||||
if (_flags & Material::F_specular) {
|
||||
out << " spec";
|
||||
}
|
||||
if (_flags & Material::F_emission) {
|
||||
out << " emit";
|
||||
}
|
||||
if (_flags & Material::F_local) {
|
||||
out << " local";
|
||||
}
|
||||
if (_flags & Material::F_twoside) {
|
||||
out << " twoside";
|
||||
}
|
||||
#endif
|
||||
out << ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +113,7 @@ compare_to_impl(const RenderAttrib *other) const {
|
|||
if (_material != ta->_material) {
|
||||
return _material < ta->_material ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
return _flags < ta->_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,6 +126,7 @@ size_t MaterialAttrib::
|
|||
get_hash_impl() const {
|
||||
size_t hash = 0;
|
||||
hash = pointer_hash::add_hash(hash, _material);
|
||||
hash = int_hash::add_hash(hash, _flags);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +135,15 @@ get_hash_impl() const {
|
|||
*/
|
||||
CPT(RenderAttrib) MaterialAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
return this;
|
||||
if (_material == nullptr) {
|
||||
return this;
|
||||
} else {
|
||||
// Make a copy, but only with the flags, not with the material itself.
|
||||
MaterialAttrib *attrib = new MaterialAttrib();
|
||||
attrib->_material = nullptr;
|
||||
attrib->_flags = _flags;
|
||||
return return_new(attrib);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,8 +174,12 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
int pi = RenderAttrib::complete_pointers(p_list, manager);
|
||||
|
||||
TypedWritable *material = p_list[pi++];
|
||||
if (material != (TypedWritable *)NULL) {
|
||||
if (material != nullptr) {
|
||||
_material = DCAST(Material, material);
|
||||
_flags = _material->_flags | Material::F_attrib_lock;
|
||||
} else {
|
||||
_material = nullptr;
|
||||
_flags = 0;
|
||||
}
|
||||
|
||||
return pi;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ PUBLISHED:
|
|||
INLINE bool is_off() const;
|
||||
INLINE Material *get_material() const;
|
||||
|
||||
public:
|
||||
INLINE int get_material_flags() const;
|
||||
|
||||
PUBLISHED:
|
||||
MAKE_PROPERTY(material, get_material);
|
||||
|
||||
|
|
@ -49,6 +52,7 @@ protected:
|
|||
|
||||
private:
|
||||
PT(Material) _material;
|
||||
int _flags;
|
||||
|
||||
PUBLISHED:
|
||||
static int get_class_slot() {
|
||||
|
|
|
|||
|
|
@ -86,11 +86,14 @@ get_hash_impl() const {
|
|||
CPT(RenderAttrib) RescaleNormalAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
// We currently only support M_normalize in the ShaderGenerator.
|
||||
if (_mode == M_none || _mode == M_normalize) {
|
||||
/*if (_mode == M_none || _mode == M_normalize) {
|
||||
return this;
|
||||
} else {
|
||||
return RescaleNormalAttrib::make(M_normalize);
|
||||
}
|
||||
}*/
|
||||
// Actually, we currently ignore this attribute in the shader generator,
|
||||
// and always normalize the normals. It's too much of a bother.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -523,14 +523,15 @@ void ShaderAttrib::
|
|||
output(ostream &out) const {
|
||||
out << "ShaderAttrib:";
|
||||
|
||||
if (_has_shader) {
|
||||
if (_shader == NULL) {
|
||||
if (_auto_shader) {
|
||||
out << "auto";
|
||||
return;
|
||||
} else if (_has_shader) {
|
||||
if (_shader == nullptr) {
|
||||
out << "off";
|
||||
} else {
|
||||
out << _shader->get_filename().get_basename();
|
||||
}
|
||||
} else if (_auto_shader) {
|
||||
out << "auto";
|
||||
}
|
||||
|
||||
out << "," << _inputs.size() << " inputs";
|
||||
|
|
|
|||
|
|
@ -140,6 +140,26 @@ get_on_texture(TextureStage *stage) const {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the texture associated with the indicated stage. It is
|
||||
* an error to call this if has_on_stage(stage) returns false.
|
||||
*
|
||||
* This method is no different than get_on_texture(stage)->get_texture_type();
|
||||
* it merely exists to address a corner case for the shader generator.
|
||||
*/
|
||||
INLINE Texture::TextureType TextureAttrib::
|
||||
get_on_texture_type(TextureStage *stage) const {
|
||||
Stages::const_iterator si;
|
||||
si = _on_stages.find(StageNode(stage));
|
||||
nassertr(si != _on_stages.end(), Texture::TT_2d_texture);
|
||||
|
||||
if ((*si)._texture == nullptr) {
|
||||
return (*si)._texture_type;
|
||||
} else {
|
||||
return (*si)._texture->get_texture_type();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sampler associated with the indicated stage, or the one
|
||||
* associated with its texture if no custom stage has been specified. It is
|
||||
|
|
@ -215,6 +235,26 @@ is_identity() const {
|
|||
return _on_stages.empty() && _off_stages.empty() && !_off_all_stages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call only on a state returned by get_auto_shader_attrib.
|
||||
*/
|
||||
bool TextureAttrib::
|
||||
on_stage_affects_rgb(size_t n) const {
|
||||
nassertr(n < _render_stages.size(), false);
|
||||
StageNode *stage = _render_stages[n];
|
||||
return stage->_texture_affects_rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call only on a state returned by get_auto_shader_attrib.
|
||||
*/
|
||||
bool TextureAttrib::
|
||||
on_stage_affects_alpha(size_t n) const {
|
||||
nassertr(n < _render_stages.size(), false);
|
||||
StageNode *stage = _render_stages[n];
|
||||
return stage->_texture_affects_alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms whether the _on_stages list is still sorted. It will become
|
||||
* unsorted if someone calls TextureStage::set_sort().
|
||||
|
|
@ -223,7 +263,7 @@ is_identity() const {
|
|||
*/
|
||||
INLINE void TextureAttrib::
|
||||
check_sorted() const {
|
||||
if (_sort_seq != TextureStage::get_sort_seq()) {
|
||||
if (_sort_seq != TextureStage::get_sort_seq() && !_sort_seq.is_fresh()) {
|
||||
((TextureAttrib *)this)->sort_on_stages();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ find_on_stage(const TextureStage *stage) const {
|
|||
*/
|
||||
CPT(RenderAttrib) TextureAttrib::
|
||||
add_on_stage(TextureStage *stage, Texture *tex, int override) const {
|
||||
nassertr(tex != nullptr, this);
|
||||
|
||||
TextureAttrib *attrib = new TextureAttrib(*this);
|
||||
Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
|
||||
(*si)._override = override;
|
||||
|
|
@ -127,6 +129,8 @@ add_on_stage(TextureStage *stage, Texture *tex, int override) const {
|
|||
*/
|
||||
CPT(RenderAttrib) TextureAttrib::
|
||||
add_on_stage(TextureStage *stage, Texture *tex, const SamplerState &sampler, int override) const {
|
||||
nassertr(tex != nullptr, this);
|
||||
|
||||
TextureAttrib *attrib = new TextureAttrib(*this);
|
||||
Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
|
||||
(*si)._override = override;
|
||||
|
|
@ -381,10 +385,19 @@ output(ostream &out) const {
|
|||
const StageNode &sn = *(*ri);
|
||||
TextureStage *stage = sn._stage;
|
||||
Texture *tex = sn._texture;
|
||||
if (tex != NULL) {
|
||||
if (tex != nullptr) {
|
||||
out << " " << stage->get_name() << ":" << tex->get_name();
|
||||
} else {
|
||||
out << " " << stage->get_name();
|
||||
out << " " << stage->get_name() << ":(" << sn._texture_type;
|
||||
if (sn._texture_affects_rgb) {
|
||||
out << " rgb";
|
||||
if (sn._texture_affects_alpha) {
|
||||
out << "a";
|
||||
}
|
||||
} else if (sn._texture_affects_alpha) {
|
||||
out << " alpha";
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
if (sn._override != 0) {
|
||||
out << "^" << sn._override;
|
||||
|
|
@ -500,6 +513,19 @@ compare_to_impl(const RenderAttrib *other) const {
|
|||
}
|
||||
}
|
||||
|
||||
if (texture == nullptr) {
|
||||
// This is an attribute returned by get_auto_shader_attrib_impl.
|
||||
if ((*si)._texture_type != (*osi)._texture_type) {
|
||||
return (*si)._texture_type < (*osi)._texture_type ? -1 : 1;
|
||||
}
|
||||
if ((*si)._texture_affects_rgb != (*osi)._texture_affects_rgb) {
|
||||
return (*si)._texture_affects_rgb < (*osi)._texture_affects_rgb ? -1 : 1;
|
||||
}
|
||||
if ((*si)._texture_affects_alpha != (*osi)._texture_affects_alpha) {
|
||||
return (*si)._texture_affects_alpha < (*osi)._texture_affects_alpha ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
++si;
|
||||
++osi;
|
||||
}
|
||||
|
|
@ -563,6 +589,13 @@ get_hash_impl() const {
|
|||
hash = pointer_hash::add_hash(hash, sn._texture);
|
||||
hash = int_hash::add_hash(hash, (int)sn._implicit_sort);
|
||||
hash = int_hash::add_hash(hash, sn._override);
|
||||
|
||||
if (sn._texture == nullptr) {
|
||||
// This is an attribute returned by get_auto_shader_attrib_impl.
|
||||
hash = int_hash::add_hash(hash, (int)sn._texture_type);
|
||||
hash = int_hash::add_hash(hash, (int)sn._texture_affects_rgb);
|
||||
hash = int_hash::add_hash(hash, (int)sn._texture_affects_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
// This bool value goes here, between the two lists, to differentiate
|
||||
|
|
@ -739,7 +772,45 @@ invert_compose_impl(const RenderAttrib *other) const {
|
|||
*/
|
||||
CPT(RenderAttrib) TextureAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
return this;
|
||||
if (_on_stages.empty()) {
|
||||
// Having no stages is the same as not applying a texture attribute.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We make a texture attribute that does not store the texture and sampler,
|
||||
// so that we don't have to generate a shader for every possible texture.
|
||||
// We do have to store the few texture properties that do affect the
|
||||
// generated shader.
|
||||
PT(TextureAttrib) attrib = new TextureAttrib;
|
||||
attrib->_on_stages = _on_stages;
|
||||
attrib->sort_on_stages();
|
||||
|
||||
Stages::iterator si;
|
||||
for (si = attrib->_on_stages.begin(); si != attrib->_on_stages.end(); ++si) {
|
||||
Texture::Format format = (*si)._texture->get_format();
|
||||
(*si)._texture_type = (*si)._texture->get_texture_type();
|
||||
(*si)._texture_affects_rgb = (format != Texture::F_alpha);
|
||||
(*si)._texture_affects_alpha = Texture::has_alpha(format);
|
||||
(*si)._texture = nullptr;
|
||||
(*si)._has_sampler = false;
|
||||
|
||||
// We will no longer be composing or sorting this state so we can get rid
|
||||
// of these values.
|
||||
(*si)._override = 0;
|
||||
(*si)._implicit_sort = 0;
|
||||
|
||||
// Exception to optimize a common case: if the first texture is an RGB
|
||||
// texture, we don't care about whether it affects the alpha channel.
|
||||
if (attrib->_render_stages[0] == &(*si) &&
|
||||
(*si)._texture_affects_rgb && !(*si)._texture_affects_alpha) {
|
||||
(*si)._texture_affects_alpha = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent check_sorted() from being called on this state.
|
||||
attrib->_sort_seq = UpdateSeq::fresh();
|
||||
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ PUBLISHED:
|
|||
INLINE int get_ff_tc_index(int n) const;
|
||||
INLINE bool has_on_stage(TextureStage *stage) const;
|
||||
INLINE Texture *get_on_texture(TextureStage *stage) const;
|
||||
INLINE Texture::TextureType get_on_texture_type(TextureStage *stage) const;
|
||||
INLINE const SamplerState &get_on_sampler(TextureStage *stage) const;
|
||||
INLINE int get_on_stage_override(TextureStage *stage) const;
|
||||
|
||||
|
|
@ -81,6 +82,8 @@ PUBLISHED:
|
|||
CPT(RenderAttrib) unify_texture_stages(TextureStage *stage) const;
|
||||
|
||||
public:
|
||||
INLINE bool on_stage_affects_rgb(size_t n) const;
|
||||
INLINE bool on_stage_affects_alpha(size_t n) const;
|
||||
CPT(TextureAttrib) filter_to_max(int max_texture_stages) const;
|
||||
|
||||
virtual bool lower_attrib_can_override() const;
|
||||
|
|
@ -114,6 +117,11 @@ private:
|
|||
int _ff_tc_index;
|
||||
unsigned int _implicit_sort;
|
||||
int _override;
|
||||
|
||||
// These fields are used by the shader generator.
|
||||
Texture::TextureType _texture_type : 16;
|
||||
bool _texture_affects_rgb : 8;
|
||||
bool _texture_affects_alpha : 8;
|
||||
};
|
||||
|
||||
class CompareTextureStagePriorities {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,14 @@ get_hash_impl() const {
|
|||
*/
|
||||
CPT(RenderAttrib) TransparencyAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
return this;
|
||||
if (_mode == TransparencyAttrib::M_alpha) {
|
||||
return this;
|
||||
} else if (_mode == TransparencyAttrib::M_premultiplied_alpha ||
|
||||
_mode == TransparencyAttrib::M_dual) {
|
||||
return return_new(new TransparencyAttrib(M_alpha));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ TypeHandle ShaderGenerator::_type_handle;
|
|||
* shader generator belongs.
|
||||
*/
|
||||
ShaderGenerator::
|
||||
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host) :
|
||||
_gsg(gsg), _host(host) {
|
||||
ShaderGenerator(GraphicsStateGuardianBase *gsg) :
|
||||
_gsg(gsg) {
|
||||
|
||||
// The ATTR# input semantics seem to map to generic vertex attributes in
|
||||
// both arbvp1 and glslv, which behave more consistently. However, they
|
||||
|
|
@ -265,12 +265,7 @@ analyze_renderstate(const RenderState *rs) {
|
|||
|
||||
const MaterialAttrib *material;
|
||||
rs->get_attrib_def(material);
|
||||
|
||||
if (!material->is_off()) {
|
||||
_material = material->get_material();
|
||||
} else {
|
||||
_material = Material::get_default();
|
||||
}
|
||||
_material_flags = material->get_material_flags();
|
||||
|
||||
// Break out the lights by type.
|
||||
|
||||
|
|
@ -285,14 +280,7 @@ analyze_renderstate(const RenderState *rs) {
|
|||
nassertv(light_obj != (PandaNode *)NULL);
|
||||
|
||||
if (light_obj->is_ambient_light()) {
|
||||
if (_material->has_ambient()) {
|
||||
LColor a = _material->get_ambient();
|
||||
if ((a[0]!=0.0)||(a[1]!=0.0)||(a[2]!=0.0)) {
|
||||
_have_ambient = true;
|
||||
}
|
||||
} else {
|
||||
_have_ambient = true;
|
||||
}
|
||||
_have_ambient = true;
|
||||
_lighting = true;
|
||||
|
||||
} else if (light_obj->is_of_type(LightLensNode::get_class_type())) {
|
||||
|
|
@ -357,37 +345,28 @@ analyze_renderstate(const RenderState *rs) {
|
|||
}
|
||||
|
||||
// Determine whether we should normalize the normals.
|
||||
const RescaleNormalAttrib *rescale;
|
||||
/*const RescaleNormalAttrib *rescale;
|
||||
rs->get_attrib_def(rescale);
|
||||
|
||||
_normalize_normals = (rescale->get_mode() != RescaleNormalAttrib::M_none);
|
||||
*/
|
||||
// Actually, let's always normalize the normals for now. This helps to
|
||||
// reduce combinatoric explosion of shaders.
|
||||
_normalize_normals = true;
|
||||
|
||||
// Decide which material modes need to be calculated.
|
||||
|
||||
if (_lighting) {
|
||||
if (_material->has_diffuse()) {
|
||||
LColor d = _material->get_diffuse();
|
||||
if ((d[0]!=0.0)||(d[1]!=0.0)||(d[2]!=0.0)) {
|
||||
_have_diffuse = true;
|
||||
}
|
||||
} else {
|
||||
_have_diffuse = true;
|
||||
}
|
||||
_have_diffuse = true;
|
||||
}
|
||||
|
||||
if (_lighting && (_material->has_emission())) {
|
||||
LColor e = _material->get_emission();
|
||||
if ((e[0]!=0.0)||(e[1]!=0.0)||(e[2]!=0.0)) {
|
||||
_have_emission = true;
|
||||
}
|
||||
if (_lighting && (_material_flags & Material::F_emission) != 0) {
|
||||
_have_emission = true;
|
||||
}
|
||||
|
||||
if (_lighting) {
|
||||
if (_material->has_specular()) {
|
||||
LColor s = _material->get_specular();
|
||||
if ((s[0]!=0.0)||(s[1]!=0.0)||(s[2]!=0.0)) {
|
||||
_have_specular = true;
|
||||
}
|
||||
if (_material_flags & Material::F_specular) {
|
||||
_have_specular = true;
|
||||
} else if (_map_index_gloss >= 0) {
|
||||
_have_specular = true;
|
||||
}
|
||||
|
|
@ -398,14 +377,10 @@ analyze_renderstate(const RenderState *rs) {
|
|||
// Decide whether to separate ambient and diffuse calculations.
|
||||
|
||||
if (_have_ambient && _have_diffuse) {
|
||||
if (_material->has_ambient()) {
|
||||
if (_material->has_diffuse()) {
|
||||
_separate_ambient_diffuse = _material->get_ambient() != _material->get_diffuse();
|
||||
} else {
|
||||
_separate_ambient_diffuse = true;
|
||||
}
|
||||
if (_material_flags & Material::F_ambient) {
|
||||
_separate_ambient_diffuse = true;
|
||||
} else {
|
||||
if (_material->has_diffuse()) {
|
||||
if (_material_flags & Material::F_diffuse) {
|
||||
_separate_ambient_diffuse = true;
|
||||
} else {
|
||||
_separate_ambient_diffuse = false;
|
||||
|
|
@ -427,10 +402,10 @@ analyze_renderstate(const RenderState *rs) {
|
|||
// Does the shader need material properties as input?
|
||||
|
||||
_need_material_props =
|
||||
(_have_ambient && (_material->has_ambient()))||
|
||||
(_have_diffuse && (_material->has_diffuse()))||
|
||||
(_have_emission && (_material->has_emission()))||
|
||||
(_have_specular && (_material->has_specular()));
|
||||
(_have_ambient && (_material_flags & Material::F_ambient) != 0) ||
|
||||
(_have_diffuse && (_material_flags & Material::F_diffuse) != 0) ||
|
||||
(_have_emission && (_material_flags & Material::F_emission) != 0) ||
|
||||
(_have_specular && (_material_flags & Material::F_specular) != 0);
|
||||
|
||||
// Check for clip planes.
|
||||
|
||||
|
|
@ -490,7 +465,7 @@ clear_analysis() {
|
|||
_out_aux_normal = false;
|
||||
_out_aux_glow = false;
|
||||
_out_aux_any = false;
|
||||
_material = (Material*)NULL;
|
||||
_material_flags = 0;
|
||||
_need_material_props = false;
|
||||
_need_world_position = false;
|
||||
_need_world_normal = false;
|
||||
|
|
@ -823,11 +798,10 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
text << "\t in float4 l_" << it->first->join("_") << " : " << it->second << ",\n";
|
||||
}
|
||||
const TexMatrixAttrib *tex_matrix = DCAST(TexMatrixAttrib, rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
|
||||
for (int i=0; i<_num_textures; i++) {
|
||||
for (int i = 0; i < _num_textures; ++i) {
|
||||
TextureStage *stage = texture->get_on_stage(i);
|
||||
Texture *tex = texture->get_on_texture(stage);
|
||||
nassertr(tex != NULL, NULL);
|
||||
text << "\t uniform sampler" << texture_type_as_string(tex->get_texture_type()) << " tex_" << i << ",\n";
|
||||
Texture::TextureType type = texture->get_on_texture_type(stage);
|
||||
text << "\t uniform sampler" << texture_type_as_string(type) << " tex_" << i << ",\n";
|
||||
if (tex_matrix->has_stage(stage)) {
|
||||
text << "\t uniform float4x4 texmat_" << i << ",\n";
|
||||
}
|
||||
|
|
@ -864,7 +838,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
text << "\t uniform float4x4 attr_material,\n";
|
||||
}
|
||||
if (_have_specular) {
|
||||
if (_material->get_local()) {
|
||||
if (_material_flags & Material::F_local) {
|
||||
text << "\t uniform float4 mspos_view,\n";
|
||||
} else {
|
||||
text << "\t uniform float4 row1_view_to_model,\n";
|
||||
|
|
@ -935,11 +909,10 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
}
|
||||
text << "\t // Fetch all textures.\n";
|
||||
if (_map_index_height >= 0 && parallax_mapping_samples > 0) {
|
||||
Texture *tex = texture->get_on_texture(texture->get_on_stage(_map_index_height));
|
||||
nassertr(tex != NULL, NULL);
|
||||
text << "\t float4 tex" << _map_index_height << " = tex" << texture_type_as_string(tex->get_texture_type());
|
||||
Texture::TextureType type = texture->get_on_texture_type(texture->get_on_stage(_map_index_height));
|
||||
text << "\t float4 tex" << _map_index_height << " = tex" << texture_type_as_string(type);
|
||||
text << "(tex_" << _map_index_height << ", texcoord" << _map_index_height << ".";
|
||||
switch (tex->get_texture_type()) {
|
||||
switch (type) {
|
||||
case Texture::TT_cube_map:
|
||||
case Texture::TT_3d_texture:
|
||||
case Texture::TT_2d_texture_array:
|
||||
|
|
@ -972,18 +945,17 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
text << " * 2.0 - 1.0)) * " << 0.5 * parallax_mapping_scale << ";\n";
|
||||
}
|
||||
}
|
||||
for (int i=0; i<_num_textures; i++) {
|
||||
for (int i = 0; i < _num_textures; ++i) {
|
||||
if (i != _map_index_height) {
|
||||
Texture *tex = texture->get_on_texture(texture->get_on_stage(i));
|
||||
nassertr(tex != NULL, NULL);
|
||||
Texture::TextureType type = texture->get_on_texture_type(texture->get_on_stage(i));
|
||||
// Parallax mapping pushes the texture coordinates of the other textures
|
||||
// away from the camera.
|
||||
if (_map_index_height >= 0 && parallax_mapping_samples > 0) {
|
||||
text << "\t texcoord" << i << ".xyz -= parallax_offset;\n";
|
||||
}
|
||||
text << "\t float4 tex" << i << " = tex" << texture_type_as_string(tex->get_texture_type());
|
||||
text << "\t float4 tex" << i << " = tex" << texture_type_as_string(type);
|
||||
text << "(tex_" << i << ", texcoord" << i << ".";
|
||||
switch(tex->get_texture_type()) {
|
||||
switch (type) {
|
||||
case Texture::TT_cube_map:
|
||||
case Texture::TT_3d_texture:
|
||||
case Texture::TT_2d_texture_array:
|
||||
|
|
@ -1040,7 +1012,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
}
|
||||
if (_have_specular) {
|
||||
text << "\t float4 tot_specular = float4(0,0,0,0);\n";
|
||||
if (_material->has_specular()) {
|
||||
if (_material_flags & Material::F_specular) {
|
||||
text << "\t float shininess = attr_material[3].w;\n";
|
||||
} else {
|
||||
text << "\t float shininess = 50; // no shininess specified, using default\n";
|
||||
|
|
@ -1072,7 +1044,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
text << "\t tot_diffuse += lcolor;\n";
|
||||
}
|
||||
if (_have_specular) {
|
||||
if (_material->get_local()) {
|
||||
if (_material_flags & Material::F_local) {
|
||||
text << "\t lhalf = normalize(lvec - normalize(l_eye_position.xyz));\n";
|
||||
} else {
|
||||
text << "\t lhalf = dlight_light" << i << "_rel_view[3].xyz;\n";
|
||||
|
|
@ -1102,7 +1074,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
text << "\t tot_diffuse += lcolor;\n";
|
||||
}
|
||||
if (_have_specular) {
|
||||
if (_material->get_local()) {
|
||||
if (_material_flags & Material::F_local) {
|
||||
text << "\t lhalf = normalize(lvec - normalize(l_eye_position.xyz));\n";
|
||||
} else {
|
||||
text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n";
|
||||
|
|
@ -1140,7 +1112,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
text << "\t tot_diffuse += lcolor;\n";
|
||||
}
|
||||
if (_have_specular) {
|
||||
if (_material->get_local()) {
|
||||
if (_material_flags & Material::F_local) {
|
||||
text << "\t lhalf = normalize(lvec - normalize(l_eye_position.xyz));\n";
|
||||
} else {
|
||||
text << "\t lhalf = normalize(lvec - float3(0,1,0));\n";
|
||||
|
|
@ -1198,7 +1170,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
}
|
||||
}
|
||||
if ((_have_ambient)&&(_separate_ambient_diffuse)) {
|
||||
if (_material->has_ambient()) {
|
||||
if (_material_flags & Material::F_ambient) {
|
||||
text << "\t result += tot_ambient * attr_material[0];\n";
|
||||
} else if (_vertex_colors) {
|
||||
text << "\t result += tot_ambient * l_color;\n";
|
||||
|
|
@ -1209,7 +1181,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
}
|
||||
}
|
||||
if (_have_diffuse) {
|
||||
if (_material->has_diffuse()) {
|
||||
if (_material_flags & Material::F_diffuse) {
|
||||
text << "\t result += tot_diffuse * attr_material[1];\n";
|
||||
} else if (_vertex_colors) {
|
||||
text << "\t result += tot_diffuse * l_color;\n";
|
||||
|
|
@ -1263,20 +1235,20 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
}
|
||||
|
||||
// Now loop through the textures to compose our magic blending formulas.
|
||||
for (int i=0; i<_num_textures; i++) {
|
||||
for (int i = 0; i < _num_textures; ++i) {
|
||||
TextureStage *stage = texture->get_on_stage(i);
|
||||
switch (stage->get_mode()) {
|
||||
case TextureStage::M_modulate: {
|
||||
int num_components = texture->get_on_texture(texture->get_on_stage(i))->get_num_components();
|
||||
bool affects_rgb = texture->on_stage_affects_rgb(i);
|
||||
bool affects_alpha = texture->on_stage_affects_alpha(i);
|
||||
|
||||
if (num_components == 1) {
|
||||
text << "\t result.a *= tex" << i << ".a;\n";
|
||||
} else if (num_components == 3) {
|
||||
text << "\t result.rgb *= tex" << i << ".rgb;\n";
|
||||
} else {
|
||||
if (affects_rgb && affects_alpha) {
|
||||
text << "\t result.rgba *= tex" << i << ".rgba;\n";
|
||||
} else if (affects_alpha) {
|
||||
text << "\t result.a *= tex" << i << ".a;\n";
|
||||
} else if (affects_rgb) {
|
||||
text << "\t result.rgb *= tex" << i << ".rgb;\n";
|
||||
}
|
||||
|
||||
break; }
|
||||
case TextureStage::M_modulate_glow:
|
||||
case TextureStage::M_modulate_gloss:
|
||||
|
|
@ -1388,7 +1360,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||
|
||||
if (_lighting) {
|
||||
if (_have_specular) {
|
||||
if (_material->has_specular()) {
|
||||
if (_material_flags & Material::F_specular) {
|
||||
text << "\t tot_specular *= attr_material[3];\n";
|
||||
}
|
||||
if (_map_index_gloss >= 0 && _auto_gloss_on) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class GeomVertexAnimationSpec;
|
|||
*/
|
||||
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedReferenceCount {
|
||||
PUBLISHED:
|
||||
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host);
|
||||
ShaderGenerator(GraphicsStateGuardianBase *gsg);
|
||||
virtual ~ShaderGenerator();
|
||||
virtual CPT(ShaderAttrib) synthesize_shader(const RenderState *rs,
|
||||
const GeomVertexAnimationSpec &anim);
|
||||
|
|
@ -87,7 +87,7 @@ protected:
|
|||
// RenderState analysis information. Created by analyze_renderstate:
|
||||
|
||||
CPT(RenderState) _state;
|
||||
Material *_material;
|
||||
int _material_flags;
|
||||
int _num_textures;
|
||||
|
||||
pvector<LightLensNode *> _lights;
|
||||
|
|
@ -144,7 +144,6 @@ protected:
|
|||
|
||||
// This is not a PT() to prevent a circular reference.
|
||||
GraphicsStateGuardianBase *_gsg;
|
||||
GraphicsOutputBase *_host;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue