⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imviewer.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "ImViewer.h"
#include "WmlImages.h"
using namespace Wml;

ImViewer g_kTheApp;

//----------------------------------------------------------------------------
ImViewer::ImViewer ()
    :
    Application2("ImViewer",0,0,256,256,ColorRGB(1.0f,1.0f,1.0f))
{
    m_bMouseDown = false;
    m_iZ = 0;
    m_aiBound = NULL;
    m_akData = NULL;
    m_afData = NULL;
    m_iSliceQuantity = 0;
}
//----------------------------------------------------------------------------
ImViewer::~ImViewer ()
{
}
//----------------------------------------------------------------------------
bool ImViewer::OnPrecreate ()
{
    if ( !Application2::OnPrecreate() )
        return false;

    // get the name of the image file to open and display
    if ( !GetCommand() )
    {
        // command line must be specified
        return false;
    }
    char* acFilename = NULL;
    GetCommand()->Filename(acFilename);
    if ( !acFilename )
    {
        // input filename must be specified on the command line
        return false;
    }

    // load the image data
    int iRTTI, iSizeOf;
    char* acData = NULL;
    bool bLoaded = Lattice::LoadRaw(acFilename,m_iDimensions,m_aiBound,
        m_iQuantity,iRTTI,iSizeOf,acData);
    delete[] acFilename;
    if ( !bLoaded )
    {
        delete[] acData;
        return false;
    }

    // Set window size based on image size.  Adjust height to allow for
    // status bar.  The window width is chosen so that rows are multiples
    // of 4 bytes.
    ms_iHeight = m_aiBound[1];
    if ( ms_iHeight < 128 )
        ms_iHeight = 128;

    int iStatusHeight = 20;
    ms_iHeight += iStatusHeight;

    ms_iWidth = m_aiBound[0];
    if ( ms_iWidth < 256 )
        ms_iWidth = 256;

    int iRem = (ms_iWidth % 4);
    if ( iRem > 0 )
        ms_iWidth += 4-iRem;

    // The application image is stored differently depending on the input
    // image format.
    int i;
    if ( iRTTI == Ergb5::GetRTTI() )
    {
        m_akData = new Color[m_iQuantity];
        unsigned short* ausData = (unsigned short*)acData;
        for (i = 0; i < m_iQuantity; i++)
        {
            unsigned char ucR = GetRed16(ausData[i]);
            unsigned char ucG = GetGreen16(ausData[i]);
            unsigned char ucB = GetBlue16(ausData[i]);
            m_akData[i] = Color(ucR,ucG,ucB);
        }
    }
    else if ( iRTTI == Ergb8::GetRTTI() )
    {
        m_akData = new Color[m_iQuantity];
        unsigned int* auiData = (unsigned int*)acData;
        for (i = 0; i < m_iQuantity; i++)
        {
            unsigned char ucR = GetRed24(auiData[i]);
            unsigned char ucG = GetGreen24(auiData[i]);
            unsigned char ucB = GetBlue24(auiData[i]);
            m_akData[i] = Color(ucR,ucG,ucB);
        }
    }
    else if ( iRTTI == Efloat::GetRTTI() )
    {
        m_afData = new float[m_iQuantity];
        memcpy(m_afData,acData,m_iQuantity*sizeof(float));
    }
    else
    {
        m_afData = new float[m_iQuantity];
        ImageConvert(m_iQuantity,iRTTI,acData,Efloat::GetRTTI(),m_afData);
    }
    delete[] acData;

    // compute min, max and range of float images
    if ( m_afData )
    {
        m_fMin = m_afData[0];
        m_fMax = m_fMin;
        for (i = 1; i < m_iQuantity; i++)
        {
            if ( m_afData[i] < m_fMin )
                m_fMin = m_afData[i];
            else if ( m_afData[i] > m_fMax )
                m_fMax = m_afData[i];
        }
        m_fRange = m_fMax - m_fMin;
        if ( m_fRange > 0.0f )
            m_fInvRange = 1.0f/m_fRange;
        else
            m_fInvRange = 0.0f;
    }

    // we only need memory to hold the active slice
    m_iSliceQuantity = m_aiBound[0]*m_aiBound[1];

    return true;
}
//----------------------------------------------------------------------------
bool ImViewer::OnInitialize ()
{
    if ( !Application2::OnInitialize() )
        return false;

    CopySliceToScreen();
    OnDisplay();
    return true;
}
//----------------------------------------------------------------------------
void ImViewer::OnTerminate ()
{
    delete[] m_akData;
    delete[] m_afData;
    delete[] m_aiBound;
    Application2::OnTerminate();
}
//----------------------------------------------------------------------------
void ImViewer::OnKeyDown (unsigned char ucKey, int, int)
{
    if ( ucKey == 'q' || ucKey == 'Q' || ucKey == KEY_ESCAPE )
    {
        RequestTermination();
        return;
    }
}
//----------------------------------------------------------------------------
void ImViewer::OnSpecialKeyDown (int iKey, int iX, int iY)
{
    if ( m_iDimensions != 3 )
        return;

    if ( iKey == KEY_UP_ARROW )
    {
        // up-arrow pressed, go to next image slize
        if ( m_iZ < m_aiBound[2] - 1 )
        {
            m_iZ++;
            CopySliceToScreen();
            if ( m_bMouseDown )
                ReadPixelValue(iX,iY);
            OnDisplay();
        }
    }
    else if ( iKey == KEY_DOWN_ARROW )
    {
        // down-arrow pressed, go to previous image slice
        if ( m_iZ > 0 )
        {
            m_iZ--;
            CopySliceToScreen();
            if ( m_bMouseDown )
                ReadPixelValue(iX,iY);
            OnDisplay();
        }
    }
}
//----------------------------------------------------------------------------
void ImViewer::OnMouseClick (int iButton, int iState, int iX, int iY,
    unsigned int)
{
    if ( iButton == MOUSE_LEFT_BUTTON )
    {
        if ( iState == MOUSE_DOWN )
        {
            m_bMouseDown = true;
            ReadPixelValue(iX,iY);
            OnDisplay();
        }
        else if ( iState == MOUSE_UP )
        {
            m_bMouseDown = false;
            ReadPixelValue(-1,-1);
            OnDisplay();
        }
    }
}
//----------------------------------------------------------------------------
void ImViewer::OnMotion (int iX, int iY, unsigned int uiModifiers)
{
    if ( m_bMouseDown )
    {
        ReadPixelValue(iX,iY);
        OnDisplay();
    }
}
//----------------------------------------------------------------------------
void ImViewer::CopySliceToScreen ()
{
    ClearScreen();

    int iX, iY;

    if ( m_afData )
    {
        if ( m_fRange > 0.0f )
        {
            float* afSlice = &m_afData[m_iZ*m_iSliceQuantity];
            for (iY = 0; iY < m_aiBound[1]; iY++)
            {
                for (iX = 0; iX < m_aiBound[0]; iX++)
                {
                    int i = iX+m_aiBound[0]*iY;
                    float fGray = 255.0f*(afSlice[i]-m_fMin)*m_fInvRange;
                    unsigned char ucGray = (unsigned char)(fGray);
                    m_akScreen[Index(iX,iY)] = Color(ucGray,ucGray,ucGray);
                }
            }
        }
    }
    else
    {
        Color* akSlice = &m_akData[m_iZ*m_iSliceQuantity];
        for (iY = 0; iY < m_aiBound[1]; iY++)
        {
            for (iX = 0; iX < m_aiBound[0]; iX++)
            {
                int i = iX+m_aiBound[0]*iY;
                m_akScreen[Index(iX,iY)] = akSlice[i];
            }
        }
    }
}
//----------------------------------------------------------------------------
void ImViewer::ReadPixelValue (int iX, int iY)
{
    if ( 0 <= iX && iX < m_aiBound[0] && 0 <= iY && iY < m_aiBound[1] )
    {
        int iIndex = iX + m_aiBound[0]*iY;
        if ( m_afData )
        {
            float* afSlice = &m_afData[m_iZ*m_iSliceQuantity];
            float fValue = afSlice[iIndex];
            if ( m_iDimensions == 2 )
                sprintf(m_acPixelStr,"(%d,%d) %f",iX,iY,fValue);
            else
                sprintf(m_acPixelStr,"(%d,%d,%d) %f",iX,iY,m_iZ,fValue);
        }
        else
        {
            Color* akSlice = &m_akData[m_iZ*m_iSliceQuantity];
            Color kValue = akSlice[iIndex];
            if ( m_iDimensions == 2 )
            {
                sprintf(m_acPixelStr,"(%d,%d) r=%d g=%d b=%d",iX,iY,
                    (int)kValue.r,(int)kValue.g,(int)kValue.b);
            }
            else
            {
                sprintf(m_acPixelStr,"(%d,%d,%d) r=%d g=%d b=%d",iX,iY,m_iZ,
                    (int)kValue.r,(int)kValue.g,(int)kValue.b);
            }
        }
    }
    else
    {
        int iLength = (int)strlen(m_acPixelStr);
        memset(m_acPixelStr,' ',iLength);
    }
}
//----------------------------------------------------------------------------
void ImViewer::ScreenOverlay ()
{
    if ( m_bMouseDown )
    {
        ms_spkRenderer->Draw(4,ms_iHeight-4,ColorRGB(0.0f,0.0f,0.0f),
            m_acPixelStr);
    }
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -