//----------------------------------------------------------------------- void gkSceneNode::attachObject( gkMovableObject* obj ) { assert(obj); if(!obj) { gkLogWarning(_T("Object ref NULL!")); return; } if (obj->isAttached()) { gkLogWarning(_T("Object already attached to a SceneNode or a Bone")); } obj->_notifyAttached(this); // Also add to name index std::pair<ObjectMap::iterator, bool> insresult = m_mapObjectsByName.insert(ObjectMap::value_type(obj->getName(), obj)); //assert(insresult.second && "Object was not attached because an object of the " // "same name was already attached to this node."); // Make sure bounds get updated (must go right to the top) needUpdate(); }
//----------------------------------------------------------------------- gkMovableObject* gkSceneNode::detachObject( BYTE index ) { gkMovableObject* ret; if (index < m_mapObjectsByName.size()) { ObjectMap::iterator i = m_mapObjectsByName.begin(); // Increment (must do this one at a time) while (index--)++i; ret = i->second; m_mapObjectsByName.erase(i); //ret->_notifyAttached((SceneNode*)0); // Make sure bounds get updated (must go right to the top) needUpdate(); return ret; } else { gkLogWarning(_T("Object index out of bounds. Couldn't find.")); return NULL; } }
bool Image::loadUncompressedTGA( TexImage* texture, FILE* file ) { //ASSERT( file != NULL && texture!=NULL ); uint32 bytePerPixel = texture->bpp/8; uint32 imgSize = texture->width*texture->height*bytePerPixel; //图像总字节数 texture->imageData = new uint8[ imgSize ]; if ( fread( texture->imageData, 1, imgSize, file ) != imgSize ) { gkLogWarning("Read texture imagedata failed!\n"); return FALSE; } //TGA采用了逆OpenGL的格式,要将BGR转换成为RGB // Go through all of the pixels and swap the B and R values since TGA // files are stored as BGR instead of RGB (or use GL_BGR_EXT verses GL_RGB) for( int i = 0; i < (int)imgSize; i+=bytePerPixel ){ /*GLushort temp = texture->imageData[i]; texture->imageData[i] = texture->imageData[i+2]; texture->imageData[i+2] = temp;*/ texture->imageData[i] ^= texture->imageData[i+2] ^= texture->imageData[i] ^= texture->imageData[ i+2 ]; //位操作提高速度,更换B,R分量 } ::fclose( file ); return TRUE; }
//----------------------------------------------------------------------- gkMovableObjectFactory* gk3DEngine::getMovableObjectFactory( gkStdString typeName ) { MovableObjectFactoryMap::iterator i = m_mapMovableObjectFactoryMap.find(typeName); if (i == m_mapMovableObjectFactoryMap.end()) { gkLogWarning( _T("没有找到对应的工厂@gkRoot::getMovableObjectFactory") ); } return i->second; }
//----------------------------------------------------------------------- gkMovableObject* gkSceneNode::getAttachedObject( const gkStdString& name ) { // Look up ObjectMap::iterator i = m_mapObjectsByName.find(name); if (i == m_mapObjectsByName.end()) { gkLogWarning(_T("Some Object in name not find.")); } return i->second; }
bool gkGameFramework::InitGame(const TCHAR* dllname) { gkLogMessage(_T("load Game...")); // ensure destroyed DestroyGameImmediate(); #ifndef _STATIC_LIB // check the dll name TCHAR name[MAX_PATH]; gkIniParser startupFile( _T("config/startup.cfg") ); startupFile.Parse(); gkStdString ret = startupFile.FetchValue( _T("launcher"), _T("gamedll") ); if(ret != _T("")) { _tcscpy(name, ret.c_str()); } else { _tcscpy(name, _T("TestCases")); } gkLogMessage(_T("load Game: %s"), name); gkStdString dllPath = gEnv->rootPath; dllPath += "\\bin64\\"; // create system.dll first gkOpenModule( m_hHandleGame, name, dllPath.c_str()); if (m_hHandleGame) { m_pFuncGameStart = (GET_GAMEDLL)DLL_GETSYM(m_hHandleGame, "gkModuleInitialize"); m_pFuncGameEnd = (DESTROY_GAMEDLL)DLL_GETSYM(m_hHandleGame, "gkModuleUnload"); m_pGame = m_pFuncGameStart(gEnv); m_pGame->OnInit(); } else { gkLogWarning(_T("gkFramework::Load GameDll %s failed."), name ); } #else m_pGame = gkLoadStaticModule_gkGame(gEnv); m_pGame->OnInit(); #endif return true; }
//--------------------------------------------------------------------- void gk3DEngine::addMovableObjectFactory(gkMovableObjectFactory* fact, bool overrideExisting) { MovableObjectFactoryMap::iterator facti = m_mapMovableObjectFactoryMap.find( fact->getType()); if (!overrideExisting && facti != m_mapMovableObjectFactoryMap.end()) { gkLogWarning( _T("一个移动物件工厂已经存在。Root::addMovableObjectFactory") ); } // Save m_mapMovableObjectFactoryMap[fact->getType()] = fact; // Success! }
//----------------------------------------------------------------------- gkMovableObject* gkSceneNode::getAttachedObject( BYTE index ) { if (index < m_mapObjectsByName.size()) { ObjectMap::iterator i = m_mapObjectsByName.begin(); // Increment (must do this one at a time) while (index--)++i; return i->second; } else { gkLogWarning(_T("Some Object in index not find.")); return NULL; } }
bool Image::loadTGA( TexImage* texture, LPCSTR filename ) { if ( filename == NULL ) return FALSE; Header uTGAcompare = { 0,0,2,0,0,0,0,0}; //2为非压缩RGB格式 3 - 未压缩的,黑白图像 Header cTGAcompare = { 0,0,10,0,0,0,0,0}; //10为压缩RGB格式 TGAHeader header; FILE* file = fopen( filename, "rb" ); if ( !file ){ gkLogWarning("Openf file %s failed!\n", filename ); return FALSE; } if ( fread( &header, 1, sizeof(TGAHeader), file ) != sizeof( TGAHeader ) ){ //读取TGA整个头结构体 if ( file ) fclose( file ); gkLogWarning("Read data failed\n"); return FALSE; } texture->width = header.width; texture->height = header.height; texture->bpp = header.bpp; if ( header.bpp == 32 ) texture->imageType = GL_RGBA; else if ( header.bpp = 24 ) texture->imageType = GL_RGB; else{ gkLogWarning("Image type error!\n"); return FALSE; } if ( memcmp( &uTGAcompare, &header.head, sizeof(header.head) )== 0 ){ //未压缩TGA texture->bCompressed = FALSE; if ( !loadUncompressedTGA( texture, file ) ){ gkLogWarning("Load uncompressed TGA failed!\n"); return FALSE; } }else if ( memcmp( &cTGAcompare, &header.head ,sizeof(header.head) ) == 0 ){ //压缩TGA texture->bCompressed = TRUE; if ( !loadCompressedTGA( texture, file ) ){ gkLogWarning("Load compressed TGA failed!\n"); return FALSE; } }else{ gkLogWarning("Error TGA type!\n"); return FALSE; } return TRUE; }
IGameObject* gkGameObjectSystem::CreateStaticGeoGameObject( const gkStdString& name, const gkStdString& meshfile, Vec3& pos, Quat& rot ) { gkGameObject* pGameObject = NULL; pGameObject = _createGameObjectInternal(name); IGameObjectRenderLayer* pRenderLayer = gEnv->p3DEngine->createRenderLayer(name, pos, rot); if (!pRenderLayer) { GK_ASSERT(0); return NULL; } pGameObject->setGameObjectLayer(pRenderLayer); gkMeshPtr pMesh = gEnv->pSystem->getMeshMngPtr()->load(meshfile); if (pMesh.isNull()) { gkLogWarning(_T("gkGOSys::StaticGeo [ %s ] load mesh [ %s ], use default."), pGameObject->getName().c_str(), meshfile.c_str()); pMesh = gEnv->pSystem->getMeshMngPtr()->load(_T("engine/assets/meshs/_default.obj")); } for ( uint32 i=0; i < pMesh->getSubsetCount(); ++i ) { gkRenderable* pStatObj = gEnv->p3DEngine->createRenderable(pMesh, e3RT_StaticObj, i); pRenderLayer->modifySubRenderable(pStatObj, i); } pGameObject->setGameObjectSuperClass(eGOClass_STATICMESH); pGameObject->setGameObjectClass(_T("StaticGeo")); gkLogMessage(_T("gkGOSys::StaticGeo [ %s ] Created. %d SubSection."), pGameObject->getName().c_str(), pMesh->getSubsetCount()); return pGameObject; }
virtual void Complete_MT() { // loader.LoadPVR_Bind( m_hw_texptr, 0 ); // gEnv->pFileSystem->closeResFile( pTextureFile ); glActiveTexture(GL_TEXTURE0); glGenTextures(1, m_hw_texptr); glBindTexture(GL_TEXTURE_2D, *m_hw_texptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, iMipCount); uint32 RowBytes, NumRows; for( int i = 0; i < iMipCount; i++ ) { GetSurfaceInfo( iWidth, iHeight, fmt, NULL, &RowBytes, &NumRows ); { //BYTE* pDestBits = ( BYTE* )LockedRect.pBits; if (IsCompressedTex(fmt)) { glCompressedTexImage2D( GL_TEXTURE_2D, i, fmt, iWidth, iHeight, 0, RowBytes * NumRows, pSrcBits); GLenum error = glGetError(); if (error) { gkLogWarning(_T("bind compress texture error.")); } } else { //uint8* white = new uint8[iWidth * iHeight * 4]; //memset(white, 0xff, iWidth * iHeight * 4); glTexImage2D( GL_TEXTURE_2D, i, fmt, iWidth, iHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, pSrcBits ); //delete white; GLenum error = glGetError(); if (error) { gkLogWarning(_T("bind texture error.")); } } //glPixelStorei(GL_UNPACK_ALIGNMENT, 4); pSrcBits += (RowBytes * NumRows); } GLenum error = glGetError(); if (error) { gkLogWarning(_T("bind texture error.")); } iWidth = iWidth >> 1; iHeight = iHeight >> 1; if( iWidth == 0 ) iWidth = 1; if( iHeight == 0 ) iHeight = 1; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); gEnv->pFileSystem->closeResFile( pFile ); }
bool gkShader::CompileShader( gkStdString &binaryPath, gkStdString &sourcePath, IResFile* &pFile, const TCHAR* profile ) { gkStdString absbinaryPath = gkGetExecRootDir() + binaryPath; // 只要决定了编译,就先删除cache DeleteFile( absbinaryPath.c_str() ); // not exist compile gkLogWarning( _T("gkShader::Shader[%s] binary not exist. "), m_wstrFileName.c_str() ); TCHAR buffer[1024]; if(profile) { _stprintf(buffer, _T("%sbin32\\fxc.exe /Zpc /T fx_2_0 %s /Fo %s %s"), gkGetExecRootDir().c_str(), profile, absbinaryPath.c_str(), sourcePath.c_str()); } else { _stprintf(buffer, _T("%sbin32\\fxc.exe /Zpc /T fx_2_0 /Fo %s %s"), gkGetExecRootDir().c_str(), absbinaryPath.c_str(), sourcePath.c_str()); } char bufferA[1024]; #ifdef UNICODE WideCharToMultiByte(CP_ACP, NULL, buffer, -1, bufferA, 1024, NULL, NULL ); #else _tcscpy( bufferA, buffer ); #endif system(bufferA); pFile = gEnv->pFileSystem->loadResFile( binaryPath.c_str(), true ); if (!pFile) { // 编译错误,使用默认的报错shader gkLogError( _T("gkShader::Shader[%s] compile failed. Use Default."), m_wstrFileName.c_str() ); pFile = gEnv->pFileSystem->loadResFile( _T("Engine/Shaders/d3d9/ksCompileFailed.sto"), true ); if (!pFile) { // 编译一下默认shader gkStdString absbinaryPath = gkGetExecRootDir() + _T("Engine/Shaders/d3d9/ksCompileFailed.sto"); gkStdString sourcePath = gkGetExecRootDir() + _T("Engine/Shaders/d3d9/hwcode/kscompilefailed.fx"); TCHAR buffer[1024]; _stprintf(buffer, _T("%sbin32\\fxc.exe /Zpc /T fx_2_0 /Fo %s %s"), gkGetExecRootDir().c_str(), absbinaryPath.c_str(), sourcePath.c_str()); char bufferA[1024]; #ifdef UNICODE WideCharToMultiByte(CP_ACP, NULL, buffer, -1, bufferA, 1024, NULL, NULL ); #else _tcscpy( bufferA, buffer ); #endif system(bufferA); pFile = gEnv->pFileSystem->loadResFile( _T("Engine/Shaders/d3d9/ksCompileFailed.sto"), true ); if (!pFile) { // 如果报错shader还有错误,只崩溃了 gkLogError( _T("gkShader::Shader[%s] compile failed."), m_wstrFileName.c_str() ); return false; } } } return true; }
bool gkShader::loadImpl( IDirect3DDevice9* d3d9Device, ID3DXEffectPool** ppPool ) { HRESULT hr = S_OK; // 先在目录内查找名字 [9/18/2010 Kaiming-Desktop] TCHAR pureName[MAX_PATH]; _tcscpy(pureName, m_wstrFileName.c_str()); TCHAR* strLastSlash = NULL; // 取得MASK并摘除 strLastSlash = _tcsrchr( pureName, _T( '@' ) ); uint32 mask = 0; if (strLastSlash) { TCHAR strmask[MAX_PATH]; _tcscpy(strmask, strLastSlash + 1); *strLastSlash = 0; gkStdStringstream ss(strmask); ss >> mask; } m_macroMask = mask; // chop it's path strLastSlash = _tcsrchr( pureName, _T( '.' ) ); if( strLastSlash ) { *strLastSlash = 0; } m_gfxName = pureName; // load gfx IRapidXmlParser parser; // gfx可能存放在三个地方 bool legacy_routine = false; gkStdString gfxPath = _T("engine/shaders/template/built_in/") + gkStdString(pureName) + _T(".gfx"); if( gEnv->pFileSystem->checkFileExist( gfxPath.c_str() ) == eFS_notExsit ) { gfxPath = _T("engine/shaders/template/hidden/") + gkStdString(pureName) + _T(".gfx"); if( gEnv->pFileSystem->checkFileExist( gfxPath.c_str() ) == eFS_notExsit ) { gfxPath = _T("engine/shaders/template/extern/") + gkStdString(pureName) + _T(".gfx"); if( gEnv->pFileSystem->checkFileExist( gfxPath.c_str() ) == eFS_notExsit ) { legacy_routine = true; gkLogWarning( _T("Shader [%s] use old routine, this should be deprecate soon, please clean."), pureName); } } } if (!legacy_routine) { parser.initializeReading( gfxPath.c_str() ); } if (!legacy_routine && parser.getRootXmlNode() && parser.getRootXmlNode()->getChildNode(_T("D3D9Shader")) ) { bool success = loadFromGfxShader( parser.getRootXmlNode(), mask, d3d9Device, ppPool ); } else { switchSystemMacro(0); } parser.finishReading(); if (hr != S_OK) { gkLogError( _T("gkShader::Shader[%s] compile failed."), m_wstrFileName.c_str() ); return false; } D3DXHANDLE script = m_pEffect->GetParameterBySemantic( NULL, "STANDARDSGLOBAL"); if (script) { D3DXHANDLE layer = m_pEffect->GetAnnotationByName(script, "ScriptLayer"); if (layer) { LPCSTR szParamName; m_pEffect->GetString(layer, &szParamName); if (!(stricmp(szParamName, "RENDERLAYER_WATER"))) { m_uDefaultRenderLayer = RENDER_LAYER_WATER; } else if (!(stricmp(szParamName, "RENDERLAYER_SKY"))) { m_uDefaultRenderLayer = RENDER_LAYER_SKIES_EARLY; } } } memset( m_staticTechnique, 0, sizeof(m_staticTechnique) ); m_staticTechnique[eSIT_General] = FX_GetTechniqueByName("RenderScene"); m_staticTechnique[eSIT_Zpass_DL] = FX_GetTechniqueByName("ZPass"); m_staticTechnique[eSIT_Zpass_DS] = FX_GetTechniqueByName("ZPass_DS"); m_staticTechnique[eSIT_ShadowPass] = FX_GetTechniqueByName("ShadowPass"); m_staticTechnique[eSIT_ReflGenPass] = FX_GetTechniqueByName("ReflGenPass"); m_staticTechnique[eSIT_FastCubeGen] = FX_GetTechniqueByName("FastCubeGenPass"); if ( getRenderer()->GetStateManager() ) { m_pEffect->SetStateManager( getRenderer()->GetStateManager() ); } // 绑定默认参数 [4/15/2013 Kaiming] m_params.cleanParams(); D3DXEFFECT_DESC EffectDesc; // Gather the parameters hr = m_pEffect->GetDesc( &EffectDesc ); for( UINT i=0; i < EffectDesc.Parameters; i++ ) { D3DXHANDLE hParameter = m_pEffect->GetParameter( NULL, i ); if( NULL == hParameter ) { continue; } D3DXPARAMETER_DESC desc; m_pEffect->GetParameterDesc( hParameter, &desc ); if (desc.Annotations > 0) { //m_pEffect->GetAnnotation( ) GKSHADERPARAM* param = NULL; switch( desc.Type) { case D3DXPT_STRING: case D3DXPT_TEXTURE: { param = new GKSHADERPARAM( desc.Name, _T("/engine/assets/textures/default/flat.tga") ); } break; case D3DXPT_FLOAT: { char* databuf = new char[desc.Bytes]; m_pEffect->GetValue( hParameter, databuf , desc.Bytes ); switch( desc.Bytes ) { case sizeof(float): { float data = *((float*)databuf); param = new GKSHADERPARAM( desc.Name, data); // 现在只给float型的添加最大最小值 [4/16/2013 YiKaiming] D3DXHANDLE handle = m_pEffect->GetAnnotationByName( hParameter, "UIMin" ); if ( handle ) { float min; m_pEffect->GetFloat( handle, &min ); param->minValue = min; } handle = m_pEffect->GetAnnotationByName( hParameter, "UIMax" ); if ( handle ) { float max; m_pEffect->GetFloat( handle, &max ); param->maxValue = max; } } break; case sizeof(Vec2): { Vec2 data = *((Vec2*)databuf); param = new GKSHADERPARAM( desc.Name, data); } break; case sizeof(Vec3): { Vec3 data = *((Vec3*)databuf); param = new GKSHADERPARAM( desc.Name, data); } break; case sizeof(Vec4): { Vec4 data = *((Vec4*)databuf); param = new GKSHADERPARAM( desc.Name, data); } break; } delete[] databuf; } break; case D3DXPT_BOOL: case D3DXPT_INT: { } break; } if (param) { m_params.m_vecParams.push_back( param ); } } } if (FAILED(hr)) { gkLogWarning(_T("ShaderSystem:: Shader [%s] loaded failed. Creating Effect."), m_wstrFileName.c_str()); return false; } return true; }
//----------------------------------------------------------------------- void gkSceneBuilder::buildSceneFromFile( gkStdString filename,bool syncMode, bool bPak , Vec3 position, uint8 uRenderLayer, bool builtIn) { HRESULT hr = S_OK; m_bBuiltInPak = builtIn; m_uRenderLayer = uRenderLayer; if (!builtIn) { // gkStdString relScenePath = gkGetGameRelativePath(wszPath); // TCHAR todfilename[MAX_PATH]; _tcscpy_s(todfilename, filename.c_str()); todfilename[_tcslen(todfilename) - 4] = 0; _tcscat_s(todfilename, _T(".tod")); IRapidXmlParser todParser; todParser.initializeReading(todfilename); if (!todParser.getRootXmlNode()) { return; } gEnv->p3DEngine->getTimeOfDay()->loadTODSequence(todParser.getRootXmlNode(), true); todParser.finishReading(); // // gkLogMessage( _T("gkSceneBuilder::TodFile Loaded. [%s]"), filename.c_str() ); } ms_nAllNodeCount = 0; ms_nLoadedNodeCount = 0; // if not syncMode, we should clear the cache if (!syncMode) { m_currEntityList.clear(); m_lastEntityList.clear(); } // first drim to a pure filename [8/20/2011 Kaiming-Desktop] // uint8 index = filename.find_last_of('\\') + 1; // uint8 count = filename.length() - index; // filename = filename.substr(index, count); // // // 先在目录内查找名字 [9/18/2010 Kaiming-Desktop] // TCHAR wszPath[MAX_PATH] = _T(""); // hr = gkFindFileRelativeGame(wszPath, MAX_PATH, filename.c_str()); // assert( hr == S_OK ); // if not builtIn, load tod file [1/8/2012 Kaiming] gkLogMessage( _T("gkSceneBuilder::Creating: [%s] ..."), filename.c_str() ); float nStartTime = gEnv->pTimer->GetAsyncCurTime(); IRapidXmlParser sceneParser; sceneParser.initializeReading(filename.c_str()); // 建立地形 [4/4/2013 Kaiming] CRapidXmlParseNode* terrianNode = sceneParser.getRootXmlNode(_T("Terrian")); if (terrianNode) { ITerrianSystem* terrian = gEnv->p3DEngine->createTerrian(); terrian->Create( terrianNode ); } CRapidXmlParseNode* rootNode = sceneParser.getRootXmlNode(_T("SceneObjects")); rootNode->GetAttribute(_T("AllCount"), ms_nAllNodeCount); CRapidXmlParseNode* firstObject = rootNode->getChildNode(_T("gkObject")); if (firstObject) { // parsing one by one parseSceneObject(firstObject); } sceneParser.finishReading(); gEnv->pSystem->updateProgress( 100 ); removeEntitiesDeleted(); float nTimeLoadFile = gEnv->pTimer->GetAsyncCurTime() - nStartTime; gkLogWarning( _T("gkSceneBuilder::Loaded: [%s], use %0.2f seconds. \n"), filename.c_str() , nTimeLoadFile ); }
bool Image::loadCompressedTGA( TexImage* texture, FILE* file ) { //ASSERT( file != NULL && texture!=NULL ); uint32 bytePerPixel = texture->bpp/8; uint32 imgSize = texture->width*texture->height*bytePerPixel; texture->imageData = new uint8[ imgSize ]; uint32 pixelcount = texture->width * texture->height; uint32 currentPixel = 0; //当前正在读取的像素 uint32 currentByte = 0; //当前正在向图像中写入的像素 uint8 *colorbuffer = (uint8 *)malloc( bytePerPixel ); // 一个像素的存储空间s do { uint8 chunkHeader = 0; //存储ID块值的变量 if ( !fread( &chunkHeader,1, sizeof( uint8 ), file ) ){ return FALSE; } if ( chunkHeader < 128 ) //RAW块 { chunkHeader++; // 变量值加1以获取RAW像素的总数 for( int i = 0; i < chunkHeader; i++ ){ if ( fread( colorbuffer, 1,sizeof( bytePerPixel ), file ) != sizeof( bytePerPixel ) ){ gkLogWarning("Read pixel failed!\n"); return FALSE; } texture->imageData[currentByte] = colorbuffer[ 2 ]; texture->imageData[currentByte+1] = colorbuffer[1]; texture->imageData[currentByte+2] = colorbuffer[0]; if ( bytePerPixel == 4 ) texture->imageData[ currentByte+3] = colorbuffer[3]; currentPixel++; currentByte += bytePerPixel; } } //下一段处理描述RLE段的“块”头。首先我们将chunkheader减去127来得到获取下一个颜色重复的次数。 else { chunkHeader -= 127; //减去127获得ID bit 的rid 开始循环拷贝我们多次读到内存中的像素,这由RLE头中的值规定。 if ( fread( colorbuffer,1, sizeof( bytePerPixel ), file ) != sizeof( bytePerPixel ) ){ gkLogWarning("Read pixel failed!\n"); return FALSE; } for( int i = 0; i < chunkHeader; i++ ){ texture->imageData[ currentByte ] = colorbuffer[ 2 ]; // 拷贝“R”字节 texture->imageData[ currentByte +1 ] = colorbuffer[ 1 ]; // 拷贝“G”字节 texture->imageData[ currentByte + 2 ] = colorbuffer[ 0 ]; // 拷贝“B”字节 if ( bytePerPixel == 4 ) texture->imageData[ currentByte+3 ] = colorbuffer[ 3 ]; // 拷贝“A”字节 currentPixel++; currentByte += bytePerPixel; } } }while( currentPixel < pixelcount ); free( colorbuffer ); ::fclose( file ); return TRUE; }