ImmediateModeRenderer/ImmediateModeRenderer.cpp


//**************************************************************************/

// Copyright (c) 2008 Autodesk, Inc.

// All rights reserved.

//

// Use of this software is subject to the terms of the Autodesk license

// agreement provided at the time of installation or download, or which

// otherwise accompanies this software in either electronic or hard copy form.

//

//**************************************************************************/

// DESCRIPTION:

// CREATED: April 2010

//**************************************************************************/

#include "ImmediateModeRenderer.h"

#include "math.h"

#if defined(WIN32) || defined(WIN64)
#include <omp.h>
#endif

#if defined(JAMBUILD)
#include <Mudbox/mudbox.h>
#include <Mudbox/MudBoxGL.h>
#else
#include "../../include/Mudbox/mudbox.h"
#include "../../include/Mudbox/MudBoxGL.h"
#endif

MB_PLUGIN( "ImmediateModeRenderer", "Immediate Mode Renderer", "Autodesk", "http://www.mudbox3d.com", 0 );

IMPLEMENT_CLASS( ImmediateModeRenderer, MeshRenderer, "Immediate Mode Renderer" );

ImmediateModeRenderer::ImmediateModeRenderer( void ) :
    m_pMesh(NULL),
    m_fPointSize(2.0f),
    m_fLineWidth(2.0f),
    m_ePolygonMode(GL_FILL),
    m_bTCMode(FALSE),
    m_iRedBits(0),
    m_iGreenBits(0),
    m_iBlueBits(0)
{
}

ImmediateModeRenderer::~ImmediateModeRenderer( void )
{
}

void ImmediateModeRenderer::Serialize( Stream &s )
{
    MeshRenderer::Serialize( s );
}

void ImmediateModeRenderer::SetTextureCoordinateMode( bool bMode ) 
{
    m_bTCMode = bMode;
}

void ImmediateModeRenderer::SetMesh( Mesh *pMesh )
{
    m_pMesh = pMesh;
    OnMeshChange();
}

void ImmediateModeRenderer::Render( const Selector *pSelector, bool bSkipMaterial, const Camera *pCamera, const AxisAlignedBoundingBox &bUV )
{
    if (!m_pMesh)
        return;

    if (!bSkipMaterial && m_pMesh->Geometry()->Material())
    {
        m_pMesh->Geometry()->Material()->Activate(m_pMesh, AxisAlignedBoundingBox(), Color::white );
    }

    glEnable(GL_NORMALIZE);

    glPolygonMode(GL_FRONT, m_ePolygonMode);

    if (m_pMesh->Type() == Mesh::typeTriangular)
    {
        glBegin(GL_TRIANGLES);
        for (int ii=0; ii<m_pMesh->FaceCount(); ii++)
        {
            renderTriangle(ii);
        }
        glEnd();
    }
    else if (m_pMesh->Type() == Mesh::typeQuadric)
    {
        glBegin(GL_QUADS);
        for (int ii=0; ii<m_pMesh->FaceCount(); ii++)
        {
            renderQuad(ii);
        }
        glEnd();
    }

    if (!bSkipMaterial && m_pMesh->Geometry()->Material())
    {
        m_pMesh->Geometry()->Material()->Deactivate();
    }
}
unsigned int encode(unsigned int faceIndex, unsigned int vertexIndex)
{
    unsigned int value = faceIndex;

    value = value << 2;

    value = value | vertexIndex;

    return value;
}

void decode(unsigned int value, unsigned int &faceIndex, unsigned int &vertexIndex)
{
    vertexIndex = 3 & value;



    faceIndex = 0xfffffffc & value;

    faceIndex = faceIndex >> 2;
}

unsigned int ImmediateModeRenderer::RenderData(const Selector *pSelector, unsigned int iStart, const Camera *pCamera)
{
    glDisable(GL_BLEND);
    glDisable(GL_DITHER);
    glDisable(GL_FOG);
    glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_1D);
    glDisable (GL_TEXTURE_2D); 
    glShadeModel( GL_FLAT );

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    unsigned int iColorCount = 0;
    char r,g,b,a;

    if (m_pMesh->Type() == Mesh::typeTriangular)
    {
        glBegin(GL_TRIANGLES);
        for (unsigned long ii=0; ii<m_pMesh->FaceCount(); ii++)
        {
            iColorCount = encode(ii, 0);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->TriangleVertexPosition(ii, 0));

            iColorCount = encode(ii, 1);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->TriangleVertexPosition(ii, 1));

            iColorCount = encode(ii, 2);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];         
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->TriangleVertexPosition(ii, 2));
        }
        glEnd();
    }
    else if (m_pMesh->Type() == Mesh::typeQuadric)
    {
        glBegin(GL_QUADS);
        for (unsigned long ii=0; ii<m_pMesh->FaceCount(); ii++)
        {
            iColorCount = encode(ii, 0);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->QuadVertexPosition(ii, 0));

            iColorCount = encode(ii, 1);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->QuadVertexPosition(ii, 1));

            iColorCount = encode(ii, 2);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->QuadVertexPosition(ii, 2));

            iColorCount = encode(ii, 3);
            r = ((char *) &iColorCount)[0]; g = ((char *) &iColorCount)[1]; b = ((char *) &iColorCount)[2]; a = ((char *) &iColorCount)[3];
            glColor4f((float) r / 256.0f, (float) g / 256.0f, (float) b / 256.0f, (float) a / 256.0f);
            glVertex3fv(m_pMesh->QuadVertexPosition(ii, 3));
        }
        glEnd();
    }

    glShadeModel( GL_SMOOTH );

    return iColorCount;
}

