Urho3D地形编辑器的使用与功能介绍

版权申诉
0 下载量 37 浏览量 更新于2024-11-24 收藏 32.9MB ZIP 举报
资源摘要信息:"Urho3D地形编辑器是一个集成在Urho3D游戏引擎中的工具,它允许用户在Urho3D环境中创建和编辑3D地形。Urho3D是一个开源的高性能游戏引擎,支持跨平台开发,用于制作2D和3D的游戏和应用程序。地形编辑器作为其工具集的一部分,提供了直观的界面和功能,让用户能够快速地搭建和修改复杂的地形模型。 首先,要理解Urho3D地形编辑器,需要对Urho3D引擎有一个基本的了解。Urho3D使用C++编写,并提供了一套API来帮助开发者创建游戏和实时应用程序。它包括了一系列的模块,例如渲染、物理、场景管理、动画和声音处理等,而地形编辑器则主要关注于场景管理模块。 使用Urho3D地形编辑器,开发者可以实现以下功能: 1. 创建地形:开发者可以开始一个全新的地形项目,通过定义地形的尺寸、分辨率、材质和光照等来构建基础地形。 2. 高度贴图导入:通过导入高度图(heightmap),地形编辑器能够根据高度数据生成地形的高低起伏,高度图是一种灰度图像,其中不同的灰度值代表不同的高度。 3. 地形材质编辑:用户可以指定不同的纹理和材料给地形的各个区域,以便创建多样化的地面效果,例如草地、泥土、岩石等。 4. 植被和细节添加:为了增加真实感,地形编辑器允许用户添加植被(如树木、灌木和草丛)和地表细节(如石头、木桩等)。 5. 地形渲染优化:Urho3D地形编辑器提供了一些工具和选项来优化地形的渲染性能,例如LOD(Level of Detail)技术和多分辨率地形。 6. 脚本和自动化:Urho3D支持使用AngelScript脚本来增强编辑器的功能和灵活性。用户可以通过脚本自动化地形编辑过程中的复杂任务。 7. 保存和导出:编辑完毕后,地形可以被保存为Urho3D的场景格式,以便在游戏中使用。也可以导出为其他格式,以便在其他工具或引擎中使用。 Urho3D地形编辑器的使用方法通常包括以下几个步骤: 1. 首先启动Urho3D地形编辑器,并创建一个新项目或者打开一个现有的地形场景文件。 2. 在编辑器中,用户可以设置地形的各种参数,包括尺寸、高度范围、材质类型等。 3. 用户导入高度图和材质贴图,编辑器会根据这些图像生成相应的地形和纹理效果。 4. 利用编辑器的工具添加树木、石头等细节,或者使用刷子工具改变地形的特定部分。 5. 通过预览窗口检查地形的外观,并调整渲染设置以提高性能。 6. 最后,保存编辑好的地形场景,或者将其导出为不同的格式以适应不同的开发需求。 Urho3D地形编辑器由于其在Urho3D引擎中的集成性,成为了制作高质量地形的有力工具。开发者可以利用它快速搭建出复杂且细节丰富的游戏世界,而无需深入了解底层的地形渲染技术。这对于独立游戏开发者和小型开发团队来说是一个非常实用的特性。"
2012-12-10 上传
/****************************************************************************************/ /* Compiler.cpp */ /* */ /* Author: Jim Mischel */ /* Description: Dialog and thread code for compiling maps with gbsplib */ /* */ /* The contents of this file are subject to the Genesis3D Public License */ /* Version 1.01 (the "License"); you may not use this file except in */ /* compliance with the License. You may obtain a copy of the License at */ /* http://www.genesis3d.com */ /* */ /* Software distributed under the License is distributed on an "AS IS" */ /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ /* the License for the specific language governing rights and limitations */ /* under the License. */ /* */ /* The Original Code is Genesis3D, released March 25, 1999. */ /* Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved */ /* */ /****************************************************************************************/ #include "stdafx.h" #include "compiler.h" #pragma warning(disable : 4201 4214 4115 4514 4711) #include <windows.h> #include <shellapi.h> #pragma warning(default : 4201 4214 4115) #include <assert.h> #include <io.h> #include <fstream.h> #include "filepath.h" #include "consoletab.h" // for ConPrintf (yes, it's ugly) #include "util.h" static CWinThread *CompilerThread = NULL; static HWND hwndThreadParent = NULL; static geBoolean ThreadActive = GE_FALSE; static HINSTANCE GBSPHandle = NULL; static GBSP_FuncHook *GlobalFHook; static ofstream *CompileLog; CompilerErrorEnum Compiler_RunPreview ( char const *PreviewFilename, char const *MotionFilename, char const *GPreviewPath ) { assert (ThreadActive == GE_FALSE); char DestBspName[_MAX_PATH]; { // Verify the .BSP file exists... if (_access (PreviewFilename, 0) != 0) { return COMPILER_ERROR_NOBSP; } } // we're going to copy the preview file to the "levels" subdirectory // of the GPreviewPath directory... // // So, if the PreviewFilename is "C:\MyStuff\MyLevel.bsp", // and GPreviewPath is "C:\Editor\GPreview.exe", then the resulting // file name is "C:\Editor\levels\MyLevel.bsp" // { /* char PreviewDrive[_MAX_PATH]; char PreviewDir[_MAX_PATH]; char Name[_MAX_PATH]; char Ext[_MAX_PATH]; _splitpath (PreviewFilename, NULL, NULL, Name, Ext); _splitpath (GPreviewPath, PreviewDrive, PreviewDir, NULL, NULL); strcat (PreviewDir, "media\\levels\\"); _makepath (DestBspName, PreviewDrive, PreviewDir, Name, Ext); */ // make dest path same as source path strcpy(DestBspName, PreviewFilename); } // if source and destination are the same, then don't copy... if (stricmp (DestBspName, PreviewFilename) != 0) { if(!CopyFile (PreviewFilename, DestBspName, FALSE)) { int LastError; LastError = GetLastError(); if (LastError != ERROR_FILE_EXISTS) { ConPrintf("GPreviewPath: %s \n", GPreviewPath); ConPrintf("CopyFile (%s, %s)\nGetLastError()==%d\n", PreviewFilename, DestBspName, LastError); return COMPILER_ERROR_BSPCOPY; } } } { // copy the motion file if it exists char DestName[_MAX_PATH]; // check to see if the file exists FilePath_SetExt (DestBspName, ".mot", DestName); if (_access (MotionFilename, 0) == 0) // _access returns 0 on success...of course! { if (stricmp (MotionFilename, DestName) != 0) { if (!CopyFile (MotionFilename, DestName, FALSE)) { if(GetLastError() != ERROR_FILE_EXISTS) { ConPrintf ("%s", "Unable to copy the motion file.\n"); ConPrintf ("%s", "Continuing with preview.\n"); } } } } else { _unlink (DestName); } } { SHELLEXECUTEINFO shx; char Params[_MAX_PATH]; char DefaultDir[_MAX_PATH]; char NoExtName[_MAX_PATH]; FilePath_GetDriveAndDir (GPreviewPath, DefaultDir); FilePath_GetName (DestBspName, NoExtName); sprintf (Params, "-map %s", NoExtName); shx.fMask = 0; shx.hwnd = NULL; //(HWND)AfxGetMainWnd(); shx.lpVerb = NULL; shx.lpFile = GPreviewPath; shx.lpParameters= Params; shx.lpDirectory = DefaultDir; shx.nShow = SW_NORMAL; shx.hInstApp = NULL; shx.cbSize = sizeof(shx); ShellExecuteEx(&shx;); } return COMPILER_ERROR_NONE; } geBoolean Compiler_CancelCompile ( void ) { if (!ThreadActive) { return GE_FALSE; } return GlobalFHook->GBSP_Cancel (); } static CompilerErrorEnum Compiler_LoadCompilerDLL ( GBSP_FuncHook **ppFHook, HINSTANCE *pHandle, ERROR_CB ErrorCallbackFcn, PRINTF_CB PrintfCallbackFcn ) { GBSP_INIT *GBSP_Init; GBSP_Hook Hook; GBSP_FuncHook *FHook; assert (ppFHook != NULL); assert (pHandle != NULL); *ppFHook = NULL; Hook.Error = ErrorCallbackFcn; Hook.Printf = PrintfCallbackFcn; GBSPHandle = LoadLibrary("gbsplib.dll"); if (GBSPHandle == NULL) { PrintfCallbackFcn ("Compile Failed: Unable to load gbsplib.dll!\nGetLastError returned %d.\n", GetLastError ()); return COMPILER_ERROR_NODLL; } GBSP_Init =(GBSP_INIT*)GetProcAddress(GBSPHandle, "GBSP_Init"); if (GBSP_Init == NULL) { PrintfCallbackFcn ("%s", "Compile Failed: Couldn't initialize GBSP_Init, GBSPLib.Dll.\n."); FreeLibrary(GBSPHandle); return COMPILER_ERROR_MISSINGFUNC; } FHook = GBSP_Init (&Hook;); if (FHook == NULL) { PrintfCallbackFcn ("%s", "Compile Failed: GBSP_Init returned NULL Hook!, GBSPLib.Dll.\n."); FreeLibrary(GBSPHandle); return COMPILER_ERROR_MISSINGFUNC; } if(FHook->VersionMajor > GBSP_VERSION_MAJOR) { PrintfCallbackFcn ("%s", "Compile Failed: GBSP Version Incompatible, GBSPLib.Dll.\n."); FreeLibrary (GBSPHandle); return COMPILER_ERROR_MISSINGFUNC; } *ppFHook = FHook; *pHandle = GBSPHandle; return COMPILER_ERROR_NONE; } CompilerErrorEnum Compiler_Compile ( CompileParamsType const *pParams, ERROR_CB ErrorCallbackFcn, PRINTF_CB PrintfCallbackFcn ) { HINSTANCE GBSPHandle; CompilerErrorEnum CompileRslt; GBSP_RETVAL GbspRslt; char BspFilename[_MAX_PATH]; char MotionFilename[_MAX_PATH]; // load compiler DLL CompileRslt = Compiler_LoadCompilerDLL (&GlobalFHook;, &GBSPHandle;, ErrorCallbackFcn, PrintfCallbackFcn); if (CompileRslt == COMPILER_ERROR_NONE) { FilePath_SetExt (pParams->Filename, ".bsp", BspFilename); FilePath_SetExt (pParams->Filename, ".mot", MotionFilename); if (pParams->EntitiesOnly) { #if 1 #pragma message ("Should UpdateEntities return a GBSP_RETVAL?") if (GlobalFHook->GBSP_UpdateEntities ((char *)pParams->Filename, BspFilename)) { GbspRslt = GBSP_OK; } else { GbspRslt = GBSP_ERROR; } #else GbspRslt = GlobalFHook->GBSP_UpdateEntities ((char *)pParams->Filename, BspFilename); #endif switch (GbspRslt) { case GBSP_ERROR: PrintfCallbackFcn ("%s", "Compile Failed: GBSP_UpdateEntities returned an error. GBSPLib.Dll.\n"); CompileRslt = COMPILER_ERROR_BSPFAIL; break; case GBSP_OK : break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "UpdateEntities cancelled by user.\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; default : assert (0); } } else if (pParams->RunBsp) { _unlink (MotionFilename); // gotta make sure this doesn't exist... GbspRslt = GlobalFHook->GBSP_CreateBSP ((char *)pParams->Filename, (BspParms *)&pParams;->Bsp); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("%s", "Compile Failed: GBSP_CreateBSP encountered an error, GBSPLib.Dll.\n."); CompileRslt = COMPILER_ERROR_BSPFAIL; break; case GBSP_OK : //save as a bsp GbspRslt = GlobalFHook->GBSP_SaveGBSPFile(BspFilename); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("Compile Failed: GBSP_SaveGBSPFile for file: %s, GBSPLib.Dll.\n.", BspFilename); CompileRslt = COMPILER_ERROR_BSPSAVE; break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "Save cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; case GBSP_OK : break; default : assert (0); } break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "Compile cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; default : assert (0); //?? } GlobalFHook->GBSP_FreeBSP(); } } if (CompileRslt == COMPILER_ERROR_NONE) { if(pParams->DoVis && !pParams->EntitiesOnly) { GbspRslt = GlobalFHook->GBSP_VisGBSPFile ((char *)BspFilename, (VisParms *)&pParams;->Vis); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("Warning: GBSP_VisGBSPFile failed for file: %s, GBSPLib.Dll.\n.", BspFilename); break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "GBSP_VisGBPSFile cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; case GBSP_OK : break; default : assert (0); } } } if (CompileRslt == COMPILER_ERROR_NONE) { if (pParams->DoLight) { /* The compiler has no flag that tells it not to do min lighting. So, if the min lighting flag is not on, we set the MinLight vector to all 0s. */ LightParms rad; rad = pParams->Light; if (!pParams->UseMinLight) { geVec3d_Set (&rad;.MinLight, 0.0f, 0.0f, 0.0f); } // If UseMinLight isn't on, then don't pass GbspRslt = GlobalFHook->GBSP_LightGBSPFile(BspFilename, &rad;); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("Warning: GBSP_LightGBSPFile failed for file: %s, GBSPLib.Dll.\n", BspFilename); break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "GBSP_LightGBSPFile cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; case GBSP_OK : break; default : assert (0); } } } // and free the DLL... if (GBSPHandle != NULL) { FreeLibrary (GBSPHandle); } return CompileRslt; } static void Compiler_NotifyApp ( char const *buf, int MsgId ) { #if 1 char *errmsg; errmsg = Util_Strdup (buf); if (errmsg != NULL) { ::PostMessage (hwndThreadParent, MsgId, COMPILER_PROCESSID, (LPARAM)errmsg); } #else ConPrintf ("%s", buf); #endif } static void Compiler_PrintfCallback ( char *format, ... ) { va_list argptr; char buf[32768]; //this is ... cautious va_start (argptr, format); vsprintf (buf, format, argptr); va_end (argptr); if (CompileLog) (*CompileLog) << buf; Compiler_NotifyApp (buf, WM_USER_COMPILE_MSG); } static void Compiler_ErrorCallback ( char *format, ... ) { va_list argptr; char buf[32768]; //this is ... cautious va_start (argptr, format); vsprintf (buf, format, argptr); va_end (argptr); if (CompileLog) (*CompileLog) << buf; Compiler_NotifyApp (buf, WM_USER_COMPILE_ERR); } static UINT Compiler_ThreadProc ( void *pParam ) { CompileParamsType CompileParams; CompilerErrorEnum CompileRslt; assert (pParam != NULL); assert (ThreadActive == GE_FALSE); ThreadActive = GE_TRUE; CompileParams = *((CompileParamsType *)pParam); char LogFilename[_MAX_PATH]; FilePath_SetExt(CompileParams.Filename, ".log", LogFilename); CompileLog = new ofstream(LogFilename, ofstream::out | ofstream::trunc); CompileRslt = Compiler_Compile (&CompileParams;, Compiler_ErrorCallback, Compiler_PrintfCallback); if (CompileRslt == COMPILER_ERROR_NONE) { Compiler_PrintfCallback ("%s", "------------------------------\n"); Compiler_PrintfCallback ("%s", "Compile successfully completed\n"); } if (CompileLog) { (*CompileLog).close(); delete CompileLog; } // notify parent that the compile has completed ::PostMessage (hwndThreadParent, WM_USER_COMPILE_DONE, COMPILER_PROCESSID, (LPARAM)CompileRslt); ThreadActive = GE_FALSE; return 0; } CompilerErrorEnum Compiler_StartThreadedCompile ( CompileParamsType const *pParams, HWND hwndNotify ) { CWinThread *Thread; assert (ThreadActive == GE_FALSE); hwndThreadParent = hwndNotify; Thread = AfxBeginThread ( Compiler_ThreadProc, // AFX_THREADPROC pfnThreadProc, (LPVOID)pParams, // LPVOID pParam, THREAD_PRIORITY_NORMAL, // int nPriority = THREAD_PRIORITY_NORMAL, 0, // UINT nStackSize = 0, 0, // DWORD dwCreateFlags = 0, NULL // LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); if (Thread != NULL) { CompilerThread = Thread; return COMPILER_ERROR_NONE; } else { return COMPILER_ERROR_THREAD; // couldn't spawn the thread } } geBoolean Compiler_CompileInProgress ( void ) { return ThreadActive; }