diff --git a/README.md b/README.md index c424651845..094a40b0a7 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Installing Panda3D ================== The latest Panda3D SDK can be downloaded from -[this page](https://www.panda3d.org/download/sdk-1-10-12/). +[this page](https://www.panda3d.org/download/sdk-1-10-13/). If you are familiar with installing Python packages, you can use the following command: diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 69bd74150f..0730500a87 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -814,7 +814,12 @@ set_properties_now(WindowProperties &properties) { if (switched) { if (_window != nil) { // For some reason, setting the style mask makes it give up its - // first-responder status. + // first-responder status. And for some reason, we need to first + // restore the window to normal level before we switch fullscreen, + // otherwise we may get a black bar if we're currently on Z_top. + if (_properties.get_z_order() != WindowProperties::Z_normal) { + [_window setLevel: NSNormalWindowLevel]; + } if ([_window respondsToSelector:@selector(setStyleMask:)]) { [_window setStyleMask:NSBorderlessWindowMask]; } @@ -847,8 +852,12 @@ set_properties_now(WindowProperties &properties) { _properties.set_fullscreen(false); // Force properties to be reset to their actual values - properties.set_undecorated(_properties.get_undecorated()); - properties.set_z_order(_properties.get_z_order()); + if (!properties.has_undecorated()) { + properties.set_undecorated(_properties.get_undecorated()); + } + if (!properties.has_z_order()) { + properties.set_z_order(_properties.get_z_order()); + } properties.clear_fullscreen(); } } @@ -865,6 +874,58 @@ set_properties_now(WindowProperties &properties) { properties.clear_minimized(); } + if (properties.has_title() && _window != nil) { + _properties.set_title(properties.get_title()); + [_window setTitle:[NSString stringWithUTF8String:properties.get_title().c_str()]]; + properties.clear_title(); + } + + if (properties.has_fixed_size() && _window != nil) { + _properties.set_fixed_size(properties.get_fixed_size()); + [_window setShowsResizeIndicator:!properties.get_fixed_size()]; + + if (!_properties.get_fullscreen()) { + // If our window is decorated, change the style mask to show or hide the + // resize button appropriately. However, if we're specifying the + // 'undecorated' property also, then we'll be setting the style mask + // about 25 LOC further down, so we won't need to bother setting it + // here. + if (!properties.has_undecorated() && !_properties.get_undecorated() && + [_window respondsToSelector:@selector(setStyleMask:)]) { + if (properties.get_fixed_size()) { + [_window setStyleMask:NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask ]; + } else { + [_window setStyleMask:NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSResizableWindowMask ]; + } + [_window makeFirstResponder:_view]; + } + } + + properties.clear_fixed_size(); + } + + if (properties.has_undecorated() && _window != nil && [_window respondsToSelector:@selector(setStyleMask:)]) { + _properties.set_undecorated(properties.get_undecorated()); + + if (!_properties.get_fullscreen()) { + if (properties.get_undecorated()) { + [_window setStyleMask: NSBorderlessWindowMask]; + } else if (_properties.get_fixed_size()) { + // Fixed size windows should not show the resize button. + [_window setStyleMask: NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask ]; + } else { + [_window setStyleMask: NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSResizableWindowMask ]; + } + [_window makeFirstResponder:_view]; + } + + properties.clear_undecorated(); + } + if (properties.has_size()) { int width = properties.get_x_size(); int height = properties.get_y_size(); @@ -978,58 +1039,6 @@ set_properties_now(WindowProperties &properties) { properties.clear_maximized(); } - if (properties.has_title() && _window != nil) { - _properties.set_title(properties.get_title()); - [_window setTitle:[NSString stringWithUTF8String:properties.get_title().c_str()]]; - properties.clear_title(); - } - - if (properties.has_fixed_size() && _window != nil) { - _properties.set_fixed_size(properties.get_fixed_size()); - [_window setShowsResizeIndicator:!properties.get_fixed_size()]; - - if (!_properties.get_fullscreen()) { - // If our window is decorated, change the style mask to show or hide the - // resize button appropriately. However, if we're specifying the - // 'undecorated' property also, then we'll be setting the style mask - // about 25 LOC further down, so we won't need to bother setting it - // here. - if (!properties.has_undecorated() && !_properties.get_undecorated() && - [_window respondsToSelector:@selector(setStyleMask:)]) { - if (properties.get_fixed_size()) { - [_window setStyleMask:NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask ]; - } else { - [_window setStyleMask:NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSResizableWindowMask ]; - } - [_window makeFirstResponder:_view]; - } - } - - properties.clear_fixed_size(); - } - - if (properties.has_undecorated() && _window != nil && [_window respondsToSelector:@selector(setStyleMask:)]) { - _properties.set_undecorated(properties.get_undecorated()); - - if (!_properties.get_fullscreen()) { - if (properties.get_undecorated()) { - [_window setStyleMask: NSBorderlessWindowMask]; - } else if (_properties.get_fixed_size()) { - // Fixed size windows should not show the resize button. - [_window setStyleMask: NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask ]; - } else { - [_window setStyleMask: NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSResizableWindowMask ]; - } - [_window makeFirstResponder:_view]; - } - - properties.clear_undecorated(); - } - if (properties.has_foreground() && !_properties.get_fullscreen() && _window != nil) { _properties.set_foreground(properties.get_foreground()); if (!_properties.get_minimized()) { diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 34e49c42de..0a88529cbe 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -57,6 +57,7 @@ #include "colorScaleAttrib.h" #include "clipPlaneAttrib.h" #include "fogAttrib.h" +#include "renderModeAttrib.h" #include "config_pstatclient.h" #include @@ -1267,6 +1268,25 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } return; } + case Shader::SMO_texconst_i: { + const TexGenAttrib *tga; + const TextureAttrib *ta; + + int num_stages = 0; + if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tga)) { + num_stages = std::min(count, (int)ta->get_num_on_stages()); + } + + int i = 0; + for (; i < num_stages; ++i) { + LVecBase3 value = tga->get_constant_value(ta->get_on_stage(i)); + into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, value[0], value[1], value[2], 1); + } + for (; i < count; ++i) { + into[i] = LMatrix4::ident_mat(); + } + return; + } case Shader::SMO_tex_is_alpha_i: { // This is a hack so we can support both F_alpha and other formats in the // default shader, to fix font rendering in GLES2 @@ -1628,6 +1648,33 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } return; } + case Shader::SMO_attr_pointparams: { + const RenderModeAttrib *target_render_mode; + _target_rs->get_attrib_def(target_render_mode); + + PN_stdfloat thickness = target_render_mode->get_thickness(); + PN_stdfloat catten = thickness; + PN_stdfloat patten = 0.0f; + if (target_render_mode->get_perspective()) { + LVecBase2i pixel_size = _current_display_region->get_pixel_size(); + + LVector3 height(0.0f, thickness, 1.0f); + height = height * _projection_mat->get_mat(); + height = height * _internal_transform->get_scale()[1]; + PN_stdfloat s = height[1] * pixel_size[1]; + + if (_current_lens->is_orthographic()) { + catten = s; + patten = 0.0f; + } else { + catten = 0.0f; + patten = s; + } + } + + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, thickness, catten, patten, 0.0f); + return; + } default: nassertv(false /*should never get here*/); return; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index be3cfb14d6..28c8e50281 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -3149,6 +3149,7 @@ set_state_and_transform(const RenderState *target, } _target_rs = target; + int shader_deps = 0; determine_target_shader(); int alpha_test_slot = AlphaTestAttrib::get_class_slot(); @@ -3178,10 +3179,7 @@ set_state_and_transform(const RenderState *target, do_issue_color_scale(); _state_mask.set_bit(color_slot); _state_mask.set_bit(color_scale_slot); - if (_current_shader_context) { - _current_shader_context->issue_parameters(this, Shader::SSD_color); - _current_shader_context->issue_parameters(this, Shader::SSD_colorscale); - } + shader_deps |= Shader::SSD_color | Shader::SSD_colorscale; } int cull_face_slot = CullFaceAttrib::get_class_slot(); @@ -3222,6 +3220,7 @@ set_state_and_transform(const RenderState *target, // PStatTimer timer(_draw_set_state_render_mode_pcollector); do_issue_render_mode(); _state_mask.set_bit(render_mode_slot); + shader_deps |= Shader::SSD_render_mode; } int rescale_normal_slot = RescaleNormalAttrib::get_class_slot(); @@ -3285,6 +3284,7 @@ set_state_and_transform(const RenderState *target, _state_mask.set_bit(texture_slot); _state_mask.set_bit(tex_matrix_slot); _state_mask.set_bit(tex_gen_slot); + shader_deps |= Shader::SSD_tex_matrix | Shader::SSD_tex_gen; } int material_slot = MaterialAttrib::get_class_slot(); @@ -3293,9 +3293,7 @@ set_state_and_transform(const RenderState *target, // PStatTimer timer(_draw_set_state_material_pcollector); do_issue_material(); _state_mask.set_bit(material_slot); - if (_current_shader_context) { - _current_shader_context->issue_parameters(this, Shader::SSD_material); - } + shader_deps |= Shader::SSD_material; } int light_slot = LightAttrib::get_class_slot(); @@ -3320,9 +3318,7 @@ set_state_and_transform(const RenderState *target, // PStatTimer timer(_draw_set_state_fog_pcollector); do_issue_fog(); _state_mask.set_bit(fog_slot); - if (_current_shader_context) { - _current_shader_context->issue_parameters(this, Shader::SSD_fog); - } + shader_deps |= Shader::SSD_fog; } int scissor_slot = ScissorAttrib::get_class_slot(); @@ -3333,6 +3329,10 @@ set_state_and_transform(const RenderState *target, _state_mask.set_bit(scissor_slot); } + if (_current_shader_context != nullptr && shader_deps != 0) { + _current_shader_context->issue_parameters(this, shader_deps); + } + _state_rs = _target_rs; } diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index dd9b8f8233..53a4b6bac9 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -254,6 +254,7 @@ issue_parameters(GSG *gsg, int altered) { HRESULT hr; PN_stdfloat v [4]; LMatrix4f temp_matrix = LCAST(float, *val); + LMatrix3f temp_matrix3; hr = D3D_OK; @@ -315,6 +316,33 @@ issue_parameters(GSG *gsg, int altered) { hr = cgD3D9SetUniform(p, v); break; + case Shader::SMP_upper3x3: + // TRANSPOSE REQUIRED + temp_matrix3 = temp_matrix.get_upper_3(); + temp_matrix3.transpose_in_place(); + data = temp_matrix3.get_data(); + + hr = cgD3D9SetUniform(p, data); + break; + + case Shader::SMP_transpose3x3: + // NO TRANSPOSE REQUIRED + temp_matrix3 = temp_matrix.get_upper_3(); + data = temp_matrix3.get_data(); + + hr = cgD3D9SetUniform(p, data); + break; + + case Shader::SMP_cell15: + hr = cgD3D9SetUniform(p, data + 15); + continue; + case Shader::SMP_cell14: + hr = cgD3D9SetUniform(p, data + 14); + continue; + case Shader::SMP_cell13: + hr = cgD3D9SetUniform(p, data + 13); + continue; + default: dxgsg9_cat.error() << "issue_parameters () SMP parameter type not implemented " << spec._piece << "\n"; diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index 5ed4b3b206..b4d38ff8e9 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -486,6 +486,14 @@ set_state_and_transform(const RenderState *target_rs, target_rs->get_attrib(TexMatrixAttrib::get_class_slot())) { altered |= Shader::SSD_tex_matrix; } + if (state_rs->get_attrib(TexGenAttrib::get_class_slot()) != + target_rs->get_attrib(TexGenAttrib::get_class_slot())) { + altered |= Shader::SSD_tex_gen; + } + if (state_rs->get_attrib(RenderModeAttrib::get_class_slot()) != + target_rs->get_attrib(RenderModeAttrib::get_class_slot())) { + altered |= Shader::SSD_render_mode; + } _state_rs = target_rs; } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 687a8bbafb..350d6ffdfb 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -12340,6 +12340,8 @@ set_state_and_transform(const RenderState *target, } int texture_slot = TextureAttrib::get_class_slot(); + int tex_gen_slot = TexGenAttrib::get_class_slot(); + int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) || !_state_mask.get_bit(texture_slot)) { //PStatGPUTimer timer(this, _draw_set_state_texture_pcollector); @@ -12355,7 +12357,7 @@ set_state_and_transform(const RenderState *target, _target_texture = (const TextureAttrib *) _target_rs->get_attrib_def(TextureAttrib::get_class_slot()); _target_tex_gen = (const TexGenAttrib *) - _target_rs->get_attrib_def(TexGenAttrib::get_class_slot()); + _target_rs->get_attrib_def(tex_gen_slot); } #endif do_issue_texture(); @@ -12363,28 +12365,36 @@ set_state_and_transform(const RenderState *target, // Since the TexGen and TexMatrix states depend partly on the particular // set of textures in use, we should force both of those to be reissued // every time we change the texture state. - _state_mask.clear_bit(TexGenAttrib::get_class_slot()); - _state_mask.clear_bit(TexMatrixAttrib::get_class_slot()); + _state_mask.clear_bit(tex_gen_slot); + _state_mask.clear_bit(tex_matrix_slot); _state_texture = _target_texture; _state_mask.set_bit(texture_slot); } + else if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) || + !_state_mask.get_bit(tex_gen_slot)) { + _target_tex_gen = (const TexGenAttrib *)_target_rs->get_attrib_def(tex_gen_slot); - // If one of the previously-loaded TexGen modes modified the texture matrix, - // then if either state changed, we have to change both of them now. - if (_tex_gen_modifies_mat) { - int tex_gen_slot = TexGenAttrib::get_class_slot(); - int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); - if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) || - _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || - !_state_mask.get_bit(tex_gen_slot) || - !_state_mask.get_bit(tex_matrix_slot)) { +#ifdef SUPPORT_FIXED_FUNCTION +#ifdef OPENGLES_1 + if (_has_texture_alpha_scale) { +#else + if (_has_texture_alpha_scale && _current_shader == nullptr) { +#endif + PT(TextureStage) stage = get_alpha_scale_texture_stage(); + _target_tex_gen = DCAST(TexGenAttrib, _target_tex_gen->add_stage + (stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f))); + } +#endif // SUPPORT_FIXED_FUNCTION + + // If one of the previously-loaded TexGen modes modified the texture matrix, + // then if either state changed, we have to change both of them now. + if (_tex_gen_modifies_mat) { _state_mask.clear_bit(tex_gen_slot); _state_mask.clear_bit(tex_matrix_slot); } } - int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || !_state_mask.get_bit(tex_matrix_slot)) { // PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector); @@ -12399,11 +12409,15 @@ set_state_and_transform(const RenderState *target, _current_shader_context->issue_parameters(Shader::SSD_tex_matrix); } #endif + + // See previous occurrence of this check. + if (_tex_gen_modifies_mat) { + _state_mask.clear_bit(tex_gen_slot); + } } #ifdef SUPPORT_FIXED_FUNCTION if (has_fixed_function_pipeline()) { - int tex_gen_slot = TexGenAttrib::get_class_slot(); if (_target_tex_gen != _state_tex_gen || !_state_mask.get_bit(tex_gen_slot)) { // PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector); diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index c4a708e4e0..077e9e1d79 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -25,6 +25,7 @@ #include "fogAttrib.h" #include "lightAttrib.h" #include "clipPlaneAttrib.h" +#include "renderModeAttrib.h" #include "bamCache.h" using std::dec; @@ -2078,6 +2079,14 @@ set_state_and_transform(const RenderState *target_rs, target_rs->get_attrib(TextureAttrib::get_class_slot())) { altered |= Shader::SSD_texture; } + if (state_rs->get_attrib(TexGenAttrib::get_class_slot()) != + target_rs->get_attrib(TexGenAttrib::get_class_slot())) { + altered |= Shader::SSD_tex_gen; + } + if (state_rs->get_attrib(RenderModeAttrib::get_class_slot()) != + target_rs->get_attrib(RenderModeAttrib::get_class_slot())) { + altered |= Shader::SSD_render_mode; + } _state_rs = target_rs; } diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index e8a1e973ac..1d1fe47724 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -500,6 +500,12 @@ cp_dependency(ShaderMatInput inp) { if (inp == SMO_tex_is_alpha_i || inp == SMO_texcolor_i) { dep |= SSD_texture | SSD_frame; } + if (inp == SMO_texconst_i) { + dep |= SSD_tex_gen; + } + if (inp == SMO_attr_pointparams) { + dep |= SSD_render_mode | SSD_transform | SSD_frame; + } return dep; } @@ -1116,6 +1122,17 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._part[1] = SMO_identity; bind._arg[1] = nullptr; bind._index = atoi(pieces[1].c_str() + 5); + } else if (pieces[1] == "pointparams") { + if (!cp_errchk_parameter_float(p,3,4)) { + return false; + } + bind._id = p._id; + bind._piece = SMP_row3; + bind._func = SMF_first; + bind._part[0] = SMO_attr_pointparams; + bind._arg[0] = nullptr; + bind._part[1] = SMO_identity; + bind._arg[1] = nullptr; } else { cp_report_error(p,"Unknown attr parameter."); return false; @@ -1282,6 +1299,27 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return true; } + if (pieces[0] == "texconst") { + if ((!cp_errchk_parameter_words(p,2))|| + (!cp_errchk_parameter_in(p)) || + (!cp_errchk_parameter_uniform(p))|| + (!cp_errchk_parameter_float(p,3,4))) { + return false; + } + ShaderMatSpec bind; + bind._id = p._id; + bind._piece = SMP_row3; + bind._func = SMF_first; + bind._part[0] = SMO_texconst_i; + bind._arg[0] = nullptr; + bind._part[1] = SMO_identity; + bind._arg[1] = nullptr; + bind._index = atoi(pieces[1].c_str()); + + cp_add_mat_spec(bind); + return true; + } + if (pieces[0] == "plane") { if ((!cp_errchk_parameter_words(p,2))|| (!cp_errchk_parameter_in(p)) || diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 97511611e1..afcc0819fd 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -216,6 +216,12 @@ public: // Color of an M_blend texture stage. SMO_texcolor_i, + // Constant value of the TexGenAttrib of stage i. + SMO_texconst_i, + + // Point parameters + SMO_attr_pointparams, + SMO_INVALID }; @@ -323,6 +329,8 @@ public: SSD_projection = 0x800, SSD_texture = 0x1000, SSD_view_transform= 0x2000, + SSD_tex_gen = 0x4000, + SSD_render_mode = 0x8000, }; enum ShaderBug { diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index f6e9c559fd..d19fb1f967 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -38,6 +38,7 @@ #include "texture.h" #include "ambientLight.h" #include "directionalLight.h" +#include "renderModeAttrib.h" #include "rescaleNormalAttrib.h" #include "pointLight.h" #include "sphereLight.h" @@ -567,6 +568,12 @@ analyze_renderstate(ShaderKey &key, const RenderState *rs) { if (rs->get_attrib(fog) && !fog->is_off()) { key._fog_mode = (int)fog->get_fog()->get_mode() + 1; } + + // Hijack this field for the perspective render-mode flag. + const RenderModeAttrib *render_mode; + if (rs->get_attrib(render_mode) && render_mode->get_perspective()) { + key._fog_mode |= 0x10000; + } } /** @@ -754,6 +761,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { bool need_eye_position = key._lighting; bool need_eye_normal = !key._lights.empty() || ((key._outputs & AuxBitplaneAttrib::ABO_aux_normal) != 0); bool need_tangents = ((key._texture_flags & ShaderKey::TF_map_normal) != 0); + bool need_point_size = (key._fog_mode & 0x10000) != 0; // If we have binormal/tangent and eye position, we can pack eye normal in // the w channels of the others. @@ -781,23 +789,34 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } } + bool need_eye_reflection = false; + bool need_fragment_view_to_world = false; + text << "void vshader(\n"; for (size_t i = 0; i < key._textures.size(); ++i) { const ShaderKey::TextureInfo &tex = key._textures[i]; switch (tex._gen_mode) { - case TexGenAttrib::M_world_position: - need_world_position = true; + case TexGenAttrib::M_world_cube_map: + need_fragment_view_to_world = true; + case TexGenAttrib::M_eye_sphere_map: + case TexGenAttrib::M_eye_cube_map: + need_eye_position = true; + need_eye_normal = true; + need_eye_reflection = true; break; case TexGenAttrib::M_world_normal: need_world_normal = true; break; - case TexGenAttrib::M_eye_position: - need_eye_position = true; - break; case TexGenAttrib::M_eye_normal: need_eye_normal = true; break; + case TexGenAttrib::M_world_position: + need_world_position = true; + break; + case TexGenAttrib::M_eye_position: + need_eye_position = true; + break; default: break; } @@ -866,7 +885,8 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t uniform float4x4 trans_model_to_view,\n"; eye_position_freg = alloc_freg(); text << "\t out float4 l_eye_position : " << eye_position_freg << ",\n"; - } else if (need_tangents) { + } + else if (need_tangents || need_point_size) { text << "\t uniform float4x4 trans_model_to_view,\n"; } if (need_eye_normal) { @@ -883,7 +903,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t uniform float4 mspos_view,\n"; text << "\t out float3 l_eyevec,\n"; } - if (key._fog_mode != 0) { + if ((key._fog_mode & 0xffff) != 0) { hpos_freg = alloc_freg(); text << "\t out float4 l_hpos : " << hpos_freg << ",\n"; } @@ -923,6 +943,10 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t in uint4 vtx_transform_index : " << transform_index_vreg << ",\n"; } } + if (need_point_size) { + text << "\t uniform float3 attr_pointparams,\n"; + text << "\t out float l_point_size : PSIZE,\n"; + } text << "\t in float4 vtx_position : " << position_vreg << ",\n"; text << "\t out float4 l_position : POSITION,\n"; text << "\t uniform float4x4 mat_modelproj\n"; @@ -954,7 +978,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } text << "\t l_position = mul(mat_modelproj, vtx_position);\n"; - if (key._fog_mode != 0) { + if ((key._fog_mode & 0xffff) != 0) { text << "\t l_hpos = l_position;\n"; } if (need_world_position) { @@ -966,6 +990,13 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { if (need_eye_position) { text << "\t l_eye_position = mul(trans_model_to_view, vtx_position);\n"; } + else if (need_point_size) { + text << "\t float4 l_eye_position = mul(trans_model_to_view, vtx_position);\n"; + } + if (need_point_size) { + text << "\t l_point_size = attr_pointparams.y + attr_pointparams.z / length(l_eye_position.xyz);\n"; + } + pmap::const_iterator it; for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) { // Pass through all texcoord inputs as-is. @@ -1011,7 +1042,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { // Fragment shader text << "void fshader(\n"; - if (key._fog_mode != 0) { + if ((key._fog_mode & 0xffff) != 0) { text << "\t in float4 l_hpos : " << hpos_freg << ",\n"; text << "\t in uniform float4 attr_fog,\n"; text << "\t in uniform float4 attr_fogcolor,\n"; @@ -1049,6 +1080,13 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { if (tex._flags & ShaderKey::TF_uses_color) { text << "\t uniform float4 texcolor_" << i << ",\n"; } + + if (tex._gen_mode == TexGenAttrib::M_constant) { + text << "\t uniform float4 texconst_" << i << ",\n"; + } + } + if (need_fragment_view_to_world) { + text << "\t uniform float3x3 trans_view_to_world,\n"; } if (need_tangents) { text << "\t in float4 l_tangent : " << tangent_freg << ",\n"; @@ -1119,6 +1157,17 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { if (need_eye_normal && pack_eye_normal) { text << "\t float3 l_eye_normal = float3(l_tangent.w, l_binormal.w, l_eye_position.w);\n"; } + if (need_eye_normal) { + text << "\t // Correct the surface normal for interpolation effects\n"; + text << "\t l_eye_normal = normalize(l_eye_normal);\n"; + } + if (need_eye_reflection || + (need_eye_position && have_specular && (key._material_flags & Material::F_local) != 0 && !key._lights.empty())) { + text << "\t float3 norm_eye_position = normalize(l_eye_position.xyz);\n"; + } + if (need_eye_reflection) { + text << "\t float3 eye_reflection = norm_eye_position - l_eye_normal * 2 * dot(l_eye_normal, norm_eye_position);\n"; + } text << "\t float4 result;\n"; if (key._outputs & (AuxBitplaneAttrib::ABO_aux_normal | AuxBitplaneAttrib::ABO_aux_glow)) { @@ -1137,17 +1186,29 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { // Cg seems to be able to optimize this temporary away when appropriate. text << "\t float4 texcoord" << i << " = l_" << tex._texcoord_name->join("_") << ";\n"; break; - case TexGenAttrib::M_world_position: - text << "\t float4 texcoord" << i << " = l_world_position;\n"; + case TexGenAttrib::M_eye_sphere_map: + text << "\t float4 texcoord" << i << " = float4(eye_reflection.xz * (1.0f / (2.0f * length(eye_reflection + float3(0, -1, 0)))) + float2(0.5f, 0.5f), 0.0f, 1.0f);\n"; + break; + case TexGenAttrib::M_world_cube_map: + text << "\t float4 texcoord" << i << " = float4(mul(trans_view_to_world, eye_reflection), 1.0f);\n"; + break; + case TexGenAttrib::M_eye_cube_map: + text << "\t float4 texcoord" << i << " = float4(eye_reflection, 1.0f);\n"; break; case TexGenAttrib::M_world_normal: text << "\t float4 texcoord" << i << " = l_world_normal;\n"; break; + case TexGenAttrib::M_eye_normal: + text << "\t float4 texcoord" << i << " = float4(l_eye_normal, 1.0f);\n"; + break; + case TexGenAttrib::M_world_position: + text << "\t float4 texcoord" << i << " = l_world_position;\n"; + break; case TexGenAttrib::M_eye_position: text << "\t float4 texcoord" << i << " = float4(l_eye_position.xyz, 1.0f);\n"; break; - case TexGenAttrib::M_eye_normal: - text << "\t float4 texcoord" << i << " = float4(l_eye_normal, 1.0f);\n"; + case TexGenAttrib::M_constant: + text << "\t float4 texcoord" << i << " = texconst_" << i << ";\n"; break; default: text << "\t float4 texcoord" << i << " = float4(0, 0, 0, 0);\n"; @@ -1240,10 +1301,6 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << ");\n"; } } - if (need_eye_normal) { - text << "\t // Correct the surface normal for interpolation effects\n"; - text << "\t l_eye_normal = normalize(l_eye_normal);\n"; - } if (need_tangents) { text << "\t // Translate tangent-space normal in map to view-space.\n"; @@ -1338,7 +1395,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t tot_diffuse += lcolor;\n"; if (have_specular) { if (key._material_flags & Material::F_local) { - text << "\t lhalf = normalize(lvec - normalize(l_eye_position.xyz));\n"; + text << "\t lhalf = normalize(lvec - norm_eye_position);\n"; } else { text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n"; } @@ -1373,7 +1430,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t tot_diffuse += lcolor;\n"; if (have_specular) { if (key._material_flags & Material::F_local) { - text << "\t lhalf = normalize(lvec - normalize(l_eye_position.xyz));\n"; + text << "\t lhalf = normalize(lvec - norm_eye_position);\n"; } else { text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n"; } @@ -1413,7 +1470,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t tot_diffuse += lcolor;\n"; if (have_specular) { if (key._material_flags & Material::F_local) { - text << "\t lhalf = normalize(lvec - normalize(l_eye_position.xyz));\n"; + text << "\t lhalf = normalize(lvec - norm_eye_position);\n"; } else { text << "\t lhalf = normalize(lvec - float3(0,1,0));\n"; } @@ -1683,8 +1740,8 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } // Apply fog. - if (key._fog_mode != 0) { - Fog::Mode fog_mode = (Fog::Mode)(key._fog_mode - 1); + if ((key._fog_mode & 0xffff) != 0) { + Fog::Mode fog_mode = (Fog::Mode)((key._fog_mode & 0xffff) - 1); switch (fog_mode) { case Fog::M_linear: text << "\t result.rgb = lerp(attr_fogcolor.rgb, result.rgb, saturate((attr_fog.z - l_hpos.z) * attr_fog.w));\n"; @@ -1729,6 +1786,9 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { if (flags != 0) { shattr = DCAST(ShaderAttrib, shattr)->set_flag(flags, true); } + if (need_point_size) { + shattr = DCAST(ShaderAttrib, shattr)->set_flag(ShaderAttrib::F_shader_point_size, true); + } reset_register_allocator(); diff --git a/panda/src/pgraphnodes/shaderGenerator.h b/panda/src/pgraphnodes/shaderGenerator.h index c4bbecf7a1..a41445d7ca 100644 --- a/panda/src/pgraphnodes/shaderGenerator.h +++ b/panda/src/pgraphnodes/shaderGenerator.h @@ -150,6 +150,7 @@ protected: bool _lighting; bool _have_separate_ambient; + // Also contains bit 0x10000 indicating perspective point mode int _fog_mode; int _outputs; diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index b96c4c4f82..9d0b161101 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -133,12 +133,6 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, */ x11GraphicsWindow:: ~x11GraphicsWindow() { - if (!_cursor_filenames.empty()) { - LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); - for (auto item : _cursor_filenames) { - XFreeCursor(_display, item.second); - } - } } /** @@ -1122,6 +1116,11 @@ close_window() { _orig_size_id = -1; } + for (auto item : _cursor_filenames) { + XFreeCursor(_display, item.second); + } + _cursor_filenames.clear(); + GraphicsWindow::close_window(); } diff --git a/pandatool/src/deploy-stub/deploy-stub.c b/pandatool/src/deploy-stub/deploy-stub.c index c021e3b7fb..484b08d159 100644 --- a/pandatool/src/deploy-stub/deploy-stub.c +++ b/pandatool/src/deploy-stub/deploy-stub.c @@ -82,6 +82,16 @@ static struct _inittab extensions[] = { static wchar_t *log_pathw = NULL; #endif +#if PY_VERSION_HEX >= 0x030b0000 +typedef struct { + const char *name; + const unsigned char *code; + int size; +} ModuleDef; +#else +typedef struct _frozen ModuleDef; +#endif + /** * Sets the main_dir field of the blobinfo structure, but only if it wasn't * already set. @@ -627,7 +637,7 @@ int wmain(int argc, wchar_t *argv[]) { int main(int argc, char *argv[]) { #endif int retval; - struct _frozen *moddef; + ModuleDef *moddef; const char *log_filename; void *blob = NULL; log_filename = NULL; @@ -677,6 +687,9 @@ int main(int argc, char *argv[]) { // Offset the pointers in the module table using the base mmap address. moddef = blobinfo.pointers[0]; +#if PY_VERSION_HEX < 0x030b0000 + PyImport_FrozenModules = moddef; +#endif while (moddef->name) { moddef->name = (char *)((uintptr_t)moddef->name + (uintptr_t)blob); if (moddef->code != 0) { @@ -685,6 +698,24 @@ int main(int argc, char *argv[]) { //printf("MOD: %s %p %d\n", moddef->name, (void*)moddef->code, moddef->size); moddef++; } + + // In Python 3.11, we need to convert this to the new structure format. +#if PY_VERSION_HEX >= 0x030b0000 + ModuleDef *moddef_end = moddef; + ptrdiff_t num_modules = moddef - (ModuleDef *)blobinfo.pointers[0]; + struct _frozen *new_moddef = (struct _frozen *)calloc(num_modules + 1, sizeof(struct _frozen)); + PyImport_FrozenModules = new_moddef; + for (moddef = blobinfo.pointers[0]; moddef < moddef_end; ++moddef) { + new_moddef->name = moddef->name; + new_moddef->code = moddef->code; + new_moddef->size = moddef->size < 0 ? -(moddef->size) : moddef->size; + new_moddef->is_package = moddef->size < 0; + new_moddef->get_code = NULL; + new_moddef++; + } +#endif + } else { + PyImport_FrozenModules = blobinfo.pointers[0]; } if (log_filename != NULL) { @@ -707,12 +738,16 @@ int main(int argc, char *argv[]) { #endif // Run frozen application - PyImport_FrozenModules = blobinfo.pointers[0]; retval = Py_FrozenMain(argc, argv); fflush(stdout); fflush(stderr); +#if PY_VERSION_HEX >= 0x030b0000 + free((void *)PyImport_FrozenModules); + PyImport_FrozenModules = NULL; +#endif + unmap_blob(blob); return retval; }