From be58900723e99145fbef6ff9bf1f634566fa259e Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Sep 2015 03:52:30 +0200 Subject: [PATCH 1/5] Implement custom font settings for splash window on Windows --- direct/src/plugin/p3dWinSplashWindow.cxx | 16 +++++++++++++--- direct/src/plugin/p3dWinSplashWindow.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/direct/src/plugin/p3dWinSplashWindow.cxx b/direct/src/plugin/p3dWinSplashWindow.cxx index eb071711db..999abdb86f 100644 --- a/direct/src/plugin/p3dWinSplashWindow.cxx +++ b/direct/src/plugin/p3dWinSplashWindow.cxx @@ -34,6 +34,7 @@ P3DWinSplashWindow(P3DInstance *inst, bool make_visible) : _thread = NULL; _thread_id = 0; _hwnd = NULL; + _font = NULL; _fg_brush = NULL; _bg_brush = NULL; _bar_brush = NULL; @@ -498,6 +499,17 @@ make_window() { ShowWindow(_hwnd, SW_HIDE); } + // Load the requested font. + _font = CreateFontA(-_font_size, 0, 0, 0, _font_weight, + (_font_style != FS_normal), FALSE, FALSE, + ANSI_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, + CLEARTYPE_QUALITY, VARIABLE_PITCH, _font_family.c_str()); + + if (_font == NULL) { + nout << "CreateFont failed: " << GetLastError() << "\n"; + _font = (HFONT)GetStockObject(ANSI_VAR_FONT); + } + _fg_brush = CreateSolidBrush(RGB(_fgcolor_r, _fgcolor_g, _fgcolor_b)); _bg_brush = CreateSolidBrush(RGB(_bgcolor_r, _bgcolor_g, _bgcolor_b)); _bar_brush = CreateSolidBrush(RGB(_barcolor_r, _barcolor_g, _barcolor_b)); @@ -840,12 +852,10 @@ paint_progress_bar(HDC dc) { if (!_drawn_label.empty()) { // Now draw the install_label right above it. - const char *text = _drawn_label.c_str(); - HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT); // Measure the text, for centering. - SelectObject(dc, font); + SelectObject(dc, _font); SIZE text_size; GetTextExtentPoint32(dc, text, strlen(text), &text_size); diff --git a/direct/src/plugin/p3dWinSplashWindow.h b/direct/src/plugin/p3dWinSplashWindow.h index 9c27f4578e..33c9f9d584 100644 --- a/direct/src/plugin/p3dWinSplashWindow.h +++ b/direct/src/plugin/p3dWinSplashWindow.h @@ -109,6 +109,7 @@ private: HANDLE _thread; DWORD _thread_id; HWND _hwnd; + HFONT _font; HBRUSH _fg_brush; HBRUSH _bg_brush; HBRUSH _bar_brush; From f9f62f17f1feb808fde79af5b3a6a535f6121855 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Sep 2015 22:27:03 +0200 Subject: [PATCH 2/5] Implement font customization options in MacOSX splash window Also, switch to non-deprecated CoreText API --- direct/src/plugin/p3dOsxSplashWindow.cxx | 168 +++++++++++++---------- direct/src/plugin/p3dOsxSplashWindow.h | 2 + 2 files changed, 100 insertions(+), 70 deletions(-) diff --git a/direct/src/plugin/p3dOsxSplashWindow.cxx b/direct/src/plugin/p3dOsxSplashWindow.cxx index 6b979b2a7b..53f9976d4c 100644 --- a/direct/src/plugin/p3dOsxSplashWindow.cxx +++ b/direct/src/plugin/p3dOsxSplashWindow.cxx @@ -36,6 +36,7 @@ P3DOsxSplashWindow:: P3DOsxSplashWindow(P3DInstance *inst, bool make_visible) : P3DSplashWindow(inst, make_visible) { + _font_attribs = NULL; _install_progress = 0; _progress_known = true; _received_data = 0; @@ -59,6 +60,9 @@ P3DOsxSplashWindow:: DisposeWindow(_toplevel_window); _toplevel_window = NULL; } + if (_font_attribs != NULL) { + CFRelease(_font_attribs); + } } //////////////////////////////////////////////////////////////////// @@ -123,6 +127,41 @@ set_wparams(const P3DWindowParams &wparams) { } } } + + // Determine the attributes of the font we're going to use. + int symbolic = 0; + if (_font_style != FS_normal) { + symbolic |= kCTFontItalicTrait; + } + if (_font_weight > 500) { + symbolic |= kCTFontBoldTrait; + } + CFNumberRef symbolic_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &symbolic); + + CFStringRef traits_keys[1] = { kCTFontSymbolicTrait }; + CFTypeRef traits_values[1] = { symbolic_ref }; + CFDictionaryRef traits = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&traits_keys, (const void **)&traits_values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef family = CFStringCreateWithCString(NULL, _font_family.c_str(), kCFStringEncodingUTF8); + + CFStringRef attribs_keys[2] = { kCTFontFamilyNameAttribute, kCTFontTraitsAttribute }; + CFTypeRef attribs_values[2] = { family, traits }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&attribs_keys, (const void **)&attribs_values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + // Create the font object. + CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes(attribs); + CTFontRef font = CTFontCreateWithFontDescriptor(font_desc, _font_size, NULL); + + CFStringRef keys[1] = { kCTFontAttributeName }; + CFTypeRef values[1] = { font }; + _font_attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFRelease(font); + CFRelease(font_desc); + CFRelease(attribs); + CFRelease(traits); + CFRelease(family); + CFRelease(symbolic_ref); } //////////////////////////////////////////////////////////////////// @@ -171,6 +210,9 @@ set_image_filename(const string &image_filename, ImagePlacement image_placement) case IP_button_click: load_image(_button_click_image, image_filename); break; + + default: + return; } refresh(); @@ -333,10 +375,8 @@ paint_window_osx_cgcontext(CGContextRef context) { CGColorRef bg = CGColorCreate(rgb_space, bg_components); CGRect region = { { 0, 0 }, { _win_width, _win_height } }; - CGContextBeginPath(context); CGContextSetFillColorWithColor(context, bg); - CGContextAddRect(context, region); - CGContextFillPath(context); + CGContextFillRect(context, region); CGColorRelease(bg); CGColorSpaceRelease(rgb_space); @@ -445,8 +485,6 @@ handle_event_osx_event_record(const P3D_event_data &event) { //////////////////////////////////////////////////////////////////// bool P3DOsxSplashWindow:: handle_event_osx_cocoa(const P3D_event_data &event) { - bool retval = false; - assert(event._event_type == P3D_ET_osx_cocoa); const P3DCocoaEvent &ce = event._event._osx_cocoa._event; @@ -455,33 +493,31 @@ handle_event_osx_cocoa(const P3D_event_data &event) { if (_visible) { CGContextRef context = ce.data.draw.context; paint_window_osx_cgcontext(context); - retval = true; + return true; + } else { + return false; } - break; case P3DCocoaEventMouseDown: set_mouse_data((int)ce.data.mouse.pluginX, (int)ce.data.mouse.pluginY, true); - retval = true; - break; + return true; case P3DCocoaEventMouseUp: set_mouse_data((int)ce.data.mouse.pluginX, (int)ce.data.mouse.pluginY, false); - retval = true; - break; + return true; case P3DCocoaEventMouseMoved: case P3DCocoaEventMouseDragged: set_mouse_data((int)ce.data.mouse.pluginX, (int)ce.data.mouse.pluginY, _mouse_down); - retval = true; - break; + return true; case P3DCocoaEventFocusChanged: _mouse_active = (ce.data.focus.hasFocus != 0); - retval = true; - break; - } + return true; - return retval; + default: + return false; + } } //////////////////////////////////////////////////////////////////// @@ -612,42 +648,33 @@ paint_image(CGContextRef context, const OsxImageData &image) { //////////////////////////////////////////////////////////////////// void P3DOsxSplashWindow:: paint_progress_bar(CGContextRef context) { - // Get some colors we'll need. We can't just use - // CGColorGetConstantColor(), since that requires 10.5. CGFloat fg_components[] = { _fgcolor_r / 255.0f, _fgcolor_g / 255.0f, _fgcolor_b / 255.0f, 1 }; CGFloat bg_components[] = { _bgcolor_r / 255.0f, _bgcolor_g / 255.0f, _bgcolor_b / 255.0f, 1 }; CGFloat bar_components[] = { _barcolor_r / 255.0f, _barcolor_g / 255.0f, _barcolor_b / 255.0f, 1 }; + CGFloat bar_bg_components[] = { _bar_bgcolor_r / 255.0f, _bar_bgcolor_g / 255.0f, _bar_bgcolor_b / 255.0f, 1 }; CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB(); CGColorRef fg = CGColorCreate(rgb_space, fg_components); CGColorRef bg = CGColorCreate(rgb_space, bg_components); CGColorRef bar = CGColorCreate(rgb_space, bar_components); + CGColorRef bar_bg = CGColorCreate(rgb_space, bar_bg_components); + // Get the proper placement for the progress bar. int bar_x, bar_y, bar_width, bar_height; get_bar_placement(bar_x, bar_y, bar_width, bar_height); - // We offset the bar by half a pixel, so we'll be drawing the - // one-pixel line through the middle of a pixel, and it won't try to - // antialias itself into a half-black two-pixel line. - float bar_xf = bar_x + 0.5; - float bar_yf = bar_y - 0.5; - - CGRect bar_rect = { { bar_xf, bar_yf }, { bar_width, bar_height } }; + CGRect bar_rect = { { bar_x, bar_y }, { bar_width, bar_height } }; // Clear the entire progress bar to white (or the background color). - CGContextBeginPath(context); - CGContextSetFillColorWithColor(context, bg); - CGContextAddRect(context, bar_rect); - CGContextFillPath(context); + CGContextSetFillColorWithColor(context, bar_bg); + CGContextFillRect(context, bar_rect); // Draw the interior of the progress bar in blue (or the bar color). if (_progress_known) { int progress_width = (int)(bar_width * _install_progress + 0.5); if (progress_width != 0) { - CGRect prog = { { bar_xf, bar_yf }, { progress_width, bar_height } }; - CGContextBeginPath(context); + CGRect prog = { { bar_x, bar_y }, { progress_width, bar_height } }; CGContextSetFillColorWithColor(context, bar); - CGContextAddRect(context, prog); - CGContextFillPath(context); + CGContextFillRect(context, prog); } } else { // Progress is unknown. Draw a moving block, not a progress bar @@ -660,57 +687,58 @@ paint_progress_bar(CGContextRef context) { progress = block_travel * 2 - progress; } - CGRect prog = { { bar_xf + progress, bar_yf }, { block_width, bar_height } }; - CGContextBeginPath(context); + CGRect prog = { { bar_x + progress, bar_y }, { block_width, bar_height } }; CGContextSetFillColorWithColor(context, bar); - CGContextAddRect(context, prog); - CGContextFillPath(context); + CGContextFillRect(context, prog); } - + // Draw the black stroke around the progress bar. - CGContextBeginPath(context); - CGContextSetLineWidth(context, 1); - CGContextSetStrokeColorWithColor(context, fg); - CGContextAddRect(context, bar_rect); - CGContextStrokePath(context); + if (_bar_border > 0) { + // We offset the border by half a pixel, so we'll be drawing the + // one-pixel line through the middle of a pixel, and it won't try to + // antialias itself into a half-black two-pixel line. + CGRect border_rect = { { bar_x - 0.5, bar_y - 0.5 }, + { bar_width + 1, bar_height + 1 } }; + + CGContextBeginPath(context); + CGContextSetLineWidth(context, 1); + CGContextSetStrokeColorWithColor(context, fg); + + for (int i = 0; i < _bar_border; ++i) { + CGContextAddRect(context, border_rect); + border_rect.origin.x -= 1; + border_rect.origin.y -= 1; + border_rect.size.width += 2; + border_rect.size.height += 2; + } + CGContextStrokePath(context); + } if (!_install_label.empty()) { - // Now draw the install_label right above it. - // Need to invert the text so it won't be upside-down. CGAffineTransform text_xform = CGAffineTransformMakeScale(1, -1); CGContextSetTextMatrix(context, text_xform); - // Choose a suitable font. - float text_height = 15.0; - CGContextSelectFont(context, _font_family.c_str(), text_height, kCGEncodingMacRoman); + // Now draw the install_label right above it. + CFStringRef string = CFStringCreateWithCString(NULL, _install_label.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef attr_string = CFAttributedStringCreate(NULL, string, _font_attribs); + CTLineRef line = CTLineCreateWithAttributedString(attr_string); - // Measure the text, for centering. - CGContextSetTextPosition(context, 0, 0); - CGContextSetTextDrawingMode(context, kCGTextInvisible); - CGContextShowText(context, _install_label.data(), _install_label.length()); - CGPoint end_point = CGContextGetTextPosition(context); - float text_width = end_point.x; - - int text_x = (int)(_win_width - text_width) / 2; - int text_y = (int)(bar_y - text_height * 1.5); - - // Clear the rectangle behind the text to bg. - CGRect text_rect = { { text_x - 2, text_y - 2 }, { text_width + 4, text_height + 4 } }; - - CGContextBeginPath(context); - CGContextAddRect(context, text_rect); - CGContextSetFillColorWithColor(context, bg); - CGContextFillPath(context); + // Determine the placement based on the size of the text. + CGRect bounds = CTLineGetImageBounds(line, context); + float text_x = (_win_width - bounds.size.width) / 2.0f - bounds.origin.x; + float text_y = bar_y + bounds.origin.y - 4 - _bar_border; // And finally, draw the text. - CGContextSetTextDrawingMode(context, kCGTextFill); - CGContextSetFillColorWithColor(context, fg); + CGContextSetTextPosition(context, text_x, text_y); + CTLineDraw(line, context); - CGContextShowTextAtPoint(context, text_x, text_y + text_height, - _install_label.data(), _install_label.length()); + CFRelease(line); + CFRelease(attr_string); + CFRelease(string); } + CGColorRelease(bar_bg); CGColorRelease(bar); CGColorRelease(bg); CGColorRelease(fg); diff --git a/direct/src/plugin/p3dOsxSplashWindow.h b/direct/src/plugin/p3dOsxSplashWindow.h index 03149bfc98..8c4cab382b 100644 --- a/direct/src/plugin/p3dOsxSplashWindow.h +++ b/direct/src/plugin/p3dOsxSplashWindow.h @@ -83,6 +83,8 @@ private: OsxImageData _button_rollover_image; OsxImageData _button_click_image; + CFDictionaryRef _font_attribs; + string _install_label; double _install_progress; bool _progress_known; From e1d7c737cf16cbc46f1b22f89205c146c88999bc Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 3 Sep 2015 03:29:42 +0200 Subject: [PATCH 3/5] Fix "... is not a Multifile" error in pdeployed executables --- direct/src/plugin_standalone/panda3dBase.cxx | 10 +++++----- direct/src/plugin_standalone/panda3dBase.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/direct/src/plugin_standalone/panda3dBase.cxx b/direct/src/plugin_standalone/panda3dBase.cxx index 6b38e221f2..707eddedd2 100644 --- a/direct/src/plugin_standalone/panda3dBase.cxx +++ b/direct/src/plugin_standalone/panda3dBase.cxx @@ -342,7 +342,7 @@ make_parent_window() { //////////////////////////////////////////////////////////////////// P3D_instance *Panda3DBase:: create_instance(const string &p3d, bool start_instance, - char **args, int num_args, const int &p3d_offset) { + char **args, int num_args, int p3d_offset) { // Check to see if the p3d filename we were given is a URL, or a // local file. Filename p3d_filename = Filename::from_os_specific(p3d); @@ -356,9 +356,9 @@ create_instance(const string &p3d, bool start_instance, p3d_filename.make_absolute(); os_p3d_filename = p3d_filename.to_os_specific(); - } + } if (is_local) { - read_p3d_info(p3d_filename); + read_p3d_info(p3d_filename, p3d_offset); } // Build up the token list. @@ -454,9 +454,9 @@ delete_instance(P3D_instance *inst) { // parameters (like width and height). //////////////////////////////////////////////////////////////////// bool Panda3DBase:: -read_p3d_info(const Filename &p3d_filename) { +read_p3d_info(const Filename &p3d_filename, int p3d_offset) { PT(Multifile) mf = new Multifile; - if (!mf->open_read(p3d_filename)) { + if (!mf->open_read(p3d_filename, p3d_offset)) { return false; } int si = mf->find_subfile("p3d_info.xml"); diff --git a/direct/src/plugin_standalone/panda3dBase.h b/direct/src/plugin_standalone/panda3dBase.h index f53e59b14c..b3ace6256f 100644 --- a/direct/src/plugin_standalone/panda3dBase.h +++ b/direct/src/plugin_standalone/panda3dBase.h @@ -49,10 +49,10 @@ protected: P3D_instance * create_instance(const string &p3d, bool start_instance, - char **args, int num_args, const int &p3d_offset = 0); + char **args, int num_args, int p3d_offset = 0); void delete_instance(P3D_instance *instance); - bool read_p3d_info(const Filename &p3d_filename); + bool read_p3d_info(const Filename &p3d_filename, int p3d_offset = 0); bool parse_token(const char *arg); bool parse_int_pair(const char *arg, int &x, int &y); string lookup_token(const string &keyword) const; From c33f3b3dca1b80c467c002edf6a577430b18e983 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 3 Sep 2015 03:49:01 +0200 Subject: [PATCH 4/5] Force httplib2 and pyglet to be platform-independent packages --- direct/src/p3d/thirdparty.pdef | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/direct/src/p3d/thirdparty.pdef b/direct/src/p3d/thirdparty.pdef index b657aac95b..bc72b39eb7 100644 --- a/direct/src/p3d/thirdparty.pdef +++ b/direct/src/p3d/thirdparty.pdef @@ -137,7 +137,7 @@ class pyopengl(package): module('OpenGL.GLU', 'OpenGL.GLUT', 'OpenGL.GLE', 'OpenGL.GLX') class httplib2(package): - config(display_name = "httplib2") + config(display_name = "httplib2", platform_specific = False) require('panda3d') module('httplib2', required = True) @@ -149,7 +149,7 @@ class box2d(package): module('Box2D', required = True) class pyglet(package): - config(display_name = "pyglet") - require('panda3d') + config(display_name = "pyglet", platform_specific = False) + require('panda3d', 'morepy') module('pyglet', required = True) From e1c0ae7f1be9e8478778306a0d42acc89a97bfb8 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 5 Sep 2015 15:28:12 +0200 Subject: [PATCH 5/5] Add F_hardware_skinning/p3d_TransformTable to GLSL on 1.9 branch, as requested Uses a hack to prevent breaking ABI compat --- panda/src/display/standardMunger.cxx | 40 ++++++--- panda/src/glstuff/glGeomMunger_src.cxx | 2 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 6 +- panda/src/glstuff/glShaderContext_src.cxx | 84 +++++++++++++++++++ panda/src/glstuff/glShaderContext_src.h | 7 ++ panda/src/pgraph/shaderAttrib.h | 1 + 6 files changed, 125 insertions(+), 15 deletions(-) diff --git a/panda/src/display/standardMunger.cxx b/panda/src/display/standardMunger.cxx index 922150a114..c33c95f7e2 100644 --- a/panda/src/display/standardMunger.cxx +++ b/panda/src/display/standardMunger.cxx @@ -37,14 +37,13 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state, StateMunger(gsg), _num_components(num_components), _numeric_type(numeric_type), - _contents(contents) + _contents(contents), + _munge_color(false), + _munge_color_scale(false), + _auto_shader(false) { _render_mode = DCAST(RenderModeAttrib, state->get_attrib(RenderModeAttrib::get_class_slot())); - _munge_color = false; - _munge_color_scale = false; - _auto_shader = false; - if (!get_gsg()->get_runtime_color_scale()) { // We might need to munge the colors. const ColorAttrib *color_attrib = (const ColorAttrib *) @@ -98,6 +97,11 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state, if (shader_attrib->auto_shader()) { _auto_shader = true; } + if (shader_attrib->get_flag(ShaderAttrib::F_hardware_skinning)) { + // Hijack this field, such as not to break ABI compatibility. + // This hack is not present in 1.10. + _num_components |= 0x10000; + } } //////////////////////////////////////////////////////////////////// @@ -120,17 +124,20 @@ munge_data_impl(const GeomVertexData *data) { CPT(GeomVertexData) new_data = data; if (_munge_color) { - new_data = new_data->set_color(_color, _num_components, _numeric_type, - _contents); + new_data = new_data->set_color(_color, _num_components & 0xffff, + _numeric_type, _contents); } else if (_munge_color_scale) { - new_data = new_data->scale_color(_color_scale, _num_components, + new_data = new_data->scale_color(_color_scale, _num_components & 0xffff, _numeric_type, _contents); } GeomVertexAnimationSpec animation = new_data->get_format()->get_animation(); - if (hardware_animated_vertices && - animation.get_animation_type() == AT_panda && - new_data->get_slider_table() == (SliderTable *)NULL) { + if (_num_components & 0x10000) { + animation.set_hardware(4, true); + + } else if (hardware_animated_vertices && + animation.get_animation_type() == AT_panda && + new_data->get_slider_table() == (SliderTable *)NULL) { // Maybe we can animate the vertices with hardware. const TransformBlendTable *table = new_data->get_transform_blend_table(); if (table != (TransformBlendTable *)NULL && @@ -306,7 +313,11 @@ compare_to_impl(const GeomMunger *other) const { return compare; } } - + bool shader_skinning = ((_num_components & 0x10000) != 0); + bool om_shader_skinning = ((om->_num_components & 0x10000) != 0); + if (shader_skinning != om_shader_skinning) { + return (int)shader_skinning - (int)om_shader_skinning; + } if (_auto_shader != om->_auto_shader) { return (int)_auto_shader - (int)om->_auto_shader; } @@ -345,6 +356,11 @@ geom_compare_to_impl(const GeomMunger *other) const { return compare; } } + bool shader_skinning = ((_num_components & 0x10000) != 0); + bool om_shader_skinning = ((om->_num_components & 0x10000) != 0); + if (shader_skinning != om_shader_skinning) { + return (int)shader_skinning - (int)om_shader_skinning; + } return StateMunger::geom_compare_to_impl(other); } diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index b2deb6e29f..a3b53ac464 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -118,7 +118,7 @@ munge_format_impl(const GeomVertexFormat *orig, if (animation.get_num_transforms() > 1) { PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat; new_array_format->add_column - (InternalName::get_transform_weight(), animation.get_num_transforms() - 1, + (InternalName::get_transform_weight(), animation.get_num_transforms(), NT_stdfloat, C_other); if (animation.get_indexed_transforms()) { diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index a1a2e7e7a9..2d0c82e0b9 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3249,11 +3249,11 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, } } +#ifndef OPENGLES const GeomVertexAnimationSpec &animation = _data_reader->get_format()->get_animation(); bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware); -#ifndef OPENGLES - if (hardware_animation) { + if (hardware_animation && _current_shader_context == NULL) { // Set up the transform matrices for vertex blending. nassertr(_supports_vertex_blend, false); glEnable(GL_VERTEX_BLEND_ARB); @@ -3335,6 +3335,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, GLPf(LoadMatrix)(_internal_transform->get_mat().get_data()); } } +#else + const bool hardware_animation = false; #endif #ifndef OPENGLES_2 diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 5df6c93871..298eda1f9e 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -197,6 +197,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext _glsl_program = 0; _uses_standard_vertex_arrays = false; _has_divisor = false; + _transform_table_index = -1; + _slider_table_index = -1; nassertv(s->get_language() == Shader::SL_GLSL); @@ -527,6 +529,26 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext s->_mat_spec.push_back(bind); continue; } + if (noprefix == "TransformTable") { + if (param_type != GL_FLOAT_MAT4) { + GLCAT.error() + << "p3d_TransformTable should be uniform mat4\n"; + continue; + } + _transform_table_index = p; + _transform_table_size = param_size; + continue; + } + if (noprefix == "SliderTable") { + if (param_type != GL_FLOAT) { + GLCAT.error() + << "p3d_SliderTable should be uniform float\n"; + continue; + } + _slider_table_index = p; + _slider_table_size = param_size; + continue; + } GLCAT.error() << "Unrecognized uniform name '" << param_name_cstr << "'!\n"; continue; @@ -1324,6 +1346,58 @@ issue_parameters(int altered) { _glgsg->report_my_gl_errors(); } +//////////////////////////////////////////////////////////////////// +// Function: GLShaderContext::update_transform_table +// Access: Public +// Description: Changes the active transform table, used for hardware +// skinning. +//////////////////////////////////////////////////////////////////// +void CLP(ShaderContext):: +update_transform_table(const TransformTable *table) { + LMatrix4f *matrices = (LMatrix4f *)alloca(_transform_table_size * 64); + + int i = 0; + if (table != NULL) { + int num_transforms = min(_transform_table_size, table->get_num_transforms()); + for (; i < num_transforms; ++i) { +#ifdef STDFLOAT_DOUBLE + LMatrix4 matrix; + table->get_transform(i)->get_matrix(matrix); + matrices[i] = LCAST(float, matrix); +#else + table->get_transform(i)->get_matrix(matrices[i]); +#endif + } + } + for (; i < _transform_table_size; ++i) { + matrices[i] = LMatrix4f::ident_mat(); + } + + _glgsg->_glUniformMatrix4fv(_transform_table_index, _transform_table_size, + GL_FALSE, (float *)matrices); +} + +//////////////////////////////////////////////////////////////////// +// Function: GLShaderContext::update_slider_table +// Access: Public +// Description: Changes the active slider table, used for hardware +// skinning. +//////////////////////////////////////////////////////////////////// +void CLP(ShaderContext):: +update_slider_table(const SliderTable *table) { + float *sliders = (float *)alloca(_slider_table_size * 4); + memset(sliders, 0, _slider_table_size * 4); + + if (table != NULL) { + int num_sliders = min(_slider_table_size, table->get_num_sliders()); + for (int i = 0; i < num_sliders; ++i) { + sliders[i] = table->get_slider(i)->get_slider(); + } + } + + _glgsg->_glUniform1fv(_slider_table_index, _slider_table_size, sliders); +} + //////////////////////////////////////////////////////////////////// // Function: GLShaderContext::disable_shader_vertex_arrays // Access: Public @@ -1441,6 +1515,16 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { } } + if (_transform_table_index >= 0) { + const TransformTable *table = _glgsg->_data_reader->get_transform_table(); + update_transform_table(table); + } + + if (_slider_table_index >= 0) { + const SliderTable *table = _glgsg->_data_reader->get_slider_table(); + update_slider_table(table); + } + _glgsg->report_my_gl_errors(); return true; diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index e2a9aadc9d..62d54ed675 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -41,6 +41,8 @@ public: void bind(bool reissue_parameters = true); void unbind(); void issue_parameters(int altered); + void update_transform_table(const TransformTable *table); + void update_slider_table(const SliderTable *table); void disable_shader_vertex_arrays(); bool update_shader_vertex_arrays(ShaderContext *prev, bool force); void disable_shader_texture_bindings(); @@ -65,6 +67,11 @@ private: //typedef pvector ParamContexts; //ParamContexts _params; + GLint _transform_table_index; + GLint _slider_table_index; + GLsizei _transform_table_size; + GLsizei _slider_table_size; + pvector _glsl_parameter_map; pmap _glsl_uniform_handles; diff --git a/panda/src/pgraph/shaderAttrib.h b/panda/src/pgraph/shaderAttrib.h index c6bb2eb583..9d677a411e 100644 --- a/panda/src/pgraph/shaderAttrib.h +++ b/panda/src/pgraph/shaderAttrib.h @@ -48,6 +48,7 @@ PUBLISHED: enum { F_disable_alpha_write = 0, // Suppress writes to color buffer alpha channel. F_subsume_alpha_test = 1, // Shader promises to subsume the alpha test using TEXKILL + F_hardware_skinning = 2, // Shader needs pre-animated vertices }; INLINE bool has_shader() const;