terraintexture.cpp

来自「x3d_new.rar」· C++ 代码 · 共 163 行

CPP
163
字号
#include "StdAfx.h"
#include "TerrainTexture.h"
#include "xUtil.h"

#include <d3dx9tex.h>

CFieldTexturePainter::CFieldTexturePainter(void)
    : m_pField(NULL)
    , m_pDevice(NULL)
    , m_nSize(0)
{
}

CFieldTexturePainter::~CFieldTexturePainter(void)
{
    ClearElement();
}

bool CFieldTexturePainter::AddElement(char* sFileName, int nPercentage)
{
    assert(m_nSize > 0);

    STextureElementInfo tei;
    if(FAILED(D3DXCreateTextureFromFileEx(m_pDevice, sFileName, m_nSize, m_nSize, 
        0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &tei.m_pTexture)))
    {
        return false;
    }

    tei.m_sFileName   = sFileName;
    tei.m_nPercentage = nPercentage;
    m_TextureElements.push_back(tei);   // 添加

    m_nTotalPercentage += nPercentage;
    return true;
}

bool CFieldTexturePainter::PaintTexture(LPDIRECT3DTEXTURE9* ppTexture)
{
    assert(m_TextureElements.size());

    // 只加载了1张纹理的情况就直接设置
    if(m_TextureElements.size() == 1)
    {
        if(FAILED(D3DXCreateTextureFromFileEx(m_pDevice, m_TextureElements[0].m_sFileName.c_str(), m_nSize, m_nSize, 
            0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppTexture)))
            return false;
        else
            return true;
    }

    assert(m_pField);

    // 1.设置纹理元素数据
    int nPercentage = 0;

    for(unsigned int i = 0; i < m_TextureElements.size(); ++i)
    {
        STextureElementInfo& tei = m_TextureElements[i];
        assert(tei.m_pTexture);

        // 计算起始高度
        nPercentage += tei.m_nPercentage;
        tei.m_nEndHeight = (int)(m_pField->GetMaxHeight() * ((float)nPercentage / m_nTotalPercentage));
     
        // 锁定纹理
        LPDIRECT3DSURFACE9 pElementSurface;

        if(FAILED(tei.m_pTexture->GetSurfaceLevel(0, &pElementSurface)))
            return false;

        if(FAILED(pElementSurface->LockRect(&tei.m_d3dlr, NULL, 0)))
            return false;

        pElementSurface->Release();
    }

    // 2.开始生成纹理数据
    D3DLOCKED_RECT d3dlr;
    LPDIRECT3DSURFACE9 pMainSurface;

    if(FAILED((*ppTexture)->GetSurfaceLevel(0, &pMainSurface)))
        return false;

    if(FAILED(pMainSurface->LockRect(&d3dlr, NULL, 0)))
        return false;

    for(int iy = 0; iy < m_nSize; ++iy)
    {
        for(int ix = 0; ix < m_nSize; ++ix)
        {
			int iDataPos = ix * sizeof(DWORD) + iy * d3dlr.Pitch;
			LPBYTE pbyData = (LPBYTE)d3dlr.pBits + iDataPos;
            memset(pbyData, 0, sizeof(DWORD));

            for(unsigned int iIndex = 1; iIndex < m_TextureElements.size(); ++iIndex)
            {
				int nmx = int((float)ix / m_nSize * m_pField->GetBorderSize());
				int nmy = int((float)iy / m_nSize * m_pField->GetBorderSize());
                unsigned char byHeight = m_pField->GetHeight(nmx, nmy);

                STextureElementInfo& teiBegin = m_TextureElements[iIndex - 1];
                STextureElementInfo& teiEnd = m_TextureElements[iIndex];

                if(teiEnd.m_nEndHeight >= byHeight)
                {
                    int nRange = teiEnd.m_nEndHeight - teiBegin.m_nEndHeight;

                    // 所占比率
                    float fRate1 = min((teiEnd.m_nEndHeight - byHeight) / (float)nRange, 1.0f);
                    float fRate2 = 1.0f - fRate1;
                    
                    // 合成
                    LPBYTE pbyElementData1 =
                        (LPBYTE)teiBegin.m_d3dlr.pBits + iDataPos;
                    LPBYTE pbyElementData2 = (LPBYTE)teiEnd.m_d3dlr.pBits + iDataPos;
                    
                    for(int i = 0; i < sizeof(DWORD); ++i)
                        pbyData[i] = min(int(pbyElementData1[i] * fRate1 + pbyElementData2[i] * fRate2), 255);

                    break;
                }
            }
        }
    }

    // 3.解锁所有纹理
    
    pMainSurface->UnlockRect();
    pMainSurface->Release();

    for(unsigned int i = 0; i < m_TextureElements.size(); ++i)
    {
        STextureElementInfo& tei = m_TextureElements[i];
        LPDIRECT3DSURFACE9 pElementSurface;

        if(FAILED(tei.m_pTexture->GetSurfaceLevel(0, &pElementSurface)))
            continue;

        pElementSurface->UnlockRect();
        pElementSurface->Release();
    }

    return true;
}

void CFieldTexturePainter::ClearElement(void)
{
    // 释放所有纹理元素
    for(unsigned int i = 0; i < m_TextureElements.size(); ++i)
    {
        STextureElementInfo& tei = m_TextureElements[i];        
        assert(tei.m_pTexture);

        tei.m_pTexture->Release();
    }

    // 清空列表
    m_TextureElements.clear();

    // 这个应该清零
    m_nTotalPercentage = 0;
}

⌨️ 快捷键说明

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