123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- /***************************************************************************
- OpenGLVisitor.cpp - description
- -------------------
- begin : Sat Jan 6 2001
- copyright : (C) 2001 by Henrik Enqvist
- email : henqvist@excite.com
- ***************************************************************************/
- #include "Private.h"
- #include "OpenGLVisitor.h"
- #include "Group.h"
- #include "Shape3D.h"
- #include "Polygon.h"
- #include "BillBoard.h"
- #include "Config.h"
- #ifndef EM_VERTEXARRAY
- #define EM_VERTEXARRAY 0
- #endif
- #ifndef EM_OPENGL_LIGHTS
- #define EM_OPENGL_LIGHTS 0
- #endif
- /* Optimization observations:
- * * Voodoo 3 System
- * glVertex3f is a bit fatser than glVertex3fv ~3%.
- * glVertex3f is faster then glVertexArray ~10-20%, really strange.
- */
- OpenGLVisitor * OpenGLVisitor::p_OpenGLVisitor = NULL;
- int OpenGLVisitor::m_iPoly = 0;
- OpenGLVisitor::OpenGLVisitor(){
- m_iMode = EM_GL_GCOL_TEX;
- m_bOffset = false;
- }
- OpenGLVisitor::~OpenGLVisitor(){
- p_OpenGLVisitor = NULL;
- }
- OpenGLVisitor * OpenGLVisitor::getInstance() {
- if (p_OpenGLVisitor == NULL) {
- p_OpenGLVisitor = new OpenGLVisitor();
- }
- return p_OpenGLVisitor;
- }
- void OpenGLVisitor::empty() {
- #if EM_USE_SDL
- #if EM_VERTEXARRAY
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
- #endif
-
- switch (m_iMode) {
- case EM_GL_GCOL_TEX: {
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- //glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glDisable(GL_ALPHA_TEST);
- glDepthMask(GL_TRUE);
- } break;
- case EM_GL_GCOL_TEX_TRANS: {
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- //glDisable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDepthMask(GL_FALSE);
- // glEnable(GL_ALPHA_TEST);
- // glAlphaFunc(GL_GREATER, 0.05);
- } break;
- case EM_GL_CLEAN: {
- #if EM_DEBUG
- m_iPoly = 0;
- #endif
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_ALPHA_TEST);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- } break;
- }
- #endif
- }
- void OpenGLVisitor::visit(Group* g) {
- #if EM_USE_SDL
- int filter = Config::getInstance()->getGLFilter();
- //bool lights = Config::getInstance()->useLights();
- switch (m_iMode) {
- case EM_GL_GCOL_TEX: {
- // shapes
- vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
- vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
- for ( ; shapeIter != shapeEnd; shapeIter++) {
- if (EM_SHAPE3D_HIDDEN & (*shapeIter)->m_iProperties) continue;
- if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 1.0);
- } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND2) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 2.0);
- } else {
- glDisable(GL_POLYGON_OFFSET_FILL);
- }
- if ((*shapeIter)->m_Texture != NULL && filter != -1) { // textured polygons
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, *((*shapeIter)->m_Texture));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) { // EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; ++polyIter) {
- if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for ( ; indexIter != indexEnd; ++indexIter) {
- glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
- (*shapeIter)->m_vTexCoord[(*indexIter)].v);
- glColor3f((*shapeIter)->m_vColor[(*indexIter)].r,
- (*shapeIter)->m_vColor[(*indexIter)].g,
- (*shapeIter)->m_vColor[(*indexIter)].b);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- } else { // ! EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; ++polyIter) {
- if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for ( ; indexIter != indexEnd; ++indexIter) {
- glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
- (*shapeIter)->m_vTexCoord[(*indexIter)].v);
- // Question should textured polygons have specular?
- glColor3f((*shapeIter)->m_vLight[(*indexIter)].r,
- (*shapeIter)->m_vLight[(*indexIter)].g,
- (*shapeIter)->m_vLight[(*indexIter)].b);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- }
- } else { // if ((*shapeIter)->m_Texture... // color polygons
- glDisable(GL_TEXTURE_2D);
- // if statement moved outside for loop for performance
- if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) { // EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; ++polyIter) {
- if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for (; indexIter != indexEnd; ++indexIter) {
- glColor3f((*shapeIter)->m_vColor[(*indexIter)].r,
- (*shapeIter)->m_vColor[(*indexIter)].g,
- (*shapeIter)->m_vColor[(*indexIter)].b);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- } else { // ! EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; ++polyIter) {
- if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for (; indexIter != indexEnd; ++indexIter) {
- glColor3f((*shapeIter)->m_vLitColor[(*indexIter)].r,
- (*shapeIter)->m_vLitColor[(*indexIter)].g,
- (*shapeIter)->m_vLitColor[(*indexIter)].b);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- }
- }
- }
- // billboard
- BillBoard * b = g->p_BillBoard;
- if (b != NULL && !(b->m_iProperties & EM_BILLBOARD_TRANS)) {
- EmAssert(b->m_Texture != NULL, "all billboards must have a texture");
- glBindTexture(GL_TEXTURE_2D, *(b->m_Texture));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- // a textured polygon
- glColor3f(1, 1, 1);
- glBegin(GL_POLYGON);
- glTexCoord2f(0, 0);
- glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
- b->m_vtxAlign.y + b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glTexCoord2f(1, 0);
- glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
- b->m_vtxAlign.y + b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glTexCoord2f(1, 1);
- glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
- b->m_vtxAlign.y - b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glTexCoord2f(0, 1);
- glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
- b->m_vtxAlign.y - b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glEnd();
-
- EM_COUT_D("OpenGLVisitor::visit() BillBoard at " << b->m_vtxAlign.x <<" "<<
- b->m_vtxAlign.y <<" "<< b->m_vtxAlign.z, 0);
- }
- } break;
- case EM_GL_GCOL_TEX_TRANS: {
- vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
- vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
- for ( ; shapeIter != shapeEnd; shapeIter++) {
- if (EM_SHAPE3D_HIDDEN & (*shapeIter)->m_iProperties) continue;
- if (!(EM_SHAPE3D_USE_TRANS & (*shapeIter)->m_iProperties)) continue;
- #if 0 // I used wireframes when showing some demos in school
- {
- // wireframe
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, -1.0);
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; ++polyIter) {
- ++m_iPoly;
- glColor3f(0.0f, 0.0f, 0.0f);
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_LINE_LOOP);
- for ( ; indexIter != indexEnd; ++indexIter) {
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- glDisable(GL_POLYGON_OFFSET_FILL);
- }
- #endif
- if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 1.0);
- } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND2) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 2.0);
- } else {
- glDisable(GL_POLYGON_OFFSET_FILL);
- }
- if ((*shapeIter)->m_Texture != NULL && filter != -1) { // textured polygon
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, *((*shapeIter)->m_Texture));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) { // EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; polyIter++) {
- if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- // textured polygon
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for ( ; indexIter != indexEnd; indexIter++) {
- glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
- (*shapeIter)->m_vTexCoord[(*indexIter)].v);
- glColor4f((*shapeIter)->m_vColor[(*indexIter)].r,
- (*shapeIter)->m_vColor[(*indexIter)].g,
- (*shapeIter)->m_vColor[(*indexIter)].b,
- (*shapeIter)->m_vColor[(*indexIter)].a);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- } else { // ! EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; polyIter++) {
- if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- // textured polygon
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for ( ; indexIter != indexEnd; indexIter++) {
- glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
- (*shapeIter)->m_vTexCoord[(*indexIter)].v);
- glColor4f((*shapeIter)->m_vLight[(*indexIter)].r,
- (*shapeIter)->m_vLight[(*indexIter)].g,
- (*shapeIter)->m_vLight[(*indexIter)].b,
- (*shapeIter)->m_vLight[(*indexIter)].a);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- }
- } else { // color polygon
- glDisable(GL_TEXTURE_2D);
- if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) {
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; polyIter++) {
- if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for ( ; indexIter != indexEnd; indexIter++) {
- // transparent polygons should not be lit, or ?
- glColor4f((*shapeIter)->m_vColor[(*indexIter)].r,
- (*shapeIter)->m_vColor[(*indexIter)].g,
- (*shapeIter)->m_vColor[(*indexIter)].b,
- (*shapeIter)->m_vColor[(*indexIter)].a);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- } else { // EM_SHAPE3D_ALWAYSLIT
- vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
- for ( ; polyIter != polyEnd; polyIter++) {
- if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
- #if EM_DEBUG
- ++m_iPoly;
- #endif
- vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
- vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
- glBegin(GL_POLYGON);
- for ( ; indexIter != indexEnd; indexIter++) {
- // transparent polygons should not be lit, or ?
- glColor4f((*shapeIter)->m_vLitColor[(*indexIter)].r,
- (*shapeIter)->m_vLitColor[(*indexIter)].g,
- (*shapeIter)->m_vLitColor[(*indexIter)].b,
- (*shapeIter)->m_vLitColor[(*indexIter)].a);
- glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
- (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
- }
- glEnd();
- }
- }
- }
- }
- // billboard
- BillBoard * b = g->p_BillBoard;
- if (b != NULL && b->m_iProperties & EM_BILLBOARD_TRANS) {
- EmAssert(b->m_Texture != NULL, "all billboards must have a texture");
- glBindTexture(GL_TEXTURE_2D, *(b->m_Texture));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- // a textured polygon
- glColor3f(1, 1, 1);
- glBegin(GL_POLYGON);
- glTexCoord2f(0, 0);
- glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
- b->m_vtxAlign.y + b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glTexCoord2f(1, 0);
- glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
- b->m_vtxAlign.y + b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glTexCoord2f(1, 1);
- glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
- b->m_vtxAlign.y - b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glTexCoord2f(0, 1);
- glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
- b->m_vtxAlign.y - b->m_fSizeyD2,
- b->m_vtxAlign.z);
- glEnd();
-
- EM_COUT_D("OpenGLVisitor::visit() BillBoard at " << b->m_vtxAlign.x <<" "<<
- b->m_vtxAlign.y <<" "<< b->m_vtxAlign.z, 0);
- }
- } break;
- }
- #endif // EM_USE_SDL
- }
|