Panda3D

pgFrameStyle.cxx

00001 // Filename: pgFrameStyle.cxx
00002 // Created by:  drose (03Jul01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pgFrameStyle.h"
00016 #include "geomNode.h"
00017 #include "pandaNode.h"
00018 #include "transparencyAttrib.h"
00019 #include "pointerTo.h"
00020 #include "nodePath.h"
00021 #include "textureAttrib.h"
00022 #include "renderState.h"
00023 #include "shadeModelAttrib.h"
00024 #include "colorAttrib.h"
00025 #include "geom.h"
00026 #include "geomTristrips.h"
00027 #include "geomVertexWriter.h"
00028 
00029 // Specifies the UV range of textures applied to the frame.  Maybe
00030 // we'll have a reason to make this a parameter of the frame style one
00031 // day, but for now it's hardcoded to fit the entire texture over the
00032 // rectangular frame.
00033 static const LVecBase4f uv_range = LVecBase4f(0.0f, 1.0f, 0.0f, 1.0f);
00034 
00035 ostream &
00036 operator << (ostream &out, PGFrameStyle::Type type) {
00037   switch (type) {
00038   case PGFrameStyle::T_none:
00039     return out << "none";
00040 
00041   case PGFrameStyle::T_flat:
00042     return out << "flat";
00043 
00044   case PGFrameStyle::T_bevel_out:
00045     return out << "bevel_out";
00046 
00047   case PGFrameStyle::T_bevel_in:
00048     return out << "bevel_in";
00049 
00050   case PGFrameStyle::T_groove:
00051     return out << "groove";
00052 
00053   case PGFrameStyle::T_ridge:
00054     return out << "ridge";
00055 
00056   case PGFrameStyle::T_texture_border:
00057     return out << "texture_border";
00058   }
00059 
00060   return out << "**unknown(" << (int)type << ")**";
00061 }
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: PGFrameStyle::get_internal_frame
00065 //       Access: Published
00066 //  Description: Computes the size of the internal frame, given the
00067 //               indicated external frame, appropriate for this kind
00068 //               of frame style.  This simply subtracts the border
00069 //               width for those frame styles that include a border.
00070 ////////////////////////////////////////////////////////////////////
00071 LVecBase4f PGFrameStyle::
00072 get_internal_frame(const LVecBase4f &frame) const {
00073   LPoint2f center((frame[0] + frame[1]) / 2.0f,
00074                   (frame[2] + frame[3]) / 2.0f);
00075   LVecBase4f scaled_frame
00076     ((frame[0] - center[0]) * _visible_scale[0] + center[0],
00077      (frame[1] - center[0]) * _visible_scale[0] + center[0],
00078      (frame[2] - center[1]) * _visible_scale[1] + center[1],
00079      (frame[3] - center[1]) * _visible_scale[1] + center[1]);
00080 
00081   switch (_type) {
00082   case T_none:
00083   case T_flat:
00084     return scaled_frame;
00085 
00086   default:
00087     break;
00088   }
00089 
00090   return LVecBase4f(scaled_frame[0] + _width[0],
00091                     scaled_frame[1] - _width[0],
00092                     scaled_frame[2] + _width[1],
00093                     scaled_frame[3] - _width[1]);
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: PGFrameStyle::output
00098 //       Access: Published
00099 //  Description: 
00100 ////////////////////////////////////////////////////////////////////
00101 void PGFrameStyle::
00102 output(ostream &out) const {
00103   out << _type << " color = " << _color << " width = " << _width;
00104   if (_visible_scale != LVecBase2f(1.0f, 1.0f)) {
00105     out << "visible_scale = " << get_visible_scale();
00106   }
00107   if (has_texture()) {
00108     out << " texture = " << *get_texture();
00109   }
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: PGFrameStyle::xform
00114 //       Access: Public
00115 //  Description: Applies the indicated transform to the FrameStyle.
00116 //               The return value is true if the frame style is
00117 //               transformed, or false if it was not affected by the
00118 //               transform.
00119 ////////////////////////////////////////////////////////////////////
00120 bool PGFrameStyle::
00121 xform(const LMatrix4f &mat) {
00122   // All we can do is scale the X and Y bevel sizes.
00123 
00124   // Extract the X and Z axes from the matrix.
00125   LVector3f x, z;
00126   mat.get_row3(x, 0);
00127   float x_scale = x.length();
00128   
00129   mat.get_row3(z, 2);
00130   float z_scale = z.length();
00131 
00132   _width[0] *= x_scale;
00133   _width[1] *= z_scale;
00134 
00135   switch (_type) {
00136   case T_none:
00137   case T_flat:
00138     return false;
00139 
00140   case T_bevel_out:
00141   case T_bevel_in:
00142   case T_groove:
00143   case T_ridge:
00144   case T_texture_border:
00145     return true;
00146   }
00147 
00148   // Shouldn't get here, but this makes the compiler happy.
00149   return true;
00150 }
00151 
00152 ////////////////////////////////////////////////////////////////////
00153 //     Function: PGFrameStyle::generate_into
00154 //       Access: Public
00155 //  Description: Generates geometry representing a frame of the
00156 //               indicated size, and parents it to the indicated node,
00157 //               with the indicated scene graph sort order.
00158 //
00159 //               The return value is the generated NodePath, if any,
00160 //               or an empty NodePath if nothing is generated.
00161 ////////////////////////////////////////////////////////////////////
00162 NodePath PGFrameStyle::
00163 generate_into(const NodePath &parent, const LVecBase4f &frame,
00164               int sort) {
00165   PT(PandaNode) new_node;
00166 
00167   LPoint2f center((frame[0] + frame[1]) / 2.0f,
00168                   (frame[2] + frame[3]) / 2.0f);
00169   LVecBase4f scaled_frame
00170     ((frame[0] - center[0]) * _visible_scale[0] + center[0],
00171      (frame[1] - center[0]) * _visible_scale[0] + center[0],
00172      (frame[2] - center[1]) * _visible_scale[1] + center[1],
00173      (frame[3] - center[1]) * _visible_scale[1] + center[1]);
00174 
00175   switch (_type) {
00176   case T_none:
00177     return NodePath();
00178 
00179   case T_flat:
00180     new_node = generate_flat_geom(scaled_frame);
00181     break;
00182 
00183   case T_bevel_out:
00184     new_node = generate_bevel_geom(scaled_frame, false);
00185     break;
00186 
00187   case T_bevel_in:
00188     new_node = generate_bevel_geom(scaled_frame, true);
00189     break;
00190 
00191   case T_groove:
00192     new_node = generate_groove_geom(scaled_frame, true);
00193     break;
00194 
00195   case T_ridge:
00196     new_node = generate_groove_geom(scaled_frame, false);
00197     break;
00198 
00199   case T_texture_border:
00200     new_node = generate_texture_border_geom(scaled_frame);
00201     break;
00202 
00203   default:
00204     break;
00205   }
00206 
00207   if (new_node != (PandaNode *)NULL && _color[3] != 1.0f) {
00208     // We've got some alpha on the color; we need transparency.
00209     new_node->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
00210   }
00211 
00212   // Adding the node to the parent keeps the reference count.
00213   return parent.attach_new_node(new_node, sort);
00214 }
00215 
00216 ////////////////////////////////////////////////////////////////////
00217 //     Function: PGFrameStyle::generate_flat_geom
00218 //       Access: Private
00219 //  Description: Generates the GeomNode appropriate to a T_flat
00220 //               frame.
00221 ////////////////////////////////////////////////////////////////////
00222 PT(PandaNode) PGFrameStyle::
00223 generate_flat_geom(const LVecBase4f &frame) {
00224   PT(GeomNode) gnode = new GeomNode("flat");
00225 
00226   float left = frame[0];
00227   float right = frame[1];
00228   float bottom = frame[2];
00229   float top = frame[3];
00230 
00231   CPT(GeomVertexFormat) format;
00232   if (has_texture()) {
00233     format = GeomVertexFormat::get_v3t2();
00234   } else {
00235     format = GeomVertexFormat::get_v3();
00236   }
00237   
00238   PT(GeomVertexData) vdata = new GeomVertexData
00239     ("PGFrame", format, Geom::UH_static);
00240   
00241   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00242   vertex.add_data3f(left, 0.0f, top);
00243   vertex.add_data3f(left, 0.0f, bottom);
00244   vertex.add_data3f(right, 0.0f, top);
00245   vertex.add_data3f(right, 0.0f, bottom);
00246 
00247   if (has_texture()) {
00248     // Generate UV's.
00249     left = uv_range[0];
00250     right = uv_range[1];
00251     bottom = uv_range[2];
00252     top = uv_range[3];
00253     
00254     GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
00255     texcoord.add_data2f(left, top);
00256     texcoord.add_data2f(left, bottom);
00257     texcoord.add_data2f(right, top);
00258     texcoord.add_data2f(right, bottom);
00259   }
00260   
00261   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
00262   strip->add_next_vertices(4);
00263   strip->close_primitive();
00264   
00265   CPT(RenderState) state = RenderState::make(ColorAttrib::make_flat(_color), -1);
00266   if (has_texture()) {
00267     state = state->set_attrib(TextureAttrib::make(get_texture()));
00268   }
00269   PT(Geom) geom = new Geom(vdata);
00270   geom->add_primitive(strip);
00271   gnode->add_geom(geom, state);
00272   
00273   return gnode.p();
00274 }
00275 
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: PGFrameStyle::generate_bevel_geom
00278 //       Access: Private
00279 //  Description: Generates the GeomNode appropriate to a T_bevel_in
00280 //               or T_bevel_out frame.
00281 ////////////////////////////////////////////////////////////////////
00282 PT(PandaNode) PGFrameStyle::
00283 generate_bevel_geom(const LVecBase4f &frame, bool in) {
00284   //
00285   // Colors:
00286   //
00287   // 
00288   //  * * * * * * * * * * * * * * * * * * * * * * *
00289   //  * *                                       * *
00290   //  *   *               ctop                *   *
00291   //  *     *                               *     *
00292   //  *       * * * * * * * * * * * * * * *       *
00293   //  *       *                           *       *
00294   //  *       *                           *       *
00295   //  * cleft *          _color           * cright*
00296   //  *       *                           *       *
00297   //  *       *                           *       *
00298   //  *       * * * * * * * * * * * * * * *       *
00299   //  *     *                               *     *
00300   //  *   *              cbottom              *   *
00301   //  * *                                       * *
00302   //  * * * * * * * * * * * * * * * * * * * * * * *
00303   //
00304   //
00305   // Vertices:
00306   //
00307   //  tristrip 1:
00308   //  4 * * * * * * * * * * * * * * * * * * * * * 6
00309   //  * *                                       *
00310   //  *   *                                   *
00311   //  *     *                               *
00312   //  *       5 * * * * * * * * * * * * * 7
00313   //  *       *
00314   //  *       *
00315   //  *       *
00316   //  *       *
00317   //  *       *
00318   //  *       3 * * * * * * * * * * * * * 1
00319   //  *     *                               *
00320   //  *   *                                   *
00321   //  * *                                       *
00322   //  2 * * * * * * * * * * * * * * * * * * * * * 0
00323   // 
00324   //  tristrip 2:
00325   //                                              1
00326   //                                            * *
00327   //                                          *   *
00328   //                                        *     *
00329   //          5 * * * * * * * * * * * * * 3       *
00330   //          *                           *       *
00331   //          *                           *       *
00332   //          *                           *       *
00333   //          *                           *       *
00334   //          *                           *       *
00335   //          4 * * * * * * * * * * * * * 2       *
00336   //                                        *     *
00337   //                                          *   *
00338   //                                            * *
00339   //                                              0
00340 
00341   PT(GeomNode) gnode = new GeomNode("bevel");
00342 
00343   float left = frame[0];
00344   float right = frame[1];
00345   float bottom = frame[2];
00346   float top = frame[3];
00347 
00348   float cx = (left + right) * 0.5;
00349   float cy = (top + bottom) * 0.5;
00350 
00351   float inner_left = min(left + _width[0], cx);
00352   float inner_right = max(right - _width[0], cx);
00353   float inner_bottom = min(bottom + _width[1], cy);
00354   float inner_top = max(top - _width[1], cy);
00355 
00356   float left_color_scale = 1.2;
00357   float right_color_scale = 0.8;
00358   float bottom_color_scale = 0.7;
00359   float top_color_scale = 1.3;
00360 
00361   if (in) {
00362     right_color_scale = 1.2;
00363     left_color_scale = 0.8;
00364     top_color_scale = 0.7;
00365     bottom_color_scale = 1.3;
00366   }
00367 
00368   // Clamp all colors at white, and don't scale the alpha.
00369   Colorf cleft(min(_color[0] * left_color_scale, 1.0f),
00370                min(_color[1] * left_color_scale, 1.0f),
00371                min(_color[2] * left_color_scale, 1.0f),
00372                _color[3]);
00373 
00374   Colorf cright(min(_color[0] * right_color_scale, 1.0f),
00375                 min(_color[1] * right_color_scale, 1.0f),
00376                 min(_color[2] * right_color_scale, 1.0f),
00377                 _color[3]);
00378 
00379   Colorf cbottom(min(_color[0] * bottom_color_scale, 1.0f),
00380                  min(_color[1] * bottom_color_scale, 1.0f),
00381                  min(_color[2] * bottom_color_scale, 1.0f),
00382                  _color[3]);
00383 
00384   Colorf ctop(min(_color[0] * top_color_scale, 1.0f),
00385               min(_color[1] * top_color_scale, 1.0f),
00386               min(_color[2] * top_color_scale, 1.0f),
00387               _color[3]);
00388 
00389   CPT(GeomVertexFormat) format;
00390   if (has_texture()) {
00391     format = GeomVertexFormat::get_v3cpt2();
00392   } else {
00393     format = GeomVertexFormat::get_v3cp();
00394   }
00395 
00396   PT(GeomVertexData) vdata = new GeomVertexData
00397     ("PGFrame", format, Geom::UH_static);
00398   
00399   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00400   GeomVertexWriter color(vdata, InternalName::get_color());
00401   
00402   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
00403   // Tristrip 1.
00404   vertex.add_data3f(right, 0.0f, bottom);
00405   vertex.add_data3f(inner_right, 0.0f, inner_bottom);
00406   vertex.add_data3f(left, 0.0f, bottom);
00407   vertex.add_data3f(inner_left, 0.0f, inner_bottom);
00408   vertex.add_data3f(left, 0.0f, top);
00409   vertex.add_data3f(inner_left, 0.0f, inner_top);
00410   vertex.add_data3f(right, 0.0f, top);
00411   vertex.add_data3f(inner_right, 0.0f, inner_top);
00412   color.add_data4f(cbottom);
00413   color.add_data4f(cbottom);
00414   color.add_data4f(cbottom);
00415   color.add_data4f(cbottom);
00416   color.add_data4f(cleft);
00417   color.add_data4f(cleft);
00418   color.add_data4f(ctop);
00419   color.add_data4f(ctop);
00420   
00421   strip->add_next_vertices(8);
00422   strip->close_primitive();
00423   
00424   // Tristrip 2.
00425   vertex.add_data3f(right, 0.0f, bottom);
00426   vertex.add_data3f(right, 0.0f, top);
00427   vertex.add_data3f(inner_right, 0.0f, inner_bottom);
00428   vertex.add_data3f(inner_right, 0.0f, inner_top);
00429   vertex.add_data3f(inner_left, 0.0f, inner_bottom);
00430   vertex.add_data3f(inner_left, 0.0f, inner_top);
00431   color.add_data4f(cright);
00432   color.add_data4f(cright);
00433   color.add_data4f(cright);
00434   color.add_data4f(cright);
00435   color.add_data4f(_color);
00436   color.add_data4f(_color);
00437   
00438   strip->add_next_vertices(6);
00439   strip->close_primitive();
00440   strip->set_shade_model(Geom::SM_flat_last_vertex);
00441 
00442   if (has_texture()) {
00443     // Generate UV's.
00444     float left = uv_range[0];
00445     float right = uv_range[1];
00446     float bottom = uv_range[2];
00447     float top = uv_range[3];
00448 
00449     float cx = (left + right) * 0.5;
00450     float cy = (top + bottom) * 0.5;
00451     
00452     float inner_left = min(left + _uv_width[0], cx);
00453     float inner_right = max(right - _uv_width[0], cx);
00454     float inner_bottom = min(bottom + _uv_width[1], cy);
00455     float inner_top = max(top - _uv_width[1], cy);
00456 
00457     GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
00458     texcoord.add_data2f(right, bottom);
00459     texcoord.add_data2f(inner_right, inner_bottom);
00460     texcoord.add_data2f(left, bottom);
00461     texcoord.add_data2f(inner_left, inner_bottom);
00462     texcoord.add_data2f(left, top);
00463     texcoord.add_data2f(inner_left, inner_top);
00464     texcoord.add_data2f(right, top);
00465     texcoord.add_data2f(inner_right, inner_top);
00466 
00467     texcoord.add_data2f(right, bottom);
00468     texcoord.add_data2f(right, top);
00469     texcoord.add_data2f(inner_right, inner_bottom);
00470     texcoord.add_data2f(inner_right, inner_top);
00471     texcoord.add_data2f(inner_left, inner_bottom);
00472     texcoord.add_data2f(inner_left, inner_top);
00473   }
00474   PT(Geom) geom = new Geom(vdata);
00475   geom->add_primitive(strip);
00476   
00477   CPT(RenderState) state;
00478   state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat),
00479                             ColorAttrib::make_vertex());
00480   if (has_texture()) {
00481     state = state->set_attrib(TextureAttrib::make(get_texture()));
00482   }
00483   gnode->add_geom(geom, state);
00484   
00485   return gnode.p();
00486 }
00487 
00488 ////////////////////////////////////////////////////////////////////
00489 //     Function: PGFrameStyle::generate_groove_geom
00490 //       Access: Private
00491 //  Description: Generates the GeomNode appropriate to a T_groove or
00492 //               T_ridge frame.
00493 ////////////////////////////////////////////////////////////////////
00494 PT(PandaNode) PGFrameStyle::
00495 generate_groove_geom(const LVecBase4f &frame, bool in) {
00496   //
00497   // Colors:
00498   //
00499   // 
00500   //  * * * * * * * * * * * * * * * * * * * * * * * * * * *
00501   //  * *                                               * *
00502   //  *   *                   ctop                    *   *
00503   //  *     *                                       *     *
00504   //  *       * * * * * * * * * * * * * * * * * * *       *
00505   //  *       * *                               * *       *
00506   //  *       *   *          cbottom          *   *       *
00507   //  *       *     *                       *     *       *
00508   //  *       *       * * * * * * * * * * *       *       *
00509   //  *       *       *                   *       *       *
00510   //  *       *       *                   *       *       *
00511   //  * cleft * cright*      _color       * cleft * cright*
00512   //  *       *       *                   *       *       *
00513   //  *       *       *                   *       *       *
00514   //  *       *       * * * * * * * * * * *       *       *
00515   //  *       *     *                       *     *       *
00516   //  *       *   *           ctop            *   *       *
00517   //  *       * *                               * *       *
00518   //  *       * * * * * * * * * * * * * * * * * * *       *
00519   //  *     *                                       *     *
00520   //  *   *                  cbottom                  *   *
00521   //  * *                                               * *
00522   //  * * * * * * * * * * * * * * * * * * * * * * * * * * *
00523   //
00524   //
00525   // Vertices:
00526   //
00527   //  tristrip 1:
00528   //  4 * * * * * * * * * * * * * * * * * * * * * * * * * 6
00529   //  * *                                               *
00530   //  *   *                                           *
00531   //  *     *                                       *
00532   //  *       5 * * * * * * * * * * * * * * * * * 7
00533   //  *       *
00534   //  *       *
00535   //  *       *
00536   //  *       *
00537   //  *       *
00538   //  *       *
00539   //  *       *
00540   //  *       *
00541   //  *       *
00542   //  *       *
00543   //  *       *
00544   //  *       *
00545   //  *       *
00546   //  *       3 * * * * * * * * * * * * * * * * * 1
00547   //  *     *                                       *
00548   //  *   *                                           *
00549   //  * *                                               *
00550   //  2 * * * * * * * * * * * * * * * * * * * * * * * * * 0
00551   //
00552   //  tristrip 2:
00553   //          4 * * * * * * * * * * * * * * * * * 6
00554   //          * *                               *
00555   //          *   *                           *
00556   //          *     *                       *
00557   //          *       5 * * * * * * * * * 7
00558   //          *       *
00559   //          *       *
00560   //          *       *
00561   //          *       *
00562   //          *       *
00563   //          *       3 * * * * * * * * * 1
00564   //          *     *                       *
00565   //          *   *                           *
00566   //          * *                               *
00567   //          2 * * * * * * * * * * * * * * * * * 0
00568   // 
00569   //  tristrip 3:
00570   //                                                      1
00571   //                                                    * *
00572   //                                                  *   *
00573   //                                                *     *
00574   //                                              3       *
00575   //                                            * *       *
00576   //                                          *   *       *
00577   //                                        *     *       *
00578   //                  7 * * * * * * * * * 5       *       *
00579   //                  *                   *       *       *
00580   //                  *                   *       *       *
00581   //                  *                   *       *       *
00582   //                  *                   *       *       *
00583   //                  *                   *       *       *
00584   //                  6 * * * * * * * * * 4       *       *
00585   //                                        *     *       *
00586   //                                          *   *       *
00587   //                                            * *       *
00588   //                                              2       *
00589   //                                                *     *
00590   //                                                  *   *
00591   //                                                    * *
00592   //                                                      0
00593 
00594   PT(GeomNode) gnode = new GeomNode("groove");
00595 
00596   float left = frame[0];
00597   float right = frame[1];
00598   float bottom = frame[2];
00599   float top = frame[3];
00600 
00601   float cx = (left + right) * 0.5;
00602   float cy = (top + bottom) * 0.5;
00603 
00604   float mid_left = min(left + 0.5f * _width[0], cx);
00605   float mid_right = max(right - 0.5f * _width[0], cx);
00606   float mid_bottom = min(bottom + 0.5f * _width[1], cy);
00607   float mid_top = max(top - 0.5f * _width[1], cy);
00608 
00609   float inner_left = min(left + _width[0], cx);
00610   float inner_right = max(right - _width[0], cx);
00611   float inner_bottom = min(bottom + _width[1], cy);
00612   float inner_top = max(top - _width[1], cy);
00613 
00614   float left_color_scale = 1.2f;
00615   float right_color_scale = 0.8f;
00616   float bottom_color_scale = 0.7f;
00617   float top_color_scale = 1.3f;
00618 
00619   if (in) {
00620     right_color_scale = 1.2f;
00621     left_color_scale = 0.8f;
00622     top_color_scale = 0.7f;
00623     bottom_color_scale = 1.3f;
00624   }
00625 
00626   // Clamp all colors at white, and don't scale the alpha.
00627   Colorf cleft(min(_color[0] * left_color_scale, 1.0f),
00628                min(_color[1] * left_color_scale, 1.0f),
00629                min(_color[2] * left_color_scale, 1.0f),
00630                _color[3]);
00631 
00632   Colorf cright(min(_color[0] * right_color_scale, 1.0f),
00633                 min(_color[1] * right_color_scale, 1.0f),
00634                 min(_color[2] * right_color_scale, 1.0f),
00635                 _color[3]);
00636 
00637   Colorf cbottom(min(_color[0] * bottom_color_scale, 1.0f),
00638                  min(_color[1] * bottom_color_scale, 1.0f),
00639                  min(_color[2] * bottom_color_scale, 1.0f),
00640                  _color[3]);
00641 
00642   Colorf ctop(min(_color[0] * top_color_scale, 1.0f),
00643               min(_color[1] * top_color_scale, 1.0f),
00644               min(_color[2] * top_color_scale, 1.0f),
00645               _color[3]);
00646 
00647   CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3cp();
00648   PT(GeomVertexData) vdata = new GeomVertexData
00649     ("PGFrame", format, Geom::UH_static);
00650   
00651   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00652   GeomVertexWriter color(vdata, InternalName::get_color());
00653   
00654   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
00655   // Tristrip 1.
00656   vertex.add_data3f(right, 0.0f, bottom);
00657   vertex.add_data3f(mid_right, 0.0f, mid_bottom);
00658   vertex.add_data3f(left, 0.0f, bottom);
00659   vertex.add_data3f(mid_left, 0.0f, mid_bottom);
00660   vertex.add_data3f(left, 0.0f, top);
00661   vertex.add_data3f(mid_left, 0.0f, mid_top);
00662   vertex.add_data3f(right, 0.0f, top);
00663   vertex.add_data3f(mid_right, 0.0f, mid_top);
00664   color.add_data4f(cbottom);
00665   color.add_data4f(cbottom);
00666   color.add_data4f(cbottom);
00667   color.add_data4f(cbottom);
00668   color.add_data4f(cleft);
00669   color.add_data4f(cleft);
00670   color.add_data4f(ctop);
00671   color.add_data4f(ctop);
00672   
00673   strip->add_next_vertices(8);
00674   strip->close_primitive();
00675   
00676   // Tristrip 2.
00677   vertex.add_data3f(mid_right, 0.0f, mid_bottom);
00678   vertex.add_data3f(inner_right, 0.0f, inner_bottom);
00679   vertex.add_data3f(mid_left, 0.0f, mid_bottom);
00680   vertex.add_data3f(inner_left, 0.0f, inner_bottom);
00681   vertex.add_data3f(mid_left, 0.0f, mid_top);
00682   vertex.add_data3f(inner_left, 0.0f, inner_top);
00683   vertex.add_data3f(mid_right, 0.0f, mid_top);
00684   vertex.add_data3f(inner_right, 0.0f, inner_top);
00685   color.add_data4f(ctop);
00686   color.add_data4f(ctop);
00687   color.add_data4f(ctop);
00688   color.add_data4f(ctop);
00689   color.add_data4f(cright);
00690   color.add_data4f(cright);
00691   color.add_data4f(cbottom);
00692   color.add_data4f(cbottom);
00693   
00694   strip->add_next_vertices(8);
00695   strip->close_primitive();
00696   
00697   // Tristrip 3.
00698   vertex.add_data3f(right, 0.0f, bottom);
00699   vertex.add_data3f(right, 0.0f, top);
00700   vertex.add_data3f(mid_right, 0.0f, mid_bottom);
00701   vertex.add_data3f(mid_right, 0.0f, mid_top);
00702   vertex.add_data3f(inner_right, 0.0f, inner_bottom);
00703   vertex.add_data3f(inner_right, 0.0f, inner_top);
00704   vertex.add_data3f(inner_left, 0.0f, inner_bottom);
00705   vertex.add_data3f(inner_left, 0.0f, inner_top);
00706   color.add_data4f(cright);
00707   color.add_data4f(cright);
00708   color.add_data4f(cright);
00709   color.add_data4f(cright);
00710   color.add_data4f(cleft);
00711   color.add_data4f(cleft);
00712   color.add_data4f(_color);
00713   color.add_data4f(_color);
00714   
00715   strip->add_next_vertices(8);
00716   strip->close_primitive();
00717   
00718   strip->set_shade_model(Geom::SM_flat_last_vertex);
00719   
00720   PT(Geom) geom = new Geom(vdata);
00721   geom->add_primitive(strip);
00722   
00723   CPT(RenderState) state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat),
00724                                              ColorAttrib::make_vertex());
00725   gnode->add_geom(geom, state);
00726   
00727   // For now, beveled and grooved geoms don't support textures.  Easy
00728   // to add if anyone really wants this.
00729   
00730   return gnode.p();
00731 }
00732 
00733 ////////////////////////////////////////////////////////////////////
00734 //     Function: PGFrameStyle::generate_texture_border_geom
00735 //       Access: Private
00736 //  Description: Generates the GeomNode appropriate to a
00737 //               T_texture_border frame.
00738 ////////////////////////////////////////////////////////////////////
00739 PT(PandaNode) PGFrameStyle::
00740 generate_texture_border_geom(const LVecBase4f &frame) {
00741   //
00742   // Vertices:
00743   //
00744   //  tristrip 1:
00745   //  0 * * * 2 * * * * * * * * * * * * * 4 * * * 6
00746   //  *     * *                     * * * *     * *
00747   //  *   *   *         * * * * * *       *   *   *
00748   //  * *     * * * * *                   * *     *
00749   //  1 * * * 3 * * * * * * * * * * * * * 5 * * * 7
00750   //
00751   //  tristrip 2:
00752   //  1 * * * 3 * * * * * * * * * * * * * 5 * * * 7
00753   //  *       *                         * *       *
00754   //  *     * *                     * *   *     * *
00755   //  *   *   *               * * *       *   *   *
00756   //  *   *   *         * * *             *   *   *
00757   //  * *     *     * *                   * *     *
00758   //  *       * * *                       *       *
00759   //  8 * * *10 * * * * * * * * * * * * *12 * * *14
00760   // 
00761   //  tristrip 3:
00762   //  8 * * *10 * * * * * * * * * * * * *12 * * *14
00763   //  *     * *                     * * * *     * *
00764   //  *   *   *         * * * * * *       *   *   *
00765   //  * *     * * * * *                   * *     *
00766   //  9 * * *11 * * * * * * * * * * * * *13 * * *15
00767 
00768   PT(GeomNode) gnode = new GeomNode("flat");
00769 
00770   float left = frame[0];
00771   float right = frame[1];
00772   float bottom = frame[2];
00773   float top = frame[3];
00774 
00775   float cx = (left + right) * 0.5;
00776   float cy = (top + bottom) * 0.5;
00777 
00778   float inner_left = min(left + _width[0], cx);
00779   float inner_right = max(right - _width[0], cx);
00780   float inner_bottom = min(bottom + _width[1], cy);
00781   float inner_top = max(top - _width[1], cy);
00782 
00783   CPT(GeomVertexFormat) format;
00784   if (has_texture()) {
00785     format = GeomVertexFormat::get_v3t2();
00786   } else {
00787     format = GeomVertexFormat::get_v3();
00788   }
00789   
00790   PT(GeomVertexData) vdata = new GeomVertexData
00791     ("PGFrame", format, Geom::UH_static);
00792   
00793   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00794   
00795   // verts 0,1,2,3
00796   vertex.add_data3f(left, 0.0f, top);
00797   vertex.add_data3f(left, 0.0f, inner_top);
00798   vertex.add_data3f(inner_left, 0.0f, top);
00799   vertex.add_data3f(inner_left, 0.0f, inner_top);
00800   // verts 4,5,6,7
00801   vertex.add_data3f(inner_right, 0.0f, top);
00802   vertex.add_data3f(inner_right, 0.0f, inner_top);
00803   vertex.add_data3f(right, 0.0f, top);
00804   vertex.add_data3f(right, 0.0f, inner_top);
00805   // verts 8,9,10,11
00806   vertex.add_data3f(left, 0.0f, inner_bottom);
00807   vertex.add_data3f(left, 0.0f, bottom);
00808   vertex.add_data3f(inner_left, 0.0f, inner_bottom);
00809   vertex.add_data3f(inner_left, 0.0f, bottom);
00810   // verts 12,13,14,15
00811   vertex.add_data3f(inner_right, 0.0f, inner_bottom);
00812   vertex.add_data3f(inner_right, 0.0f, bottom);
00813   vertex.add_data3f(right, 0.0f, inner_bottom);
00814   vertex.add_data3f(right, 0.0f, bottom);
00815 
00816   if (has_texture()) {
00817     // Generate UV's.
00818     float left = uv_range[0];
00819     float right = uv_range[1];
00820     float bottom = uv_range[2];
00821     float top = uv_range[3];
00822 
00823     float cx = (left + right) * 0.5;
00824     float cy = (top + bottom) * 0.5;
00825     
00826     float inner_left = min(left + _uv_width[0], cx);
00827     float inner_right = max(right - _uv_width[0], cx);
00828     float inner_bottom = min(bottom + _uv_width[1], cy);
00829     float inner_top = max(top - _uv_width[1], cy);
00830 
00831     GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
00832   
00833     // verts 0,1,2,3
00834     texcoord.add_data2f(left, top);
00835     texcoord.add_data2f(left, inner_top);
00836     texcoord.add_data2f(inner_left, top);
00837     texcoord.add_data2f(inner_left, inner_top);
00838     // verts 4,5,6,7
00839     texcoord.add_data2f(inner_right, top);
00840     texcoord.add_data2f(inner_right, inner_top);
00841     texcoord.add_data2f(right, top);
00842     texcoord.add_data2f(right, inner_top);
00843     // verts 8,9,10,11
00844     texcoord.add_data2f(left, inner_bottom);
00845     texcoord.add_data2f(left, bottom);
00846     texcoord.add_data2f(inner_left, inner_bottom);
00847     texcoord.add_data2f(inner_left, bottom);
00848     // verts 12,13,14,15
00849     texcoord.add_data2f(inner_right, inner_bottom);
00850     texcoord.add_data2f(inner_right, bottom);
00851     texcoord.add_data2f(right, inner_bottom);
00852     texcoord.add_data2f(right, bottom);
00853   }
00854   
00855   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
00856   
00857   // tristrip #1
00858   strip->add_consecutive_vertices(0, 8);
00859   strip->close_primitive();
00860   
00861   // tristrip #2
00862   strip->add_vertex(1);
00863   strip->add_vertex(8);
00864   strip->add_vertex(3);
00865   strip->add_vertex(10);
00866   strip->add_vertex(5);
00867   strip->add_vertex(12);
00868   strip->add_vertex(7);
00869   strip->add_vertex(14);
00870   strip->close_primitive();
00871   
00872   // tristrip #3
00873   strip->add_consecutive_vertices(8, 8);
00874   strip->close_primitive();
00875   
00876   CPT(RenderState) state = RenderState::make(ColorAttrib::make_flat(_color), -1);
00877   if (has_texture()) {
00878     state = state->set_attrib(TextureAttrib::make(get_texture()));
00879   }
00880 
00881   PT(Geom) geom = new Geom(vdata);
00882   geom->add_primitive(strip);
00883   gnode->add_geom(geom, state);
00884   
00885   return gnode.p();
00886 }
 All Classes Functions Variables Enumerations