43 #include <ACG/GL/acg_glew.hh> 45 #include "GLPrimitives.hh" 46 #include <ACG/GL/IRenderer.hh> 54 GLPrimitive::GLPrimitive() :
55 vboDataInvalid_(true),
56 normalOrientation_(OUTSIDE),
71 GLPrimitive::~GLPrimitive()
74 glDeleteBuffers(1, &vbo_);
83 if (!numTris_ || vboDataInvalid_)
84 numTris_ = getNumTriangles();
89 assert(numLines_ == 0);
93 vboData_ =
new float[8 * 3 * numTris_];
95 if (curTriPtr_ == numTris_)
98 float* pTri = &vboData_[0] + (curTriPtr_++) * 3 * 8;
101 for (
int i = 0; i < 3; ++i) {
102 for (
int k = 0; k < 3; ++k)
103 *(pTri++) = _p[i][k];
105 for (
int k = 0; k < 3; ++k)
106 *(pTri++) = _n[i][k];
108 for (
int k = 0; k < 2; ++k)
109 *(pTri++) = _tex[i][k];
116 if (!numLines_ || vboDataInvalid_)
117 numLines_ = getNumLines();
122 assert(numTris_ == 0);
125 vboData_ =
new float[8 * 2 * numLines_];
127 if (curTriPtr_ == numLines_)
130 float* pLine = &vboData_[0] + (curTriPtr_++) * 2 * 8;
133 for (
int i = 0; i < 2; ++i) {
134 for (
int k = 0; k < 3; ++k)
135 *(pLine++) = _p[i][k];
137 for (
int k = 0; k < 3; ++k)
138 *(pLine++) = _n[i][k];
140 for (
int k = 0; k < 2; ++k)
141 *(pLine++) = _tex[i][k];
148 void GLPrimitive::bindVBO()
152 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
154 glVertexPointer(3, GL_FLOAT, 32, 0);
156 glEnableClientState(GL_VERTEX_ARRAY);
158 glNormalPointer(GL_FLOAT, 32, (GLvoid*) 12);
160 glEnableClientState(GL_NORMAL_ARRAY);
162 glClientActiveTexture(GL_TEXTURE0);
163 glTexCoordPointer(2, GL_FLOAT, 32, (GLvoid*) 24);
165 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
172 bool GLPrimitive::checkVBO()
178 const int bufSize = numTris_ ? numTris_ * 3 * 8 * 4 : numLines_ * 2 * 8 * 4;
181 if (!vboData_ || (!numTris_ && !numLines_) || (numTris_ && numLines_))
185 glGenBuffers(1, &vbo_);
186 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
187 glBufferData(GL_ARRAY_BUFFER, bufSize, vboData_, GL_STATIC_DRAW);
193 if (vboDataInvalid_) {
195 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
196 glBufferData(GL_ARRAY_BUFFER, bufSize, vboData_, GL_STATIC_DRAW);
197 vboDataInvalid_ =
false;
205 void GLPrimitive::unBindVBO()
207 glBindBuffer(GL_ARRAY_BUFFER, 0);
210 glDisableClientState(GL_VERTEX_ARRAY);
211 glDisableClientState(GL_NORMAL_ARRAY);
212 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
218 void GLPrimitive::draw_primitive()
223 glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3);
225 glDrawArrays(GL_LINES, 0, numLines_ * 2);
236 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
237 vertexDecl_.activateShaderPipeline(_program);
240 glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3);
242 glDrawArrays(GL_LINES, 0, numLines_ * 2);
244 vertexDecl_.deactivateShaderPipeline(_program);
245 glBindBuffer(GL_ARRAY_BUFFER, 0);
251 void GLPrimitive::addToRenderer_primitive(
class IRenderer* _renderer, RenderObject* _ro )
255 _ro->vertexBuffer = vbo_;
256 _ro->vertexDecl = &vertexDecl_;
259 _ro->glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3);
261 _ro->glDrawArrays(GL_LINES, 0, numLines_ * 2);
263 _renderer->addRenderObject(_ro);
269 void GLPrimitive::updateVBOData() {
282 unsigned int GLPrimitive::getVBO()
284 return checkVBO() ? vbo_ : 0;
287 const VertexDeclaration* GLPrimitive::getVertexDecl()
const 298 GLSphere::GLSphere(
int _slices,
int _stacks) :
307 GLSphere::~GLSphere()
314 void GLSphere::draw(GLState& _state,
float _radius,
const ACG::Vec3f& _center)
316 _state.push_modelview_matrix();
319 _state.scale(_radius, _radius, _radius);
321 GLPrimitive::draw_primitive();
323 _state.pop_modelview_matrix();
328 void GLSphere::addToRenderer( IRenderer* _renderer,
const RenderObject* _base,
float _radius,
const ACG::Vec3f& _center )
330 RenderObject ro = *_base;
333 ro.modelview.scale((
double)_radius, (
double)_radius, (
double)_radius);
335 GLPrimitive::addToRenderer_primitive(_renderer, &ro);
341 int GLSphere::getNumTriangles()
343 return 2 * slices_ + (stacks_ - 2) * slices_ * 2;
348 void GLSphere::updateVBO()
350 for (
int sl = 0; sl < slices_; ++sl) {
354 addTriangle(0, st, sl + 1, st + 1, sl, st + 1);
357 for (
int st = 1; st < stacks_ - 1; ++st) {
358 addTriangle(sl, st, sl + 1, st, sl, st + 1);
359 addTriangle(sl + 1, st, sl + 1, st + 1, sl, st + 1);
363 addTriangle(0, stacks_, sl, stacks_ - 1, sl + 1, stacks_ - 1);
370 void GLSphere::addTriangle(
int sl0,
int st0,
int sl1,
int st1,
int sl2,
int st2)
376 n[0] = p[0] = positionOnSphere(sl0, st0);
377 n[1] = p[1] = positionOnSphere(sl1, st1);
378 n[2] = p[2] = positionOnSphere(sl2, st2);
382 tex[0] = texCoordOnSphere(sl0, st0);
383 tex[1] = texCoordOnSphere(sl1, st1);
384 tex[2] = texCoordOnSphere(sl2, st2);
386 addTriangleToVBO(p, n, tex);
391 ACG::Vec3f GLSphere::positionOnSphere(
int _sliceNumber,
int _stackNumber)
395 double alpha = (M_PI / double(stacks_)) *
double(_stackNumber);
396 double beta = ((2.0 * M_PI) /
double(slices_)) *
double(_sliceNumber);
398 double ringRadius = sin(alpha);
399 position[0] = sin(beta) * ringRadius;
400 position[1] = cos(beta) * ringRadius;
401 position[2] = cos(alpha);
408 ACG::Vec2f GLSphere::texCoordOnSphere(
int _sliceNumber,
int _stackNumber)
412 double alpha = (M_PI / double(stacks_)) *
double(_stackNumber);
413 texCoord[0] = double(_sliceNumber) / double(slices_);
414 texCoord[1] = 0.5 * (cos(alpha) + 1.0);
423 GLCone::GLCone(
int _slices,
int _stacks,
float _bottomRadius,
float _topRadius,
bool _bottomCap,
bool _topCap) :
426 bottomRadius_(_bottomRadius),
427 topRadius_(_topRadius),
428 bottomCap_(_bottomCap),
443 void GLCone::setBottomRadius(
float _bottomRadius) {
444 if (bottomRadius_ != _bottomRadius)
445 vboDataInvalid_ =
true;
446 bottomRadius_ = _bottomRadius;
451 void GLCone::setTopRadius(
float _topRadius) {
452 if (topRadius_ != _topRadius)
453 vboDataInvalid_ =
true;
454 topRadius_ = _topRadius;
459 void GLCone::setNormalOrientation(NormalOrientation orientation) {
460 if (normalOrientation_ != orientation)
461 vboDataInvalid_ =
true;
462 normalOrientation_ = orientation;
471 _state.push_modelview_matrix();
491 for (
int i = 0; i < 3; ++i) {
492 mAlign(i, 0) = vRotAxis[i];
493 mAlign(i, 1) = vUp[i];
494 mAlign(i, 2) = _upDir[i];
502 mAlign.
scale(1.0, 1.0, _height);
507 _state.mult_matrix(mAlign, mAlignInv);
509 GLPrimitive::draw_primitive();
511 _state.pop_modelview_matrix();
517 void GLCone::addToRenderer(IRenderer* _renderer,
518 const RenderObject* _base,
524 RenderObject ro = *_base;
544 for (
int i = 0; i < 3; ++i) {
545 mAlign(i, 0) = vRotAxis[i];
546 mAlign(i, 1) = vUp[i];
547 mAlign(i, 2) = _upDir[i];
555 mAlign.
scale(_radiusScale, _radiusScale, _height);
557 ro.modelview *= mAlign;
559 GLPrimitive::addToRenderer_primitive(_renderer, &ro);
564 int GLCone::getNumTriangles()
566 int numTris = stacks_ * slices_ * 2;
578 ACG::Vec3f GLCone::positionOnCone(
int _sliceNumber,
int _stackNumber)
582 double beta = ((2.0 * M_PI) / slices_) * _sliceNumber;
584 double relativeHeight = _stackNumber / (double) stacks_;
585 double ringRadius = (1.0 - relativeHeight) * bottomRadius_ + relativeHeight * topRadius_;
586 position[0] = sin(beta) * ringRadius;
587 position[1] = cos(beta) * ringRadius;
588 position[2] = relativeHeight;
595 ACG::Vec2f GLCone::texCoordOnCone(
int _sliceNumber,
int _stackNumber)
599 texCoord[0] = _sliceNumber / (double) slices_;
600 texCoord[1] = _stackNumber / (double) stacks_;
607 ACG::Vec3f GLCone::normalOnCone(
int _sliceNumber,
int _stackNumber)
611 double beta = ((2.0 * M_PI) / slices_) * _sliceNumber;
614 normal[0] = sin(beta);
615 normal[1] = cos(beta);
616 normal[2] = (bottomRadius_ - topRadius_);
624 void GLCone::addTriangle(
int sl0,
int st0,
int sl1,
int st1,
int sl2,
int st2)
630 p[0] = positionOnCone(sl0, st0);
631 p[1] = positionOnCone(sl1, st1);
632 p[2] = positionOnCone(sl2, st2);
633 if (normalOrientation_ == OUTSIDE) {
634 n[0] = normalOnCone(sl0, st0);
635 n[1] = normalOnCone(sl1, st1);
636 n[2] = normalOnCone(sl2, st2);
637 }
else if (normalOrientation_ == INSIDE) {
638 n[0] = -normalOnCone(sl0, st0);
639 n[1] = -normalOnCone(sl1, st1);
640 n[2] = -normalOnCone(sl2, st2);
642 tex[0] = texCoordOnCone(sl0, st0);
643 tex[1] = texCoordOnCone(sl1, st1);
644 tex[2] = texCoordOnCone(sl2, st2);
646 addTriangleToVBO(p, n, tex);
651 void GLCone::updateVBO()
653 for (
int sl = 0; sl < slices_; ++sl) {
661 p[1] = positionOnCone(sl + 1, stacks_);
662 p[2] = positionOnCone(sl, stacks_);
663 if (normalOrientation_ == OUTSIDE) {
667 }
else if (normalOrientation_ == INSIDE) {
674 double beta = ((2.0 * M_PI) / slices_) * (sl + 1);
676 beta = ((2.0 * M_PI) / slices_) * (sl);
679 addTriangleToVBO(p, n, tex);
682 for (
int st = 0; st < stacks_; ++st) {
683 addTriangle(sl, st, sl, st + 1, sl + 1, st);
684 addTriangle(sl + 1, st, sl, st + 1, sl + 1, st + 1);
693 p[1] = positionOnCone(sl, 0);
694 p[2] = positionOnCone(sl + 1, 0);
695 if (normalOrientation_ == OUTSIDE) {
699 }
else if (normalOrientation_ == INSIDE) {
706 double beta = ((2.0 * M_PI) / slices_) * (sl);
708 beta = ((2.0 * M_PI) / slices_) * (sl + 1);
711 addTriangleToVBO(p, n, tex);
720 GLCylinder::GLCylinder(
int _slices,
int _stacks,
float _radius,
bool _bottomCap,
bool _topCap) :
721 GLCone(_slices, _stacks, _radius, _radius, _bottomCap, _topCap)
740 innerRadius_(_innerRadius),
741 outerRadius_(_outerRadius),
742 startAngle_(_startAngle),
743 sweepAngle_(_sweepAngle)
750 void GLPartialDisk::setInnerRadius(
float _innerRadius) {
751 if (innerRadius_ != _innerRadius)
752 vboDataInvalid_ =
true;
753 innerRadius_ = _innerRadius;
758 void GLPartialDisk::setOuterRadius(
float _outerRadius) {
759 if (outerRadius_ != _outerRadius)
760 vboDataInvalid_ =
true;
761 outerRadius_ = _outerRadius;
766 int GLPartialDisk::getNumTriangles() {
767 return slices_ * (loops_+1) * 2;
772 void GLPartialDisk::updateVBO() {
773 assert(slices_ >= 2);
775 assert(outerRadius_ > 0.0f);
776 assert(innerRadius_ >= 0.0f);
777 assert(innerRadius_ < outerRadius_);
779 if (sweepAngle_ < -360.0f)
780 sweepAngle_ = 360.0f;
781 if (sweepAngle_ > 360.0f)
782 sweepAngle_ = 360.0f;
783 if (sweepAngle_ < 0) {
784 startAngle_ += sweepAngle_;
785 sweepAngle_ = -sweepAngle_;
788 float* sinCache =
new float[slices_+1];
789 float* cosCache =
new float[slices_+1];
792 float angleOffsetRadian = startAngle_ * M_PI / 180.0f;
793 float sweepAngleRadian = sweepAngle_ * M_PI / 180.0f;
794 for (
int i = 0; i < slices_+1; ++i) {
795 float angle = angleOffsetRadian + sweepAngleRadian * i/slices_;
796 sinCache[i] = sin(angle);
797 cosCache[i] = cos(angle);
801 float deltaRadius = outerRadius_ - innerRadius_;
802 for (
int i = loops_+1; i > 0; --i) {
805 for (
int j = 0; j < slices_; ++j) {
815 float innerRadius = outerRadius_ - deltaRadius * ((float) i / (loops_ + 1));
817 float outerRadius = outerRadius_ - deltaRadius * ((float) (i - 1) / (loops_ + 1));
824 p[0] =
ACG::Vec3f(innerRadius * sinCache[j], innerRadius * cosCache[j], 0.0f);
825 p[1] =
ACG::Vec3f(outerRadius * sinCache[j], outerRadius * cosCache[j], 0.0f);
826 p[2] =
ACG::Vec3f(outerRadius * sinCache[j+1], outerRadius * cosCache[j+1], 0.0f);
836 addTriangleToVBO(p, n, tex);
843 p2[0] =
ACG::Vec3f(innerRadius * sinCache[j], innerRadius * cosCache[j], 0.0f);
844 p2[1] =
ACG::Vec3f(outerRadius * sinCache[j+1], outerRadius * cosCache[j+1], 0.0f);
845 p2[2] =
ACG::Vec3f(innerRadius * sinCache[j+1], innerRadius * cosCache[j+1], 0.0f);
855 addTriangleToVBO(p2, n2, tex2);
887 for (
int i = 0; i < 3; ++i) {
888 mAlign(i, 0) = vRotAxis[i];
889 mAlign(i, 1) = vUp[i];
890 mAlign(i, 2) = _upDir[i];
902 GLPrimitive::draw_primitive();
917 GLDisk::GLDisk(
int _slices,
int _loops,
float _innerRadius,
float _outerRadius) :
918 GLPartialDisk(_slices, _loops, _innerRadius, _outerRadius, 0.0f, 360.0f)
936 int GLBox::getNumTriangles()
943 void GLBox::updateVBO()
945 static const Vec3f pos[8] =
947 Vec3f(-0.5f,-0.5f,0.5f),
Vec3f(-0.5f,-0.5f,-0.5f),
Vec3f(0.5f,-0.5f,-0.5f),
949 Vec3f(0.5f,0.5f,-0.5f),
Vec3f(-0.5f,0.5f,-0.5f)
952 static const Vec3f norm[6] =
958 static const Vec2f texc[4] =
964 static const int tris[12][9] =
966 {0,1,2 ,0,0,0 ,0,1,2}, {2,3,0 ,0,0,0 ,2,3,0}, {4,5,6 ,1,1,1 ,3,0,1},
967 {6,7,4 ,1,1,1 ,1,2,3}, {0,3,5 ,2,2,2 ,3,0,1}, {5,4,0 ,2,2,2 ,1,2,3},
968 {3,2,6 ,3,3,3 ,3,0,1}, {6,5,3 ,3,3,3 ,1,2,3}, {2,1,7 ,4,4,4 ,3,0,1},
969 {7,6,2 ,4,4,4 ,1,2,3}, {1,0,4 ,5,5,5 ,3,0,1}, {4,7,1 ,5,5,5 ,1,2,3}
972 for (
int i = 0; i < 12; ++i)
974 Vec3f triPos[3] = { pos[tris[i][0]], pos[tris[i][1]], pos[tris[i][2]] };
975 Vec3f triNorm[3] = { norm[tris[i][3]], norm[tris[i][4]], norm[tris[i][5]] };
976 Vec2f triTexc[3] = { texc[tris[i][6]], texc[tris[i][7]], texc[tris[i][8]] };
978 addTriangleToVBO(triPos, triNorm, triTexc);
984 GLLineBox::GLLineBox()
989 GLLineBox::~GLLineBox()
995 int GLLineBox::getNumTriangles()
1000 int GLLineBox::getNumLines()
1007 void GLLineBox::updateVBO()
1009 static const Vec3f pos[8] =
1011 Vec3f(-0.5f,-0.5f,0.5f),
Vec3f(-0.5f,-0.5f,-0.5f),
Vec3f(0.5f,-0.5f,-0.5f),
1012 Vec3f(0.5f,-0.5f,0.5f),
Vec3f(-0.5f,0.5f,0.5f),
Vec3f(0.5f,0.5f,0.5f),
1013 Vec3f(0.5f,0.5f,-0.5f),
Vec3f(-0.5f,0.5f,-0.5f)
1016 static const Vec3f norm[6] =
1022 static const Vec2f texc[4] =
1028 static const int lines[12][6] =
1030 {1,2, 0,0, 0,3}, {0,3, 0,0, 0,3}, {4,5, 0,0, 0,3}, {7,6, 0,0, 0,3},
1031 {1,7, 0,0, 0,3}, {0,4, 0,0, 0,3}, {2,6, 0,0, 0,3}, {3,5, 0,0, 0,3},
1032 {1,0, 0,0, 0,3}, {2,3, 0,0, 0,3}, {7,4, 0,0, 0,3}, {6,5, 0,0, 0,3}
1035 for (
int i = 0; i < 12; ++i)
1037 Vec3f p[2] = { pos[lines[i][0]], pos[lines[i][1]]};
1038 Vec3f n[2] = { norm[lines[i][2]], norm[lines[i][3]]};
1039 Vec2f t[2] = { texc[lines[i][4]], texc[lines[i][5]]};
1041 addLineToVBO(p, n, t);
1049 GLDodecahedron::GLDodecahedron()
1054 GLDodecahedron::~GLDodecahedron()
1060 int GLDodecahedron::getNumTriangles()
1067 void GLDodecahedron::updateVBO()
1069 static const Vec3f pos[20] =
1070 {
Vec3f( 1 , 1 , 1 ),
1071 Vec3f( 1 , 1 , -1 ),
1072 Vec3f( 1 , -1 , 1 ),
1073 Vec3f( 1 , -1 , -1 ),
1074 Vec3f( -1 , 1 , 1 ),
1075 Vec3f( -1 , 1 , -1 ),
1076 Vec3f( -1 , -1 , 1 ),
1077 Vec3f( -1 , -1 , -1 ),
1078 Vec3f( 0 , 0.618034 , 1.61803 ),
1079 Vec3f( 0 , 0.618034 , -1.61803 ),
1080 Vec3f( 0 , -0.618034 , 1.61803 ),
1081 Vec3f( 0 , -0.618034 , -1.61803 ),
1082 Vec3f( 0.618034 , 1.61803 , 0 ),
1083 Vec3f( 0.618034 , -1.61803 , 0 ),
1084 Vec3f( -0.618034 , 1.61803 , 0 ),
1085 Vec3f( -0.618034 , -1.61803 , 0 ),
1086 Vec3f( 1.61803 , 0 , 0.618034 ),
1087 Vec3f( 1.61803 , 0 , -0.618034 ),
1088 Vec3f( -1.61803 , 0 , 0.618034 ),
1089 Vec3f( -1.61803 , 0 , -0.618034 )
1092 static const Vec3f norm[20] =
1094 Vec3f( 0.57735 , 0.57735 , 0.57735 ),
1095 Vec3f( 0.57735 , 0.57735 , -0.57735 ),
1096 Vec3f( 0.57735 , -0.57735 , 0.57735 ),
1097 Vec3f( 0.57735 , -0.57735 , -0.57735 ),
1098 Vec3f( -0.57735 , 0.57735 , 0.57735 ),
1099 Vec3f( -0.57735 , 0.57735 , -0.57735 ),
1100 Vec3f( -0.57735 , -0.57735 , 0.57735 ),
1101 Vec3f( -0.57735 , -0.57735 , -0.57735 ),
1102 Vec3f( 0 , 0.356822 , 0.934172 ),
1103 Vec3f( 0 , 0.356822 , -0.934172 ),
1104 Vec3f( 0 , -0.356822 , 0.934172 ),
1105 Vec3f( 0 , -0.356822 , -0.934172 ),
1106 Vec3f( 0.356822 , 0.934172 , 0 ),
1107 Vec3f( 0.356822 , -0.934172 , 0 ),
1108 Vec3f( -0.356822 , 0.934172 , 0 ),
1109 Vec3f( -0.356822 , -0.934172 , 0 ),
1110 Vec3f( 0.934172 , 0 , 0.356822 ),
1111 Vec3f( 0.934172 , 0 , -0.356822 ),
1112 Vec3f( -0.934172 , 0 , 0.356822 ),
1113 Vec3f( -0.934172 , 0 , -0.356822 )
1116 static const Vec2f texc[20] =
1143 static const int tris[36][9] =
1145 { 20,20,20, 19,19,19, 5,5,5 },
1146 { 12,12,12, 8,8,8, 20,20,20 },
1147 { 14,14,14, 3,3,3, 11,11,11 },
1148 { 17,17,17, 18,18,18, 2,2,2 },
1149 { 11,11,11, 3,3,3, 17,17,17 },
1150 { 14,14,14, 4,4,4, 18,18,18 },
1151 { 16,16,16, 8,8,8, 12,12,12 },
1152 { 7,7,7, 19,19,19, 20,20,20 },
1153 { 7,7,7, 11,11,11, 9,9,9 },
1154 { 1,1,1, 13,13,13, 15,15,15 },
1155 { 2,2,2, 10,10,10, 6,6,6 },
1156 { 18,18,18, 4,4,4, 12,12,12 },
1157 { 15,15,15, 6,6,6, 5,5,5 },
1158 { 6,6,6, 20,20,20, 5,5,5 },
1159 { 6,6,6, 10,10,10, 20,20,20 },
1160 { 10,10,10, 12,12,12, 20,20,20 },
1161 { 7,7,7, 16,16,16, 11,11,11 },
1162 { 16,16,16, 14,14,14, 11,11,11 },
1163 { 13,13,13, 1,1,1, 2,2,2 },
1164 { 1,1,1, 17,17,17, 2,2,2 },
1165 { 1,1,1, 9,9,9, 17,17,17 },
1166 { 9,9,9, 11,11,11, 17,17,17 },
1167 { 17,17,17, 3,3,3, 18,18,18 },
1168 { 3,3,3, 14,14,14, 18,18,18 },
1169 { 4,4,4, 14,14,14, 12,12,12 },
1170 { 14,14,14, 16,16,16, 12,12,12 },
1171 { 8,8,8, 16,16,16, 20,20,20 },
1172 { 16,16,16, 7,7,7, 20,20,20 },
1173 { 5,5,5, 19,19,19, 9,9,9 },
1174 { 19,19,19, 7,7,7, 9,9,9 },
1175 { 5,5,5, 9,9,9, 15,15,15 },
1176 { 9,9,9, 1,1,1, 15,15,15 },
1177 { 15,15,15, 13,13,13, 6,6,6 },
1178 { 13,13,13, 2,2,2, 6,6,6 },
1179 { 10,10,10, 2,2,2, 12,12,12 },
1180 { 2,2,2, 18,18,18, 12,12,12 }
1184 for (
int i = 0; i < 36; ++i)
1186 Vec3f p[3] = { pos[tris[i][0]-1], pos[tris[i][3]-1], pos[tris[i][6]-1]};
1187 Vec3f n[3] = { norm[tris[i][2]-1], norm[tris[i][5]-1], norm[tris[i][8]-1]};
1188 Vec2f t[3] = { texc[tris[i][1]-1], texc[tris[i][4]-1], texc[tris[i][7]-1]};
1190 addTriangleToVBO(p, n, t);
1196 GLIcosahedron::GLIcosahedron()
1201 GLIcosahedron::~GLIcosahedron()
1207 int GLIcosahedron::getNumTriangles()
1214 void GLIcosahedron::updateVBO()
1216 static const Vec3f pos[12] =
1218 Vec3f( 0 , -1 , -1.61803),
1219 Vec3f( 0 , 1 , -1.61803),
1220 Vec3f( 0 , 1 , 1.61803 ),
1221 Vec3f( 0 , -1 , 1.61803 ),
1222 Vec3f( -1 , -1.61803, 0 ),
1223 Vec3f( 1 , -1.61803, 0 ),
1224 Vec3f( 1 , 1.61803 , 0 ),
1225 Vec3f( -1 , 1.61803 , 0 ),
1226 Vec3f( -1.61803 , 0 , -1 ),
1227 Vec3f( -1.61803 , 0 , 1 ),
1228 Vec3f( 1.61803 , 0 , 1 ),
1229 Vec3f( 1.61803 , 0 , -1 )
1232 static const Vec3f norm[12] =
1234 Vec3f( 0 , -0.525731 , -0.850651 ),
1235 Vec3f( 2.79423e-17, 0.525731 , -0.850651 ),
1236 Vec3f( 0 , 0.525731 , 0.850651 ),
1237 Vec3f( 2.79423e-17, -0.525731 , 0.850651 ),
1238 Vec3f( -0.525731 , -0.850651 , 0 ),
1239 Vec3f( 0.525731 , -0.850651 , 2.79423e-17 ),
1240 Vec3f( 0.525731 , 0.850651 , 0 ),
1241 Vec3f( -0.525731 , 0.850651 , 0 ),
1242 Vec3f( -0.850651 , 2.79423e-17, 0.525731 ),
1243 Vec3f( 0.850651 , 0 , 0.525731 ),
1244 Vec3f( -0.850651 , 0 , -0.525731 ),
1245 Vec3f( 0.850651 , 2.79423e-17, -0.525731 )
1248 static const Vec2f texc[12] =
1267 static const int tris[20][9] =
1269 { 3,3,3, 7,7,7, 8,8,8, },
1270 { 8,8,8, 7,7,7, 2,2,2, },
1271 { 12,12,12, 1,1,1, 2,2,2, },
1272 { 1,1,1, 9,9,9, 2,2,2, },
1273 { 5,5,5, 10,10,10, 9,9,9, },
1274 { 9,9,9, 10,10,10, 8,8,8, },
1275 { 10,10,10, 4,4,4, 3,3,3, },
1276 { 11,11,1,3,3,3, 4,4,4, },
1277 { 6,6,6, 12,12,12, 11,11,1, },
1278 { 12,12,12, 7,7,7, 11,11,1, },
1279 { 1,1,1, 6,6,6, 5,5,5, },
1280 { 6,6,6, 4,4,4, 5,5,5, },
1281 { 7,7,7, 3,3,3, 11,11,1, },
1282 { 7,7,7, 12,12,12, 2,2,2, },
1283 { 2,2,2, 9,9,9, 8,8,8, },
1284 { 10,10,10, 3,3,3, 8,8,8, },
1285 { 4,4,4, 6,6,6, 11,11,1, },
1286 { 1,1,1, 12,12,12, 6,6,6, },
1287 { 4,4,4, 10,10,10, 5,5,5, },
1288 { 1,1,1, 5,5,5, 9,9,9, }
1292 for (
int i = 0; i < 20; ++i)
1294 Vec3f p[3] = { pos[tris[i][0]-1], pos[tris[i][3]-1], pos[tris[i][6]-1]};
1295 Vec3f n[3] = { norm[tris[i][2]-1], norm[tris[i][5]-1], norm[tris[i][8]-1]};
1296 Vec2f t[3] = { texc[tris[i][1]-1], texc[tris[i][4]-1], texc[tris[i][7]-1]};
1298 addTriangleToVBO(p, n, t);
1304 GLOctahedron::GLOctahedron()
1309 GLOctahedron::~GLOctahedron()
1315 int GLOctahedron::getNumTriangles()
1322 void GLOctahedron::updateVBO()
1324 static const Vec3f pos[6] =
1326 Vec3f( -1.41421 , 0 , 0 ),
1327 Vec3f( 0 , -1.41421, 0 ),
1328 Vec3f( 1.41421 , 0 , 0 ),
1329 Vec3f( 0 , 1.41421 , 0 ),
1330 Vec3f( 0 , 0 , 1.41421 ),
1331 Vec3f( 0 , 0 , -1.41421)
1334 static const Vec3f norm[6] =
1344 static const Vec2f texc[6] =
1357 static const int tris[8][9] =
1359 { 1,1,1, 2,2,2, 5,5,5 },
1360 { 2,2,2, 3,3,3, 5,5,5 },
1361 { 3,3,3, 4,4,4, 5,5,5 },
1362 { 1,1,1, 5,5,5, 4,4,4 },
1363 { 6,6,6, 2,2,2, 1,1,1 },
1364 { 6,6,6, 3,3,3, 2,2,2 },
1365 { 6,6,6, 4,4,4, 3,3,3 },
1366 { 6,6,6, 1,1,1, 4,4,4 }
1370 for (
int i = 0; i < 8; ++i)
1372 Vec3f p[3] = { pos[tris[i][0]-1], pos[tris[i][3]-1], pos[tris[i][6]-1]};
1373 Vec3f n[3] = { norm[tris[i][2]-1], norm[tris[i][5]-1], norm[tris[i][8]-1]};
1374 Vec2f t[3] = { texc[tris[i][1]-1], texc[tris[i][4]-1], texc[tris[i][7]-1]};
1376 addTriangleToVBO(p, n, t);
1382 GLTetrahedron::GLTetrahedron()
1387 GLTetrahedron::~GLTetrahedron()
1393 int GLTetrahedron::getNumTriangles()
1400 void GLTetrahedron::updateVBO()
1402 static const Vec3f pos[4] =
1406 Vec3f( -1, 1 , -1 ),
1410 static const Vec3f norm[4] =
1412 Vec3f( -0.57735, -0.57735, 0.57735 ),
1413 Vec3f( 0.57735 , 0.57735 , 0.57735 ),
1414 Vec3f( -0.57735, 0.57735 , -0.57735 ),
1415 Vec3f( 0.57735 , -0.57735, -0.57735 )
1418 static const Vec2f texc[4] =
1429 static const int tris[4][9] =
1431 { 1, 1, 1, 2, 2, 2, 3, 3, 3 },
1432 { 1, 1, 1, 3, 3, 3, 4, 4, 4 },
1433 { 3, 3, 3, 2, 2, 2, 4, 4, 4 },
1434 { 4, 4, 4, 2, 2, 2, 1, 1, 1 }
1438 for (
int i = 0; i < 4; ++i)
1440 Vec3f p[3] = { pos[tris[i][0]-1], pos[tris[i][3]-1], pos[tris[i][6]-1]};
1441 Vec3f n[3] = { norm[tris[i][2]-1], norm[tris[i][5]-1], norm[tris[i][8]-1]};
1442 Vec2f t[3] = { texc[tris[i][1]-1], texc[tris[i][4]-1], texc[tris[i][7]-1]};
1444 addTriangleToVBO(p, n, t);
1449 GLTorus::GLTorus(GLdouble innerRadius,
1450 GLdouble outerRadius,
1451 GLint nsides, GLint rings):
1454 innerRadius_(innerRadius),
1455 outerRadius_(outerRadius)
1467 int GLTorus::getNumTriangles()
1469 return rings_*nsides_*2;
1474 void GLTorus::updateVBO()
1482 std::vector<Vec3f> points;
1483 std::vector<Vec3f> normals;
1484 std::vector<Vec2f> texCoords;
1485 std::vector<Vec3f> unitRing;
1487 float ringSegmentAngle = 2 * M_PI / nsides_;
1488 float torusSegmentAngle = 2 * M_PI / rings_;
1491 for (
int i = 0 ; i < nsides_ ; ++i)
1493 Vec3f ringPoint =
Vec3f(cos(ringSegmentAngle * i),0.0f,sin(ringSegmentAngle *i));
1494 unitRing.push_back(ringPoint);
1498 for(
int j = 0; j < rings_ ; ++j)
1502 for(
Vec3f point : unitRing)
1505 torusPoint = point * (1.f/innerRadius_);
1507 torusPoint +=
Vec3f(outerRadius_ + innerRadius_,0,0);
1509 Vec3f pointOnTorus =
Vec3f(torusPoint[0] * cos(j*torusSegmentAngle) + torusPoint[1] * sin(j*torusSegmentAngle),
1510 torusPoint[0] * -sin(j*torusSegmentAngle) + torusPoint[1] * cos(j*torusSegmentAngle),
1513 points.push_back(pointOnTorus);
1516 Vec3f normalOnTorus =
Vec3f(point[0] * cos(j*torusSegmentAngle) + point[1] * sin(j*torusSegmentAngle),
1517 point[0] * -sin(j*torusSegmentAngle) + point[1] * cos(j*torusSegmentAngle),
1521 normals.push_back(normalOnTorus);
1526 texCoords.push_back(
Vec2f(j/rings_,side/nsides_));
1534 int end = rings_*nsides_;
1535 int segmentOffset = nsides_;
1537 for(
int i = 0 ; i < end ; ++i)
1539 if((i+1) % nsides_ == 0)
1542 oddIndex = -nsides_;
1546 segmentOffset = nsides_;
1550 Vec3f p[3] = { points[i] , points[(i+nsides_)%end] , points[(i+segmentOffset+1)%end] };
1551 Vec3f n[3] = { normals[i] , normals[(i+nsides_)%end] , normals[(i+segmentOffset+1)%end] };
1552 Vec2f t[3] = { texCoords[i] , texCoords[(i+nsides_)%end] , texCoords[(i+segmentOffset+1)%end] };
1553 addTriangleToVBO(p, n, t);
1555 Vec3f p2[3] = { points[(i+1 + oddIndex)%end] , points[(i)%end] , points[(i+segmentOffset+1)%end] };
1556 Vec3f n2[3] = { normals[(i+1 + oddIndex)%end] , normals[(i)%end] , normals[(i+segmentOffset+1)%end] };
1557 Vec2f t2[3] = { texCoords[(i+1 + oddIndex)%end] , texCoords[(i)%end], texCoords[(i+segmentOffset+1)%end] };
1558 addTriangleToVBO(p2, n2, t2);
void pop_modelview_matrix()
pop modelview matrix
osg::Vec3f cross(const osg::Vec3f &_v1, const osg::Vec3f &_v2)
Adapter for osg vector member computing a scalar product.
VectorT< float, 2 > Vec2f
Namespace providing different geometric functions concerning angles.
void identity()
setup an identity matrix
void mult_matrix(const GLMatrixd &_m, const GLMatrixd &_inv_m, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply by a given transformation matrix
bool invert()
matrix inversion (returns true on success)
void push_modelview_matrix()
push modelview matrix
VectorT< float, 3 > Vec3f
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
GLDisk(int _slices, int _loops, float _innerRadius, float _outerRadius)
void compatibilityProfile(bool _enableCoreProfile)
Store opengl core profile setting.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
osg::Vec3f::ValueType dot(const osg::Vec3f &_v1, const osg::Vec3f &_v2)
Adapter for osg vector member computing a scalar product.
GLPartialDisk(int _slices, int _loops, float _innerRadius, float _outerRadius, float _startAngle, float _sweepAngle)
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)