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 LVecBase4 uv_range = LVecBase4(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 LVecBase4 PGFrameStyle:: 00072 get_internal_frame(const LVecBase4 &frame) const { 00073 LPoint2 center((frame[0] + frame[1]) / 2.0f, 00074 (frame[2] + frame[3]) / 2.0f); 00075 LVecBase4 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 LVecBase4(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 != LVecBase2(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 LMatrix4 &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 LVector3 x, z; 00126 mat.get_row3(x, 0); 00127 PN_stdfloat x_scale = x.length(); 00128 00129 mat.get_row3(z, 2); 00130 PN_stdfloat 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 LVecBase4 &frame, 00164 int sort) { 00165 PT(PandaNode) new_node; 00166 00167 LPoint2 center((frame[0] + frame[1]) / 2.0f, 00168 (frame[2] + frame[3]) / 2.0f); 00169 LVecBase4 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 LVecBase4 &frame) { 00224 PT(GeomNode) gnode = new GeomNode("flat"); 00225 00226 PN_stdfloat left = frame[0]; 00227 PN_stdfloat right = frame[1]; 00228 PN_stdfloat bottom = frame[2]; 00229 PN_stdfloat 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_data3(LPoint3::rfu(left, 0.0f, top)); 00243 vertex.add_data3(LPoint3::rfu(left, 0.0f, bottom)); 00244 vertex.add_data3(LPoint3::rfu(right, 0.0f, top)); 00245 vertex.add_data3(LPoint3::rfu(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_data2(left, top); 00256 texcoord.add_data2(left, bottom); 00257 texcoord.add_data2(right, top); 00258 texcoord.add_data2(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 LVecBase4 &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 PN_stdfloat left = frame[0]; 00344 PN_stdfloat right = frame[1]; 00345 PN_stdfloat bottom = frame[2]; 00346 PN_stdfloat top = frame[3]; 00347 00348 PN_stdfloat cx = (left + right) * 0.5; 00349 PN_stdfloat cy = (top + bottom) * 0.5; 00350 00351 PN_stdfloat inner_left = min(left + _width[0], cx); 00352 PN_stdfloat inner_right = max(right - _width[0], cx); 00353 PN_stdfloat inner_bottom = min(bottom + _width[1], cy); 00354 PN_stdfloat inner_top = max(top - _width[1], cy); 00355 00356 PN_stdfloat left_color_scale = 1.2; 00357 PN_stdfloat right_color_scale = 0.8; 00358 PN_stdfloat bottom_color_scale = 0.7; 00359 PN_stdfloat 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 LColor cleft(min(_color[0] * left_color_scale, (PN_stdfloat)1.0), 00370 min(_color[1] * left_color_scale, (PN_stdfloat)1.0), 00371 min(_color[2] * left_color_scale, (PN_stdfloat)1.0), 00372 _color[3]); 00373 00374 LColor cright(min(_color[0] * right_color_scale, (PN_stdfloat)1.0), 00375 min(_color[1] * right_color_scale, (PN_stdfloat)1.0), 00376 min(_color[2] * right_color_scale, (PN_stdfloat)1.0), 00377 _color[3]); 00378 00379 LColor cbottom(min(_color[0] * bottom_color_scale, (PN_stdfloat)1.0), 00380 min(_color[1] * bottom_color_scale, (PN_stdfloat)1.0), 00381 min(_color[2] * bottom_color_scale, (PN_stdfloat)1.0), 00382 _color[3]); 00383 00384 LColor ctop(min(_color[0] * top_color_scale, (PN_stdfloat)1.0), 00385 min(_color[1] * top_color_scale, (PN_stdfloat)1.0), 00386 min(_color[2] * top_color_scale, (PN_stdfloat)1.0), 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_data3(LPoint3::rfu(right, 0.0f, bottom)); 00405 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_bottom)); 00406 vertex.add_data3(LPoint3::rfu(left, 0.0f, bottom)); 00407 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_bottom)); 00408 vertex.add_data3(LPoint3::rfu(left, 0.0f, top)); 00409 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_top)); 00410 vertex.add_data3(LPoint3::rfu(right, 0.0f, top)); 00411 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_top)); 00412 color.add_data4(cbottom); 00413 color.add_data4(cbottom); 00414 color.add_data4(cbottom); 00415 color.add_data4(cbottom); 00416 color.add_data4(cleft); 00417 color.add_data4(cleft); 00418 color.add_data4(ctop); 00419 color.add_data4(ctop); 00420 00421 strip->add_next_vertices(8); 00422 strip->close_primitive(); 00423 00424 // Tristrip 2. 00425 vertex.add_data3(LPoint3::rfu(right, 0.0f, bottom)); 00426 vertex.add_data3(LPoint3::rfu(right, 0.0f, top)); 00427 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_bottom)); 00428 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_top)); 00429 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_bottom)); 00430 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_top)); 00431 color.add_data4(cright); 00432 color.add_data4(cright); 00433 color.add_data4(cright); 00434 color.add_data4(cright); 00435 color.add_data4(_color); 00436 color.add_data4(_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 PN_stdfloat left = uv_range[0]; 00445 PN_stdfloat right = uv_range[1]; 00446 PN_stdfloat bottom = uv_range[2]; 00447 PN_stdfloat top = uv_range[3]; 00448 00449 PN_stdfloat cx = (left + right) * 0.5; 00450 PN_stdfloat cy = (top + bottom) * 0.5; 00451 00452 PN_stdfloat inner_left = min(left + _uv_width[0], cx); 00453 PN_stdfloat inner_right = max(right - _uv_width[0], cx); 00454 PN_stdfloat inner_bottom = min(bottom + _uv_width[1], cy); 00455 PN_stdfloat inner_top = max(top - _uv_width[1], cy); 00456 00457 GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); 00458 texcoord.add_data2(right, bottom); 00459 texcoord.add_data2(inner_right, inner_bottom); 00460 texcoord.add_data2(left, bottom); 00461 texcoord.add_data2(inner_left, inner_bottom); 00462 texcoord.add_data2(left, top); 00463 texcoord.add_data2(inner_left, inner_top); 00464 texcoord.add_data2(right, top); 00465 texcoord.add_data2(inner_right, inner_top); 00466 00467 texcoord.add_data2(right, bottom); 00468 texcoord.add_data2(right, top); 00469 texcoord.add_data2(inner_right, inner_bottom); 00470 texcoord.add_data2(inner_right, inner_top); 00471 texcoord.add_data2(inner_left, inner_bottom); 00472 texcoord.add_data2(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 LVecBase4 &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 PN_stdfloat left = frame[0]; 00597 PN_stdfloat right = frame[1]; 00598 PN_stdfloat bottom = frame[2]; 00599 PN_stdfloat top = frame[3]; 00600 00601 PN_stdfloat cx = (left + right) * 0.5; 00602 PN_stdfloat cy = (top + bottom) * 0.5; 00603 00604 PN_stdfloat mid_left = min(left + 0.5f * _width[0], cx); 00605 PN_stdfloat mid_right = max(right - 0.5f * _width[0], cx); 00606 PN_stdfloat mid_bottom = min(bottom + 0.5f * _width[1], cy); 00607 PN_stdfloat mid_top = max(top - 0.5f * _width[1], cy); 00608 00609 PN_stdfloat inner_left = min(left + _width[0], cx); 00610 PN_stdfloat inner_right = max(right - _width[0], cx); 00611 PN_stdfloat inner_bottom = min(bottom + _width[1], cy); 00612 PN_stdfloat inner_top = max(top - _width[1], cy); 00613 00614 PN_stdfloat left_color_scale = 1.2; 00615 PN_stdfloat right_color_scale = 0.8f; 00616 PN_stdfloat bottom_color_scale = 0.7f; 00617 PN_stdfloat top_color_scale = 1.3; 00618 00619 if (in) { 00620 right_color_scale = 1.2; 00621 left_color_scale = 0.8f; 00622 top_color_scale = 0.7f; 00623 bottom_color_scale = 1.3; 00624 } 00625 00626 // Clamp all colors at white, and don't scale the alpha. 00627 LColor cleft(min(_color[0] * left_color_scale, (PN_stdfloat)1.0), 00628 min(_color[1] * left_color_scale, (PN_stdfloat)1.0), 00629 min(_color[2] * left_color_scale, (PN_stdfloat)1.0), 00630 _color[3]); 00631 00632 LColor cright(min(_color[0] * right_color_scale, (PN_stdfloat)1.0), 00633 min(_color[1] * right_color_scale, (PN_stdfloat)1.0), 00634 min(_color[2] * right_color_scale, (PN_stdfloat)1.0), 00635 _color[3]); 00636 00637 LColor cbottom(min(_color[0] * bottom_color_scale, (PN_stdfloat)1.0), 00638 min(_color[1] * bottom_color_scale, (PN_stdfloat)1.0), 00639 min(_color[2] * bottom_color_scale, (PN_stdfloat)1.0), 00640 _color[3]); 00641 00642 LColor ctop(min(_color[0] * top_color_scale, (PN_stdfloat)1.0), 00643 min(_color[1] * top_color_scale, (PN_stdfloat)1.0), 00644 min(_color[2] * top_color_scale, (PN_stdfloat)1.0), 00645 _color[3]); 00646 00647 CPT(GeomVertexFormat) format; 00648 if (has_texture()) { 00649 format = GeomVertexFormat::get_v3cpt2(); 00650 } else { 00651 format = GeomVertexFormat::get_v3cp(); 00652 } 00653 PT(GeomVertexData) vdata = new GeomVertexData 00654 ("PGFrame", format, Geom::UH_static); 00655 00656 GeomVertexWriter vertex(vdata, InternalName::get_vertex()); 00657 GeomVertexWriter color(vdata, InternalName::get_color()); 00658 00659 PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static); 00660 // Tristrip 1. 00661 vertex.add_data3(LPoint3::rfu(right, 0.0f, bottom)); 00662 vertex.add_data3(LPoint3::rfu(mid_right, 0.0f, mid_bottom)); 00663 vertex.add_data3(LPoint3::rfu(left, 0.0f, bottom)); 00664 vertex.add_data3(LPoint3::rfu(mid_left, 0.0f, mid_bottom)); 00665 vertex.add_data3(LPoint3::rfu(left, 0.0f, top)); 00666 vertex.add_data3(LPoint3::rfu(mid_left, 0.0f, mid_top)); 00667 vertex.add_data3(LPoint3::rfu(right, 0.0f, top)); 00668 vertex.add_data3(LPoint3::rfu(mid_right, 0.0f, mid_top)); 00669 color.add_data4(cbottom); 00670 color.add_data4(cbottom); 00671 color.add_data4(cbottom); 00672 color.add_data4(cbottom); 00673 color.add_data4(cleft); 00674 color.add_data4(cleft); 00675 color.add_data4(ctop); 00676 color.add_data4(ctop); 00677 00678 strip->add_next_vertices(8); 00679 strip->close_primitive(); 00680 00681 // Tristrip 2. 00682 vertex.add_data3(LPoint3::rfu(mid_right, 0.0f, mid_bottom)); 00683 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_bottom)); 00684 vertex.add_data3(LPoint3::rfu(mid_left, 0.0f, mid_bottom)); 00685 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_bottom)); 00686 vertex.add_data3(LPoint3::rfu(mid_left, 0.0f, mid_top)); 00687 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_top)); 00688 vertex.add_data3(LPoint3::rfu(mid_right, 0.0f, mid_top)); 00689 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_top)); 00690 color.add_data4(ctop); 00691 color.add_data4(ctop); 00692 color.add_data4(ctop); 00693 color.add_data4(ctop); 00694 color.add_data4(cright); 00695 color.add_data4(cright); 00696 color.add_data4(cbottom); 00697 color.add_data4(cbottom); 00698 00699 strip->add_next_vertices(8); 00700 strip->close_primitive(); 00701 00702 // Tristrip 3. 00703 vertex.add_data3(LPoint3::rfu(right, 0.0f, bottom)); 00704 vertex.add_data3(LPoint3::rfu(right, 0.0f, top)); 00705 vertex.add_data3(LPoint3::rfu(mid_right, 0.0f, mid_bottom)); 00706 vertex.add_data3(LPoint3::rfu(mid_right, 0.0f, mid_top)); 00707 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_bottom)); 00708 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_top)); 00709 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_bottom)); 00710 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_top)); 00711 color.add_data4(cright); 00712 color.add_data4(cright); 00713 color.add_data4(cright); 00714 color.add_data4(cright); 00715 color.add_data4(cleft); 00716 color.add_data4(cleft); 00717 color.add_data4(_color); 00718 color.add_data4(_color); 00719 00720 strip->add_next_vertices(8); 00721 strip->close_primitive(); 00722 00723 strip->set_shade_model(Geom::SM_flat_last_vertex); 00724 00725 if (has_texture()) { 00726 // Generate UV's. 00727 PN_stdfloat left = uv_range[0]; 00728 PN_stdfloat right = uv_range[1]; 00729 PN_stdfloat bottom = uv_range[2]; 00730 PN_stdfloat top = uv_range[3]; 00731 00732 PN_stdfloat cx = (left + right) * 0.5; 00733 PN_stdfloat cy = (top + bottom) * 0.5; 00734 00735 PN_stdfloat mid_left = min(left + 0.5f * _width[0], cx); 00736 PN_stdfloat mid_right = max(right - 0.5f * _width[0], cx); 00737 PN_stdfloat mid_bottom = min(bottom + 0.5f * _width[1], cy); 00738 PN_stdfloat mid_top = max(top - 0.5f * _width[1], cy); 00739 00740 PN_stdfloat inner_left = min(left + _width[0], cx); 00741 PN_stdfloat inner_right = max(right - _width[0], cx); 00742 PN_stdfloat inner_bottom = min(bottom + _width[1], cy); 00743 PN_stdfloat inner_top = max(top - _width[1], cy); 00744 00745 GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); 00746 texcoord.add_data2(right, bottom); 00747 texcoord.add_data2(mid_right, mid_bottom); 00748 texcoord.add_data2(left, bottom); 00749 texcoord.add_data2(mid_left, mid_bottom); 00750 texcoord.add_data2(left, top); 00751 texcoord.add_data2(mid_left, mid_top); 00752 texcoord.add_data2(right, top); 00753 texcoord.add_data2(mid_right, mid_top); 00754 00755 texcoord.add_data2(mid_right, mid_bottom); 00756 texcoord.add_data2(inner_right, inner_bottom); 00757 texcoord.add_data2(mid_left, mid_bottom); 00758 texcoord.add_data2(inner_left, inner_bottom); 00759 texcoord.add_data2(mid_left, mid_top); 00760 texcoord.add_data2(inner_left, inner_top); 00761 texcoord.add_data2(mid_right, mid_top); 00762 texcoord.add_data2(inner_right, inner_top); 00763 00764 texcoord.add_data2(right, bottom); 00765 texcoord.add_data2(right, top); 00766 texcoord.add_data2(mid_right, mid_bottom); 00767 texcoord.add_data2(mid_right, mid_top); 00768 texcoord.add_data2(inner_right, inner_bottom); 00769 texcoord.add_data2(inner_right, inner_top); 00770 texcoord.add_data2(inner_left, inner_bottom); 00771 texcoord.add_data2(inner_left, inner_top); 00772 } 00773 00774 PT(Geom) geom = new Geom(vdata); 00775 geom->add_primitive(strip); 00776 00777 CPT(RenderState) state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat), 00778 ColorAttrib::make_vertex()); 00779 if (has_texture()) { 00780 state = state->set_attrib(TextureAttrib::make(get_texture())); 00781 } 00782 gnode->add_geom(geom, state); 00783 00784 return gnode.p(); 00785 } 00786 00787 //////////////////////////////////////////////////////////////////// 00788 // Function: PGFrameStyle::generate_texture_border_geom 00789 // Access: Private 00790 // Description: Generates the GeomNode appropriate to a 00791 // T_texture_border frame. 00792 //////////////////////////////////////////////////////////////////// 00793 PT(PandaNode) PGFrameStyle:: 00794 generate_texture_border_geom(const LVecBase4 &frame) { 00795 // 00796 // Vertices: 00797 // 00798 // tristrip 1: 00799 // 0 * * * 2 * * * * * * * * * * * * * 4 * * * 6 00800 // * * * * * * * * * 00801 // * * * * * * * * * * * * 00802 // * * * * * * * * * * 00803 // 1 * * * 3 * * * * * * * * * * * * * 5 * * * 7 00804 // 00805 // tristrip 2: 00806 // 1 * * * 3 * * * * * * * * * * * * * 5 * * * 7 00807 // * * * * * 00808 // * * * * * * * * 00809 // * * * * * * * * * 00810 // * * * * * * * * * 00811 // * * * * * * * * 00812 // * * * * * * 00813 // 8 * * *10 * * * * * * * * * * * * *12 * * *14 00814 // 00815 // tristrip 3: 00816 // 8 * * *10 * * * * * * * * * * * * *12 * * *14 00817 // * * * * * * * * * 00818 // * * * * * * * * * * * * 00819 // * * * * * * * * * * 00820 // 9 * * *11 * * * * * * * * * * * * *13 * * *15 00821 00822 PT(GeomNode) gnode = new GeomNode("flat"); 00823 00824 PN_stdfloat left = frame[0]; 00825 PN_stdfloat right = frame[1]; 00826 PN_stdfloat bottom = frame[2]; 00827 PN_stdfloat top = frame[3]; 00828 00829 PN_stdfloat cx = (left + right) * 0.5; 00830 PN_stdfloat cy = (top + bottom) * 0.5; 00831 00832 PN_stdfloat inner_left = min(left + _width[0], cx); 00833 PN_stdfloat inner_right = max(right - _width[0], cx); 00834 PN_stdfloat inner_bottom = min(bottom + _width[1], cy); 00835 PN_stdfloat inner_top = max(top - _width[1], cy); 00836 00837 CPT(GeomVertexFormat) format; 00838 if (has_texture()) { 00839 format = GeomVertexFormat::get_v3t2(); 00840 } else { 00841 format = GeomVertexFormat::get_v3(); 00842 } 00843 00844 PT(GeomVertexData) vdata = new GeomVertexData 00845 ("PGFrame", format, Geom::UH_static); 00846 00847 GeomVertexWriter vertex(vdata, InternalName::get_vertex()); 00848 00849 // verts 0,1,2,3 00850 vertex.add_data3(LPoint3::rfu(left, 0.0f, top)); 00851 vertex.add_data3(LPoint3::rfu(left, 0.0f, inner_top)); 00852 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, top)); 00853 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_top)); 00854 // verts 4,5,6,7 00855 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, top)); 00856 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_top)); 00857 vertex.add_data3(LPoint3::rfu(right, 0.0f, top)); 00858 vertex.add_data3(LPoint3::rfu(right, 0.0f, inner_top)); 00859 // verts 8,9,10,11 00860 vertex.add_data3(LPoint3::rfu(left, 0.0f, inner_bottom)); 00861 vertex.add_data3(LPoint3::rfu(left, 0.0f, bottom)); 00862 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, inner_bottom)); 00863 vertex.add_data3(LPoint3::rfu(inner_left, 0.0f, bottom)); 00864 // verts 12,13,14,15 00865 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, inner_bottom)); 00866 vertex.add_data3(LPoint3::rfu(inner_right, 0.0f, bottom)); 00867 vertex.add_data3(LPoint3::rfu(right, 0.0f, inner_bottom)); 00868 vertex.add_data3(LPoint3::rfu(right, 0.0f, bottom)); 00869 00870 if (has_texture()) { 00871 // Generate UV's. 00872 PN_stdfloat left = uv_range[0]; 00873 PN_stdfloat right = uv_range[1]; 00874 PN_stdfloat bottom = uv_range[2]; 00875 PN_stdfloat top = uv_range[3]; 00876 00877 PN_stdfloat cx = (left + right) * 0.5; 00878 PN_stdfloat cy = (top + bottom) * 0.5; 00879 00880 PN_stdfloat inner_left = min(left + _uv_width[0], cx); 00881 PN_stdfloat inner_right = max(right - _uv_width[0], cx); 00882 PN_stdfloat inner_bottom = min(bottom + _uv_width[1], cy); 00883 PN_stdfloat inner_top = max(top - _uv_width[1], cy); 00884 00885 GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); 00886 00887 // verts 0,1,2,3 00888 texcoord.add_data2(left, top); 00889 texcoord.add_data2(left, inner_top); 00890 texcoord.add_data2(inner_left, top); 00891 texcoord.add_data2(inner_left, inner_top); 00892 // verts 4,5,6,7 00893 texcoord.add_data2(inner_right, top); 00894 texcoord.add_data2(inner_right, inner_top); 00895 texcoord.add_data2(right, top); 00896 texcoord.add_data2(right, inner_top); 00897 // verts 8,9,10,11 00898 texcoord.add_data2(left, inner_bottom); 00899 texcoord.add_data2(left, bottom); 00900 texcoord.add_data2(inner_left, inner_bottom); 00901 texcoord.add_data2(inner_left, bottom); 00902 // verts 12,13,14,15 00903 texcoord.add_data2(inner_right, inner_bottom); 00904 texcoord.add_data2(inner_right, bottom); 00905 texcoord.add_data2(right, inner_bottom); 00906 texcoord.add_data2(right, bottom); 00907 } 00908 00909 PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static); 00910 00911 // tristrip #1 00912 strip->add_consecutive_vertices(0, 8); 00913 strip->close_primitive(); 00914 00915 // tristrip #2 00916 strip->add_vertex(1); 00917 strip->add_vertex(8); 00918 strip->add_vertex(3); 00919 strip->add_vertex(10); 00920 strip->add_vertex(5); 00921 strip->add_vertex(12); 00922 strip->add_vertex(7); 00923 strip->add_vertex(14); 00924 strip->close_primitive(); 00925 00926 // tristrip #3 00927 strip->add_consecutive_vertices(8, 8); 00928 strip->close_primitive(); 00929 00930 CPT(RenderState) state = RenderState::make(ColorAttrib::make_flat(_color), -1); 00931 if (has_texture()) { 00932 state = state->set_attrib(TextureAttrib::make(get_texture())); 00933 } 00934 00935 PT(Geom) geom = new Geom(vdata); 00936 geom->add_primitive(strip); 00937 gnode->add_geom(geom, state); 00938 00939 return gnode.p(); 00940 }