Exemplo n.º 1
0
/* texture unit 2: additional sphere map texture, if exist */
void PMDModel::renderModel()
{
   unsigned long i;
   float c[4];
   PMDMaterial *m;
   float modelAlpha;
   unsigned short *surfaceData;

   if (!m_vertexList) return;

#ifndef MMDFILES_CONVERTCOORDINATESYSTEM
   glPushMatrix();
   glScalef(1.0f, 1.0f, -1.0f); /* from left-hand to right-hand */
   glCullFace(GL_FRONT);
#endif /* !MMDFILES_CONVERTCOORDINATESYSTEM */

   /* activate texture unit 0 */
   glActiveTextureARB(GL_TEXTURE0_ARB);
   glClientActiveTextureARB(GL_TEXTURE0_ARB);

   /* set lists */
   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_NORMAL_ARRAY);
   glVertexPointer(3, GL_FLOAT, sizeof(btVector3), m_skinnedVertexList);
   glNormalPointer(GL_FLOAT, sizeof(btVector3), m_skinnedNormalList);
   /* set model texture coordinates to texture unit 0 */
   glClientActiveTextureARB(GL_TEXTURE0_ARB);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glTexCoordPointer(2, GL_FLOAT, 0, m_texCoordList);
   if (m_toon) {
      /* set toon texture coordinates to texture unit 1 */
      glActiveTextureARB(GL_TEXTURE1_ARB);
      glEnable(GL_TEXTURE_2D);
      glClientActiveTextureARB(GL_TEXTURE1_ARB);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      if (m_selfShadowDrawing)
         /* when drawing a shadow part in shadow mapping, force toon texture coordinates to (0, 0) */
         glTexCoordPointer(2, GL_FLOAT, 0, m_toonTexCoordListForShadowMap);
      else
         glTexCoordPointer(2, GL_FLOAT, 0, m_toonTexCoordList);
      glActiveTextureARB(GL_TEXTURE0_ARB);
      glClientActiveTextureARB(GL_TEXTURE0_ARB);
   }
   if (m_hasSingleSphereMap) {
      /* this model contains single sphere map texture */
      /* set texture coordinate generation for sphere map on texture unit 0 */
      glEnable(GL_TEXTURE_2D);
      glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
      glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
      glDisable(GL_TEXTURE_2D);
   }
   if (m_hasMultipleSphereMap) {
      /* this model contains additional sphere map texture */
      /* set texture coordinate generation for sphere map on texture unit 2 */
      glActiveTextureARB(GL_TEXTURE2_ARB);
      glEnable(GL_TEXTURE_2D);
      glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
      glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
      glDisable(GL_TEXTURE_2D);
      glActiveTextureARB(GL_TEXTURE0_ARB);
   }

   /* calculate alpha value, applying model global alpha */
   modelAlpha = m_globalAlpha;
   surfaceData = m_surfaceList;

   /* render per material */
   for (i = 0; i < m_numMaterial; i++) {
      m = &(m_material[i]);
      /* set colors */
      c[3] = m->getAlpha() * modelAlpha;
      if (c[3] > 0.99f) c[3] = 1.0f; /* clamp to 1.0 */
      if (m_toon) {
         /* use averaged color of diffuse and ambient for both */
         m->copyAvgcol(c);
         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, &(c[0]));
         m->copySpecular(c);
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(c[0]));
      } else {
         /* use each color */
         m->copyDiffuse(c);
         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(c[0]));
         m->copyAmbient(c);
         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(c[0]));
         m->copySpecular(c);
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(c[0]));
      }
      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->getShiness());

      /* disable face culling for transparent materials */
      if (m->getAlpha() < 1.0f)
         glDisable(GL_CULL_FACE);
      else
         glEnable(GL_CULL_FACE);

      /* if using multiple texture units, set current unit to 0 */
      if (m_toon || m_hasMultipleSphereMap)
         glActiveTextureARB(GL_TEXTURE0_ARB);

      if (m->getTexture()) {
         /* bind model texture */
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, m->getTexture()->getID());
         if (m_hasSingleSphereMap) {
            if (m->getTexture()->isSphereMap()) {
               /* this is sphere map */
               /* enable texture coordinate generation */
               if (m->getTexture()->isSphereMapAdd())
                  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
               glEnable(GL_TEXTURE_GEN_S);
               glEnable(GL_TEXTURE_GEN_T);
            } else {
               /* disable generation */
               glDisable(GL_TEXTURE_GEN_S);
               glDisable(GL_TEXTURE_GEN_T);
            }
         }
      } else {
         glDisable(GL_TEXTURE_2D);
      }

      if (m_toon) {
         /* set toon texture for texture unit 1 */
         glActiveTextureARB(GL_TEXTURE1_ARB);
         glBindTexture(GL_TEXTURE_2D, m_toonTextureID[m->getToonID()]);
         /* set GL_CLAMP_TO_EDGE for toon texture to avoid texture interpolation at edge */
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      }

      if (m_hasMultipleSphereMap) {
         if (m->getAdditionalTexture()) {
            /* this material has additional sphere map texture, bind it at texture unit 2 */
            glActiveTextureARB(GL_TEXTURE2_ARB);
            glEnable(GL_TEXTURE_2D);
            if (m->getAdditionalTexture()->isSphereMapAdd())
               glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
            else
               glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
            glBindTexture(GL_TEXTURE_2D, m->getAdditionalTexture()->getID());
            glEnable(GL_TEXTURE_GEN_S);
            glEnable(GL_TEXTURE_GEN_T);
         } else {
            /* disable generation */
            glActiveTextureARB(GL_TEXTURE2_ARB);
            glDisable(GL_TEXTURE_2D);
         }
      }

      /* draw elements */
      glDrawElements(GL_TRIANGLES, m->getNumSurface(), GL_UNSIGNED_SHORT, surfaceData);

      /* move surface pointer to next material */
      surfaceData += m->getNumSurface();

      /* reset some parameters */
      if (m->getTexture() && m->getTexture()->isSphereMap() && m->getTexture()->isSphereMapAdd()) {
         if (m_toon)
            glActiveTextureARB(GL_TEXTURE0_ARB);
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
      }
   }

   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_NORMAL_ARRAY);
   if (m_toon) {
      glClientActiveTextureARB(GL_TEXTURE0_ARB);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
      if (m_hasSingleSphereMap) {
         glActiveTextureARB(GL_TEXTURE0_ARB);
         glDisable(GL_TEXTURE_GEN_S);
         glDisable(GL_TEXTURE_GEN_T);
      }
      glClientActiveTextureARB(GL_TEXTURE1_ARB);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
      if (m_hasMultipleSphereMap) {
         glActiveTextureARB(GL_TEXTURE2_ARB);
         glDisable(GL_TEXTURE_GEN_S);
         glDisable(GL_TEXTURE_GEN_T);
      }
      glActiveTextureARB(GL_TEXTURE0_ARB);
   } else {
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
      if (m_hasSingleSphereMap) {
         glDisable(GL_TEXTURE_GEN_S);
         glDisable(GL_TEXTURE_GEN_T);
      }
      if (m_hasMultipleSphereMap) {
         glActiveTextureARB(GL_TEXTURE2_ARB);
         glDisable(GL_TEXTURE_GEN_S);
         glDisable(GL_TEXTURE_GEN_T);
         glActiveTextureARB(GL_TEXTURE0_ARB);
      }
   }

   if (m_hasSingleSphereMap || m_hasMultipleSphereMap) {
      glDisable(GL_TEXTURE_GEN_S);
      glDisable(GL_TEXTURE_GEN_T);
   }
   if (m_toon) {
      glActiveTextureARB(GL_TEXTURE1_ARB);
      glDisable(GL_TEXTURE_2D);
   }
   if (m_hasMultipleSphereMap) {
      glActiveTextureARB(GL_TEXTURE2_ARB);
      glDisable(GL_TEXTURE_2D);
   }
   glActiveTextureARB(GL_TEXTURE0_ARB);

   glDisable(GL_TEXTURE_2D);
   glEnable(GL_CULL_FACE);