void ImmediateModeRenderer::renderTriangle(int index)
{
    glVertex3fv(m_pMesh->TriangleVertexPosition(index, 0));
    glNormal3fv(m_pMesh->TriangleVertexNormal(index,0));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->TriangleVertexTC(index,0).u, m_pMesh->TriangleVertexTC(index,0).v);

    glVertex3fv(m_pMesh->TriangleVertexPosition(index, 1));
    glNormal3fv(m_pMesh->TriangleVertexNormal(index,1));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->TriangleVertexTC(index,1).u, m_pMesh->TriangleVertexTC(index,1).v);
    
    glVertex3fv(m_pMesh->TriangleVertexPosition(index, 2));
    glNormal3fv(m_pMesh->TriangleVertexNormal(index,2));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->TriangleVertexTC(index,2).u, m_pMesh->TriangleVertexTC(index,2).v);
}

void ImmediateModeRenderer::renderQuad(int index)
{
    glVertex3fv(m_pMesh->QuadVertexPosition(index, 0));
    glNormal3fv(m_pMesh->QuadVertexNormal(index, 0));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->QuadVertexTC(index,0).u, m_pMesh->QuadVertexTC(index,0).v);

    glVertex3fv(m_pMesh->QuadVertexPosition(index, 1));
    glNormal3fv(m_pMesh->QuadVertexNormal(index, 1));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->QuadVertexTC(index,1).u, m_pMesh->QuadVertexTC(index,1).v);

    glVertex3fv(m_pMesh->QuadVertexPosition(index, 2));
    glNormal3fv(m_pMesh->QuadVertexNormal(index, 2));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->QuadVertexTC(index,2).u, m_pMesh->QuadVertexTC(index,2).v);

    glVertex3fv(m_pMesh->QuadVertexPosition(index, 3));
    glNormal3fv(m_pMesh->QuadVertexNormal(index, 3));
    if (m_bTCMode)
        glTexCoord2f(m_pMesh->QuadVertexTC(index,3).u, m_pMesh->QuadVertexTC(index,3).v);
}

void ImmediateModeRenderer::OnVertexPositionChange( unsigned int iVertexIndex, unsigned int iFaceIndex )
{
}

void ImmediateModeRenderer::OnVertexStateChange( unsigned int iVertexIndex, unsigned int iFaceIndex )
{
}

void ImmediateModeRenderer::OnMeshChange( void )
{
}

void ImmediateModeRenderer::DecodeData( unsigned int iData, unsigned int &iFaceIndex, unsigned int &iVertexIndex )
{
    unsigned int iFaceVertex = 0;
    decode(iData, iFaceIndex, iFaceVertex);

    if (m_pMesh->Type() == Mesh::typeTriangular)
    {
        iVertexIndex = m_pMesh->TriangleIndex(iFaceIndex, iFaceVertex);
    }
    else if (m_pMesh->Type() == Mesh::typeQuadric)
    {
        iVertexIndex = m_pMesh->QuadIndex(iFaceIndex, iFaceVertex);
    }
}

void ImmediateModeRenderer::SetLODLevel(float fLevel)
{
}

float ImmediateModeRenderer::LODLevel() const
{
    return 0;
}

const AxisAlignedBoundingBox &ImmediateModeRenderer::ActiveUVArea() const
{
    return m_ActiveUVArea;
}

void ImmediateModeRenderer::SetWireFrameMode(bool bMode)
{
}

bool ImmediateModeRenderer::WireFrameMode() const
{
    return false;
}

void ImmediateModeRenderer::SetColorMode(bool bMode)
{
}

bool ImmediateModeRenderer::ColorMode() const
{
    return false;
}

void ImmediateModeRenderer::SetWireLevel(unsigned int)
{
}

unsigned int ImmediateModeRenderer::WireLevel() const
{
    return 0;
}

bool ImmediateModeRenderer::TextureCoordinateMode() const
{
    return false;
}

void ImmediateModeRenderer::SetTangentMode(bool bMode)
{
}

bool ImmediateModeRenderer::TangentMode() const
{
    return false;
}

void ImmediateModeRenderer::SetFacetedMode(bool)
{
}

bool ImmediateModeRenderer::FacetedMode() const
{
    return false;
}

void ImmediateModeRenderer::OnNodeEvent(const Attribute &, NodeEventType)
{
}

void ImmediateModeRenderer::Initialize()
{
}