|
|
实在是新手,我做了几次都没有编译通过:
工具:VC.NET 2003,Virtools Dev 3.0
我的这个框架是这样实现的:
1、用MFC生成一个基于Dialog的工程,然后删除不必要的Dialog和
AboutDlg,剩下了theApp,这就是我们要的。
2、设置好Include和Lib路径:VC.NET的 工具->选项->项目->VC++目录->显示以下内容的目录(S):
然后选择“包含文件”路径:C:\Program Files\Virtools\Virtools Dev 3.0\Sdk\Includes
“库文件”路径:C:\Program Files\Virtools\Virtools Dev 3.0\Sdk\Lib
3、设置工程属性:
项目->xxx属性(本例是MyTest属性)->链接器->输入->附加依赖项
设置为 VxMath.lib CK2.lib(至少包含)。
4、在stdafx.h中写入“#include "CKAll.h"
5、接下来就是下面这些代码了,旨在教你构建一个可以开发Virtools Player的框架
真正内容还要由你来
6、本代码可以看作是Virtools 的 Standalone Player 的代码的子集,但又不全是,
不同之处你可以自己比较一下了
***************************************************************/
// MyTest.cpp : 定义应用程序的类行为。
#include "stdafx.h"
#include "MyTest.h"
#ifdef CK_LIB
#include "CKLibIncludes.h"
#include "NewPlayerStaticLibs.h"
#include ".\mytest.h"
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define MAX_LOADSTRING 100
#define BTN_PLAY 1
#define BTN_RESET 2
#define BTN_CLOSE 3
#define BTN_LOAD 4
#define MAXOPTIONS 9
#define CAPTIONHEIGHT 22
// Global Variables for Interface
HINSTANCE hInst; // current instance
HACCEL g_hAccelTable;
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The Main Window class Name
TCHAR szRenderWindowClass[MAX_LOADSTRING]; // The render window class Name
HWND g_MainWindow,g_RenderWin; // The Main Window and Render Window Handles
HMENU g_ContextMenu; // Contextual Menu
HBITMAP g_Plays[4]; // Menu Bitmaps
HBITMAP g_Reset[3]; // ...
HBITMAP g_Close[2]; // ...
HBITMAP g_Load[3]; // ...
HBITMAP g_Virtools; // ...
int g_CurrentPlayState=0; // Menu Button States...
int g_CurrentResetState=0; // ...
int g_CurrentCloseState=0; // ...
int g_CurrentLoadState=0; // ...
BOOL g_DisableSwitch=FALSE; // Disables switching to or from fullscreen mode
BOOL g_NoContextMenu=FALSE; // Disables the context menu on right clicks
BOOL g_GoFullScreen=FALSE; // Go directly to fullscreen
int g_RefreshRate=0; // Default Fullscreen refresh rate
int g_Width=640; // Default Window width
int g_Height=480; // Default Window Height
int g_Bpp=16; // Default FullScreen Bit Per Pixel
int g_Driver=0; // Default FullScreen Driver
int g_CaptionOffset=0;
RECT g_mainwin_rect; //size of the main window (used to resize it when switching to fullscreen
//------------------------------------------------
// Global Variables for Player
CKContext* TheCKContext=NULL;
CKTimeManager* TheTimeManager=NULL;
CKMessageManager* TheMessageManager=NULL;
CKRenderManager* TheRenderManager=NULL;
CKRenderContext* TheRenderContext=NULL;
CKSpriteText* TheFrameRate=NULL;
CKSpriteText* g_MadeWith=NULL;
BOOL g_ShowFrameRate=FALSE;
BOOL g_ShowMadeWith=FALSE; // Go directly to fullscreen
DWORD g_TimeToHideSprite=0;
int g_FullScreenDriver=0;
int g_Mode=-1;
int g_MsgClick,g_MsgDoubleClick;
CKParameterOut* g_po; //Attribute used for exiting and changing file
BOOL g_ExitCK=FALSE; //Attribute value for exiting the player
int g_attr=-1; //Attribute type used for exiting and changing file
CKLevel* g_Level;
//--------------------------------------------------
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK RenderWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK Setup(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void DoVirtoolsProcess();
void CreateInterfaceSprite();
BOOL Load(char *str) ;
int GetTitleBtn();
void RepaintTitleBar();
void OnFullScreen(BOOL Replay = TRUE);
void OnPlayPause(int force);
void OnReset();
void ExitVirtoolsPlayer();
#define FORCE_PLAY 1
#define FORCE_PAUSE 2
// CMyTestApp
BEGIN_MESSAGE_MAP(CMyTestApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
CMyTestApp::CMyTestApp()// CMyTestApp 构造
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
CMyTestApp theApp;// 唯一的一个 CMyTestApp 对象
BOOL CMyTestApp::InitInstance()// CMyTestApp 初始化
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControls()。否则,将无法创建窗口。
InitCommonControls();
CWinApp::InitInstance();
AfxEnableControlContainer();
SetRegistryKey(_T("3D场景技术后台管理系统"));
// Initialize global strings
LoadString(m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(m_hInstance, IDC_NEWPLAYER, szWindowClass, MAX_LOADSTRING);
LoadString(m_hInstance, IDC_NEWPLAYERRENDER, szRenderWindowClass, MAX_LOADSTRING);
// Register window classes
MyRegisterClass(m_hInstance);
// Perform application initialization:
g_hAccelTable = LoadAccelerators(m_hInstance, (LPCTSTR)IDC_NEWPLAYER);
char Dummy[512]="";
char FileName[512]="";
char Options[MAXOPTIONS][128]={ "","","","","","","",""};
char Engine[128]="CK2_3D"; // Default render engine
int Xpos,Ypos;
int Width=g_Width+GetSystemMetrics(SM_CXBORDER)*2,Height=g_Height+GetSystemMetrics(SM_CYBORDER)*3+CAPTIONHEIGHT;
//GetSystemMetrics(SM_CYCAPTION);
RECT rect,dev={ 0,0,g_Width,g_Height};
hInst = m_hInstance; // Store instance handle in our global variable
//--------- Splash dialog
HWND splash=CreateDialog(m_hInstance,(LPCTSTR)IDD_DIALOG2, NULL, (DLGPROC)About);
GetWindowRect(splash,&rect);
SetWindowPos(splash,NULL,(GetSystemMetrics(SM_CXSCREEN)-(rect.right-rect.left))/2,
(GetSystemMetrics(SM_CYSCREEN)-(rect.bottom-rect.top))/2,
0,0,SWP_NOZORDER|SWP_NOSIZE);
ShowWindow(splash, SW_SHOW);
UpdateWindow(splash);
g_CaptionOffset=CAPTIONHEIGHT-GetSystemMetrics(SM_CYCAPTION)-2*GetSystemMetrics(SM_CYBORDER);
//----------- Main Window Creation
Xpos=(GetSystemMetrics(SM_CXSCREEN)-Width)/2;
Ypos=(GetSystemMetrics(SM_CYSCREEN)-Height)/2;
g_MainWindow = CreateWindow(szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SYSMENU),
Xpos, Ypos, Width, Height,
NULL, NULL, m_hInstance, NULL);
if (!g_MainWindow) return FALSE;
//----------- Render Window Creation
g_RenderWin = CreateWindowEx(WS_EX_TOPMOST,szRenderWindowClass, "",
(WS_CHILD|WS_OVERLAPPED|WS_VISIBLE),
0,0,g_Width,g_Height,
g_MainWindow,NULL,m_hInstance,0);
if (!g_RenderWin) return FALSE;
DragAcceptFiles(g_MainWindow,TRUE);
DragAcceptFiles(g_RenderWin,TRUE);
int RenderEngine=0;
CKStartUp();
CKPluginManager* ThePluginManager=CKGetPluginManager();
#ifdef CK_LIB
/*******************************************************
Version of the player with every plugins included
as a static library and not a Dll
********************************************************/
//---- DX7 rasterizer...
ThePluginManager->AddRenderEngineRasterizer(CKDX8RasterizerGetInfo);
//---- 1: If every plugins are needed (need to compile with every lib)
/*
RegisterAllStaticPlugins(ThePluginManager);
*/
//---- 2 : The above is equivalent to :
/*
RegisterRenderEngine(ThePluginManager);
RegisterAllReaders(ThePluginManager);
RegisterAllManagers(ThePluginManager);
RegisterAllBehaviors(ThePluginManager);
*/
//---- 3 : The above is equivalent to :
//---- in this case we can get rid of plugins
//---- we know we will not need...
CKPluginManager* pm = ThePluginManager;
RegisterRenderEngine(pm);
RegisterVirtoolsReader(pm);
RegisterImageReader(pm);
RegisterAVIReader(pm);
RegisterPNGReader(pm);
RegisterJPGReader(pm);
// MP3 are managed by the wav reader now
//RegisterMP3Reader(pm);
RegisterWAVReader(pm);
RegisterParamOpManager(pm);
RegisterInputManager(pm);
RegisterSoundManager(pm);
Register3DTransfoBehaviors(pm);
RegisterBBAddonsBehaviors(pm);
RegisterBBAddons2Behaviors(pm);
RegisterCamerasBehaviors(pm);
RegisterCamerasBehaviors(pm);
RegisterControllersBehaviors(pm);
RegisterCharactersBehaviors(pm);
RegisterCollisionsBehaviors(pm);
RegisterGridsBehaviors(pm);
RegisterInterfaceBehaviors(pm);
RegisterLightsBehaviors(pm);
RegisterLogicsBehaviors(pm);
RegisterMaterialsBehaviors(pm);
RegisterMeshesBehaviors(pm);
RegisterMidiBehaviors(pm);
RegisterNarrativesBehaviors(pm);
RegisterParticleSystemsBehaviors(pm);
//RegisterPhysicsBehaviors(pm);
RegisterSoundsBehaviors(pm);
RegisterVisualsBehaviors(pm);
RegisterWorldEnvBehaviors(pm);
RegisterVSLBehaviors(pm);
RegisterWebServerManager(pm);
//RegisterNetworkBehaviors(pm);
//RegisterNetworkServerBehaviors(pm);
//RegisterMultiPlayerBehaviors(pm);
//RegisterDownloadBehaviors(pm);
//RegisterDatabaseBehaviors(pm);
#else
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char szPath[_MAX_PATH],PluginPath[_MAX_PATH],RenderPath[_MAX_PATH],BehaviorPath[_MAX_PATH],ManagerPath[_MAX_PATH];
//--------- Get Extensions Directory
//这里我没有用环境变量,而是用的绝对路径
//注意这里的转移字符 "\",在Virtools给的例子里面没有,
//而且用起来不太好使,至少在我这里是这样的
strcpy(szPath,"C:\\Program Files\\Virtools\\Virtools Dev 3.0\\");
sprintf(PluginPath,"%s%s",szPath," lugins");
sprintf(RenderPath,"%s%s",szPath,"RenderEngines");
sprintf(ManagerPath,"%s%s",szPath,"Managers");
sprintf(BehaviorPath,"%s%s",szPath,"BuildingBlocks");
//--------- Parse Dlls
ThePluginManager->ParsePlugins(RenderPath);
ThePluginManager->ParsePlugins(ManagerPath);
ThePluginManager->ParsePlugins(BehaviorPath);
ThePluginManager->ParsePlugins(PluginPath);
//----- Search if a render engine was specified
int count=ThePluginManager->GetPluginCount(CKPLUGIN_RENDERENGINE_DLL);
if (strlen(Engine)>0) {
for (int i=0;i<count;i++)
{
CKPluginEntry* desc=ThePluginManager->GetPluginInfo(CKPLUGIN_RENDERENGINE_DLL,i);
CKPluginDll* dll =ThePluginManager->GetPluginDllInfo(desc->m_PluginDllIndex);
if (!strnicmp(Engine,dll->m_DllFileName.Str(),strlen(dll->m_DllFileName.Str()))) { RenderEngine=i; break; }
}
}
if (!count) {
MessageBox(NULL,"Initialisation Error","Unable to load a RenderEngine",MB_OK|MB_ICONERROR);
return FALSE;
}
#endif
XString inifile = CKGetStartPath();
inifile << "Player.ini";
//------ Initialize CK engine
CKERROR res=CKCreateContext(&TheCKContext,g_MainWindow,inifile.CStr());
if (res!=CK_OK)
{
if (res==CKERR_NODLLFOUND) MessageBox(NULL,"Initialisation Error","Unable to load a RenderEngine",MB_OK|MB_ICONERROR);
return FALSE;
}
TheCKContext->SetVirtoolsVersion(CK_VIRTOOLS_DEV,0x02000043);
TheMessageManager =TheCKContext->GetMessageManager();
TheTimeManager =TheCKContext->GetTimeManager();
TheRenderManager =TheCKContext->GetRenderManager();
//-------- Init Done => check available Display Mode and validate width / height / bpp settings
{
int i;
VxDriverDesc *MainDesc=TheRenderManager->GetRenderDriverDescription(0);
if (!MainDesc) {
MessageBox(NULL,"Initialisation Error","Unable to initialize a render driver",MB_OK|MB_ICONERROR);
CKCloseContext(TheCKContext);
return FALSE;
}
for (i=0;i<MainDesc->DisplayModes.Size();i++)
{
if (MainDesc->DisplayModes.Width==g_Width)
if (MainDesc->DisplayModes.Height==g_Height)
if (g_Bpp==MainDesc->DisplayModes.Bpp)
if (!g_RefreshRate || (g_RefreshRate == MainDesc->DisplayModes.RefreshRate)) {
g_FullScreenDriver=0;
g_Mode=i;
break;
}
}
if (g_Mode<0) {
// We didn't find a valid resolution try again with a different bpp (but > 16)
// default to a standard resolution
g_Width=640;
g_Height=480;
for (i=0;i<MainDesc->DisplayModes.Size();i++)
{
if (MainDesc->DisplayModes.Width==g_Width)
if (MainDesc->DisplayModes.Height==g_Height)
if (MainDesc->DisplayModes.Bpp>8) {
g_FullScreenDriver=0;
g_Mode=i;
g_Bpp=MainDesc->DisplayModes.Bpp;
break;
}
}
}
}
//---- If current driver cannot do windowed mode force fullscreen
// VxDriverDesc* desc=CKGetRenderDriverDescription(g_Driver);
// if (!desc->Caps2D.CanDoWindowed) g_GoFullScreen=TRUE;
//---- If there is no file to load and we go fullscreen
//---- stops now
if (g_GoFullScreen && strlen(FileName)<=0)
{
MessageBox(NULL,"No file specified...","Virtools Player Error",MB_ICONEXCLAMATION|MB_OK);
return FALSE;
}
DestroyWindow(splash);
ShowWindow(g_MainWindow, m_nCmdShow);
UpdateWindow(g_MainWindow);
ShowWindow(g_RenderWin, m_nCmdShow);
UpdateWindow(g_RenderWin);
//////// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
//////// 而不是启动应用程序的消息泵。
//上面这段话是系统加的,其实我已经在类里封装了消息泵(消息循环)Run();
//接下来可就是你对virtools 的理解了,我得程序到此为止,靠你了 
return TRUE;
}
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_NEWPLAYER);
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
//这个就是用来Render的子窗口
WNDCLASS MyRenderClass;
ZeroMemory(&MyRenderClass,sizeof(MyRenderClass));
MyRenderClass.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
MyRenderClass.lpfnWndProc=(WNDPROC)RenderWndProc;
MyRenderClass.hInstance=hInstance;
MyRenderClass.hbrBackground =CreateSolidBrush(0x00ff);
MyRenderClass.lpszClassName=szRenderWindowClass;
RegisterClass(&MyRenderClass);
return RegisterClassEx(&wcex);
}
//这里我把窗口的回调函数分开写了,这个是主窗口函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent,btn;
switch (message)
{
case WM_KEYDOWN: // Keys
{
int Key=(int)wParam;
if(Key==VK_ESCAPE)
DestroyWindow(hWnd);
else if(Key==VK_SPACE)
MessageBox(hWnd,"Nice to meet you\nKeep comunication with me please!","albertbanda says to you: -- Press ESC to quit.",MB_OK);
}
break;
case WM_RBUTTONUP:
break;
case WM_LBUTTONDBLCLK: // Sends a Message "OnClick" or "OnDblClick" if any object is under mouse cursor
case WM_LBUTTONDOWN:
break;
case WM_COMMAND: // Contextual menu commands
break;
case WM_GETMINMAXINFO: // Minimum size of the player window
case WM_SIZE: // Resize the render context
break;
case WM_SYSKEYDOWN: // If ALT-ENTER is pressed go to fullscreen
break;
case WM_SETCURSOR:
break;
case WM_DROPFILES: // Load any dropped file
break;
case WM_NCLBUTTONDOWN: // Handle clicks on caption bar
break;
case WM_MOUSEMOVE:
case WM_NCMOUSEMOVE: // Handle Highlights on buttons
break;
case WM_ACTIVATEAPP:
break;
case WM_NCACTIVATE: // Repaint title bar
case WM_NCPAINT:
break;
case WM_PAINT: // Repaint main frame
break;
case WM_DESTROY: // Clean up things
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//这个是Render窗口函数,你当然可以创建多线程
LRESULT CALLBACK RenderWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent,btn;
PAINTSTRUCT ps;
HDC hdc;
TCHAR MyCon[]="这是一个用VC开发Virtools的框架程序,还没有实际内容,下面就看你的了!";
switch (message)
{
case WM_KEYDOWN: // Keys
{
int Key=(int)wParam;
}
break;
case WM_PAINT:
{
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc,10,10,MyCon,sizeof(MyCon)-1);
EndPaint(hWnd,&ps);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//下面是消息循环,也就是系统所说的消息泵;当然,你可以根据需要更改和扩展之
int CMyTestApp::Run(void)
{
MSG msg;
while (1)
{
if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
return msg.wParam;
}
else if (!TranslateAccelerator(msg.hwnd, g_hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
} |
|