#ifndef MMDFILES_CONVERTCOORDINATESYSTEM
   glCullFace(GL_BACK);
   glPopMatrix();
#endif /* !MMDFILES_CONVERTCOORDINATESYSTEM */
}
Exemplo n.º 2
0
/* texture unit 2: additional sphere map texture, if exist */
void PMDModel::renderModel()
{
    unsigned int i;
    float c[4];
    PMDMaterial *m;
    float modelAlpha;
    unsigned int numSurface;
    unsigned int surfaceOffset;
    bool drawEdge;

    if (!m_vertexList) return;
    if (!m_showFlag) return;

#ifndef MMDFILES_CONVERTCOORDINATESYSTEM
    glPushMatrix();
    glScalef(1.0f, 1.0f, -1.0f); /* from left-hand to right-hand */
    glCullFace(GL_FRONT);
#endif /* !MMDFILES_CONVERTCOORDINATESYSTEM */

    /* activate texture unit 0 */
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glClientActiveTextureARB(GL_TEXTURE0_ARB);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, m_vboBufStatic);
    glTexCoordPointer(2, GL_FLOAT, 0, (const GLvoid *) NULL);

    glBindBuffer(GL_ARRAY_BUFFER, m_vboBufDynamic);

    /* set lists */
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(btVector3), (const GLvoid *) m_vboOffsetVertex);
    glNormalPointer(GL_FLOAT, sizeof(btVector3), (const GLvoid *) m_vboOffsetNormal);
    if (m_toon) {
        /* set toon texture coordinates to texture unit 1 */
        glActiveTextureARB(GL_TEXTURE1_ARB);
        glEnable(GL_TEXTURE_2D);
        glClientActiveTextureARB(GL_TEXTURE1_ARB);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        if (m_selfShadowDrawing) {
            glBindBuffer(GL_ARRAY_BUFFER, m_vboBufStatic);
            glTexCoordPointer(2, GL_FLOAT, 0, (const GLvoid *) m_vboOffsetCoordForShadowMap);
            glBindBuffer(GL_ARRAY_BUFFER, m_vboBufDynamic);
        } else
            glTexCoordPointer(2, GL_FLOAT, 0, (const GLvoid *) m_vboOffsetToon);
        glActiveTextureARB(GL_TEXTURE0_ARB);
        glClientActiveTextureARB(GL_TEXTURE0_ARB);
    }
