Panda3D
|
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 }