#ifndef MMDFILES_DONTUSESPHEREMAP
    if (m_hasSingleSphereMap) {
        /* this model contains single sphere map texture */
        /* set texture coordinate generation for sphere map on texture unit 0 */
        glEnable(GL_TEXTURE_2D);
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
        glDisable(GL_TEXTURE_2D);
    }
    if (m_hasMultipleSphereMap) {
        /* this model contains additional sphere map texture */
        /* set texture coordinate generation for sphere map on texture unit 2 */
        glActiveTextureARB(GL_TEXTURE2_ARB);
        glEnable(GL_TEXTURE_2D);
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
        glDisable(GL_TEXTURE_2D);
        glActiveTextureARB(GL_TEXTURE0_ARB);
    }
#endif /* !MMDFILES_DONTUSESPHEREMAP */

    /* calculate alpha value, applying model global alpha */
    modelAlpha = m_globalAlpha;

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboBufElement);

    /* render per material */
    for (i = 0; i < m_numMaterial; i++) {
        m = &(m_material[m_materialRenderOrder[i]]);
        /* set colors */
        c[3] = m->getAlpha() * modelAlpha;
        if (c[3] > 0.99f) c[3] = 1.0f; /* clamp to 1.0 */
        if (m_toon) {
            /* use averaged color of diffuse and ambient for both */
            m->copyAvgcol(c);
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, &(c[0]));
            m->copySpecular(c);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(c[0]));
        } else {
            /* use each color */
            m->copyDiffuse(c);
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(c[0]));
            m->copyAmbient(c);
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(c[0]));
            m->copySpecular(c);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(c[0]));
        }
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->getShiness());

        /* disable face culling for transparent materials */
        if (m->getAlpha() < 1.0f)
            glDisable(GL_CULL_FACE);
        else
            glEnable(GL_CULL_FACE);

        /* if using multiple texture units, set current unit to 0 */
        if (m_toon || m_hasMultipleSphereMap)
            glActiveTextureARB(GL_TEXTURE0_ARB);

        if (m->getTexture()) {
            /* bind model texture */
            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, m->getTexture()->getID());
#ifndef MMDFILES_DONTUSESPHEREMAP
            if (m_hasSingleSphereMap) {
                if (m->getTexture()->isSphereMap()) {
                    /* this is sphere map */
                    /* enable texture coordinate generation */
                    if (m->getTexture()->isSphereMapAdd())
                        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
                    glEnable(GL_TEXTURE_GEN_S);
                    glEnable(GL_TEXTURE_GEN_T);
                } else {
                    /* disable generation */
                    glDisable(GL_TEXTURE_GEN_S);
                    glDisable(GL_TEXTURE_GEN_T);
                }
            }
#endif /* !MMDFILES_DONTUSESPHEREMAP */
        } else {
            glDisable(GL_TEXTURE_2D);
        }

        if (m_toon) {
            /* set toon texture for texture unit 1 */
            glActiveTextureARB(GL_TEXTURE1_ARB);
            glBindTexture(GL_TEXTURE_2D, m_toonTextureID[m->getToonID()]);
            /* set GL_CLAMP_TO_EDGE for toon texture to avoid texture interpolation at edge */
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        }

#ifndef MMDFILES_DONTUSESPHEREMAP
        if (m_hasMultipleSphereMap) {
            if (m->getAdditionalTexture()) {
                /* this material has additional sphere map texture, bind it at texture unit 2 */
                glActiveTextureARB(GL_TEXTURE2_ARB);
                glEnable(GL_TEXTURE_2D);
                if (m->getAdditionalTexture()->isSphereMapAdd())
                    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
                else
                    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                glBindTexture(GL_TEXTURE_2D, m->getAdditionalTexture()->getID());
                glEnable(GL_TEXTURE_GEN_S);
                glEnable(GL_TEXTURE_GEN_T);
            } else {
                /* disable generation */
                glActiveTextureARB(GL_TEXTURE2_ARB);
                glDisable(GL_TEXTURE_2D);
            }
        }
#endif /* !MMDFILES_DONTUSESPHEREMAP */

        /* draw elements */
        glDrawElements(GL_TRIANGLES, m->getNumSurface(), GL_UNSIGNED_SHORT, (const GLvoid *) (sizeof(unsigned short) * m->getSurfaceListIndex()));

        /* reset some parameters */
        if (m->getTexture() && m->getTexture()->isSphereMap() && m->getTexture()->isSphereMapAdd()) {
            if (m_toon)
                glActiveTextureARB(GL_TEXTURE0_ARB);
            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        }
    }

    glDisableClientState(GL_NORMAL_ARRAY);
    if (m_toon) {
        glClientActiveTextureARB(GL_TEXTURE0_ARB);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#ifndef MMDFILES_DONTUSESPHEREMAP
        if (m_hasSingleSphereMap) {
            glActiveTextureARB(GL_TEXTURE0_ARB);
            glDisable(GL_TEXTURE_GEN_S);
            glDisable(GL_TEXTURE_GEN_T);
        }
#endif /* !MMDFILES_DONTUSESPHEREMAP */
        glClientActiveTextureARB(GL_TEXTURE1_ARB);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#ifndef MMDFILES_DONTUSESPHEREMAP
        if (m_hasMultipleSphereMap) {
            glActiveTextureARB(GL_TEXTURE2_ARB);
            glDisable(GL_TEXTURE_GEN_S);
            glDisable(GL_TEXTURE_GEN_T);
        }
#endif /* !MMDFILES_DONTUSESPHEREMAP */
        glActiveTextureARB(GL_TEXTURE0_ARB);
    } else {
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#ifndef MMDFILES_DONTUSESPHEREMAP
        if (m_hasSingleSphereMap) {
            glDisable(GL_TEXTURE_GEN_S);
            glDisable(GL_TEXTURE_GEN_T);
        }
        if (m_hasMultipleSphereMap) {
            glActiveTextureARB(GL_TEXTURE2_ARB);
            glDisable(GL_TEXTURE_GEN_S);
            glDisable(GL_TEXTURE_GEN_T);
            glActiveTextureARB(GL_TEXTURE0_ARB);
        }
#endif /* !MMDFILES_DONTUSESPHEREMAP */
    }

#ifndef MMDFILES_DONTUSESPHEREMAP
    if (m_hasSingleSphereMap || m_hasMultipleSphereMap) {
        glDisable(GL_TEXTURE_GEN_S);
        glDisable(GL_TEXTURE_GEN_T);
    }
#endif /* !MMDFILES_DONTUSESPHEREMAP */
    if (m_toon) {
        glActiveTextureARB(GL_TEXTURE1_ARB);
        glDisable(GL_TEXTURE_2D);
    }
#ifndef MMDFILES_DONTUSESPHEREMAP
    if (m_hasMultipleSphereMap) {
        glActiveTextureARB(GL_TEXTURE2_ARB);
        glDisable(GL_TEXTURE_2D);
    }
#endif /* !MMDFILES_DONTUSESPHEREMAP */
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glClientActiveTextureARB(GL_TEXTURE0_ARB);

    glDisable(GL_TEXTURE_2D);
    glEnable(GL_CULL_FACE);
#ifndef MMDFILES_CONVERTCOORDINATESYSTEM
    glCullFace(GL_BACK);
    glPopMatrix();
#endif /* !MMDFILES_CONVERTCOORDINATESYSTEM */


    /* draw edge */
    drawEdge = true;
    if (m_forceEdge) {
        /* force edge drawing even if this model has no edge surface or no-toon mode */
        if (m_numSurfaceForEdge == 0) {
            numSurface = m_numSurface;
            surfaceOffset = 0;
        } else {
            numSurface = m_numSurfaceForEdge;
            surfaceOffset = m_vboOffsetSurfaceForEdge;
        }
    } else {
        /* draw edge when toon mode, skip when this model has no edge surface */
        if (!m_toon)
            drawEdge = false;
        if (m_numSurfaceForEdge == 0)
            drawEdge = false;
        numSurface = m_numSurfaceForEdge;
        surfaceOffset = m_vboOffsetSurfaceForEdge;
    }

    if (drawEdge) {

#ifndef MMDFILES_CONVERTCOORDINATESYSTEM
        glPushMatrix();
        glScalef(1.0f, 1.0f, -1.0f);
        glCullFace(GL_BACK);
#else
        /* draw back surface only */
        glCullFace(GL_FRONT);
#endif /* !MMDFILES_CONVERTCOORDINATESYSTEM */

        glDisable(GL_LIGHTING);
        glColor4f(m_edgeColor[0], m_edgeColor[1], m_edgeColor[2], m_edgeColor[3] * modelAlpha);
        glVertexPointer(3, GL_FLOAT, sizeof(btVector3), (const GLvoid *) m_vboOffsetEdge);
        glDrawElements(GL_TRIANGLES, numSurface, GL_UNSIGNED_SHORT, (const GLvoid *) surfaceOffset);
        glEnable(GL_LIGHTING);

        /* draw front again */
#ifndef MMDFILES_CONVERTCOORDINATESYSTEM
        glPopMatrix();
        glCullFace(GL_FRONT);
#else
        glCullFace(GL_BACK);
#endif /* !MMDFILES_CONVERTCOORDINATESYSTEM */
    }

    glDisableClientState(GL_VERTEX_ARRAY);

    /* unbind buffer */
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}