Simple Win32 Program

简介:

Rational: I wanted to create an archetype program that would be able to handle multiple key combinations. Say, the right shift key and the the key character 'X'. My options available OIS, MFC, or WxWindows. MFC and WxWindows would be a lot overhead and dll version management for what is a simple program. After unsuccseful attempts at making OIS work I decided that the [Petzold:http://en.wikipedia.org/wiki/Charles_Petzold] style of program would minimize the windows "portion" and show how ogre would need to interact. When finished this program would show the classic orgehead mesh, respond to a few key inputs and adjust to camera position in response to the mouse or the keyboard.


First this program was created with Microsoft Visual Studio 2003 and links to the einhort version 1.3.0 of ogre library. The easiest way to start off is to use the wizard to create a simple windows application ogre32,which should give you the following files: 

ogre32.cpp
ogre32.h
ogre32.ico
ogre32.ncb
ogre32.rc
ogre32.sln
ogre32.vcproj
ReadMe.txt
Resource.h
small.ico
stdafx.cpp
stdafx.h
Before modifying the code that the wizard created you will need to get the media files and scripts necessary to display the ogrehead.mesh file. To do this you will need to create the directory 'media' under your main project and copy the following files into this directory. The png and jpg files can be found in the one of textures directory. The Ogre.material file is modified version of the Ogre.material file that comes with ogre source code. The origininal can be found at .\ogrenew\Samples\Media\materials\scripts. 


cursor.png
dirt01.jpg
GreenSkin.jpg
Ogre.material
ogreborder.png
ogreborderUp.png
ogrehead.mesh
spheremap.png
WeirdEye.png
You will need to create three configuration files: 


ogre.cfg
Plugins.cfg
resources.cfg

ogre.cfg

 
None.gifRender System=Direct3D9 Rendering Subsystem
None.gif
None.gif [ Direct3D9 Rendering Subsystem ]
None.gifAllow NVPerfHUD=No
None.gifAnti aliasing=None
None.gifFloating-point mode=Fastest
None.gifFull Screen=No
None.gifRendering Device=NVIDIA GeForce FX 5200
None.gifVSync=No
None.gifVideo Mode=800 x 600 @ 32-bit colour
None.gif
None.gif [ OpenGL Rendering Subsystem ]
None.gifColour Depth=32
None.gifDisplay Frequency=60
None.gifFSAA=0
None.gifFull Screen=Yes
None.gifRTT Preferred Mode=FBO
None.gifVSync=No
None.gifVideo Mode=1024 x 768

Plugins.cfg

 
None.gif# Defines plugins to load
None.gif
None.gif# Define plugin folder
None.gifPluginFolder=.
None.gif
None.gif# Define plugins
None.gifPlugin=RenderSystem_Direct3D9

resources.cfg

None.gif# Resource locations to be added to the default path
None.gif [ General ]
None.gifFileSystem=./media
None.gif
You will need to edit the follow files: 
stdafx.h
ogre32.cpp

stdafx.h

None.gif#pragma once
None.gif
None.gif
None.gif #define WIN32_LEAN_AND_MEAN
None.gif#include <windows.h>
None.gif //  C RunTime Header Files
None.gif
#include <stdlib.h>
None.gif#include <malloc.h>
None.gif#include <memory.h>
None.gif#include <tchar.h>
None.gif#include <Ogre.h>     // brings in most everything

 

ogre32.cpp

The following is the original  ogre32.cpp  file This will create a simple project that displays the ogrehead mesh file.
None.gif //  ogre32.cpp : Defines the entry point for the application.
None.gif
//
None.gif

None.gif#include "stdafx.h"
None.gif#include "ogre32.h"
None.gif #define MAX_LOADSTRING 100
None.gif
None.gif //  Global Variables:
None.gif
HINSTANCE hInst;             //  current instance
None.gif
TCHAR szTitle[MAX_LOADSTRING];         //  The title bar text
None.gif
TCHAR szWindowClass[MAX_LOADSTRING];     //  the main window class name
None.gif

None.gif using  namespace Ogre;  //  <-- ultimate in lazy

 

The most important of the following variables is mRoot. As the "Root class represents a starting point for the client application. From here, the application can gain access to the fundamentals of the system ... and Root must be created before any other Ogre operations are called. Once an instance has been created, the same instance is accessible throughout the life of that object by using Root::getSingleton (as a reference) or Root::getSingletonPtr (as a pointer). " See http://www.ogre3d.org/docs/api/html/classOgre_1_1Root.html#_details for more details.

Please consult the wiki for more detailed reasons on why we added each of these variables.

None.gifRoot *mRoot             = 0;   //  
None.gif
SceneManager *mSceneMgr = 0;   //  
None.gif
Camera *mCamera         = 0;   //  
None.gif
Viewport* mViewPort     = 0; 
None.gifRenderWindow* mRenderWindow=0; 
None.gif
None.gif //  Forward declarations of functions included in this code module:
None.gif
ATOM                MyRegisterClass(HINSTANCE hInstance);
None.gifBOOL                InitInstance(HINSTANCE,  int);
None.gifLRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
None.gifLRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
None.gif
None.gif int APIENTRY _tWinMain(HINSTANCE hInstance,
None.gif                     HINSTANCE hPrevInstance,
None.gif                     LPTSTR    lpCmdLine,
None.gif                      int       nCmdShow)
ExpandedBlockStart.gif {
InBlock.gif     // TODO: Place code here.
InBlock.gif
    MSG msg;
InBlock.gif    HACCEL hAccelTable;
InBlock.gif    HWND hWnd;
InBlock.gif    // Initialize global strings
InBlock.gif
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
InBlock.gif    LoadString(hInstance, IDC_OGRE32, szWindowClass, MAX_LOADSTRING);
InBlock.gif    MyRegisterClass(hInstance);
InBlock.gif
InBlock.gif    
InBlock.gif    hInst = hInstance; // Store instance handle in our global variable
InBlock.gif

InBlock.gif    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
InBlock.gif
InBlock.gif    if (!hWnd)
ExpandedSubBlockStart.gif    {
InBlock.gif        return FALSE;
ExpandedSubBlockEnd.gif    }

create the root ogre system
None.gifmRoot =  new Root();

 load the configuration file why?
None.gif    ConfigFile cf;
None.gif    cf.load("resources.cfg");
None.gif
None.gif    ConfigFile::SectionIterator seci = cf.getSectionIterator();
None.gif
None.gif    String secName, typeName, archName;
None.gif     while (seci.hasMoreElements())
ExpandedBlockStart.gif     {
InBlock.gif        secName = seci.peekNextKey();
InBlock.gif        ConfigFile::SettingsMultiMap *settings = seci.getNext();
InBlock.gif        ConfigFile::SettingsMultiMap::iterator i;
InBlock.gif        for (i = settings->begin(); i != settings->end(); ++i)
ExpandedSubBlockStart.gif        {
InBlock.gif            typeName = i->first;
InBlock.gif            archName = i->second;
InBlock.gif            ResourceGroupManager::getSingleton().addResourceLocation(
InBlock.gif                archName, typeName, secName);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

 Load the directx rendering system we dont have to Display the configuration dialog.
None.gifRenderSystemList *rsList = mRoot->getAvailableRenderers();
None.gif     int c=0;
None.gif     bool foundit =  false;
None.gif    RenderSystem *selectedRenderSystem=0;
None.gif     while(c < ( int) rsList->size())
ExpandedBlockStart.gif     {
InBlock.gif        selectedRenderSystem = rsList->at(c);
InBlock.gif        String rname = selectedRenderSystem->getName();
InBlock.gif        if(rname.compare("Direct3D9 Rendering Subsystem")==0)
ExpandedSubBlockStart.gif        {
InBlock.gif            foundit=true;
InBlock.gif            break;
ExpandedSubBlockEnd.gif        }

InBlock.gif        c++; // <-- oh how clever
ExpandedBlockEnd.gif
    }

None.gif     if(!foundit) 
None.gif         return FALSE;  // we didn't find itdot.gif
None.gif
None.gif    
// we found it, we might as well use it!
None.gif
    mRoot->setRenderSystem(selectedRenderSystem);
None.gif
None.gif    selectedRenderSystem->setConfigOption("Full Screen","No");  
None.gif    selectedRenderSystem->setConfigOption("Video Mode","800 x 600 @ 16-bit colour");
None.gif
None.gif     // retrieve the config option map
None.gif
    ConfigOptionMap comap = selectedRenderSystem->getConfigOptions();
None.gif
None.gif     // and now we need to run through all of it
None.gif
    ConfigOptionMap::const_iterator start = comap.begin();
None.gif    ConfigOptionMap::const_iterator end = comap.end();
None.gif     while(start != end)
ExpandedBlockStart.gif     {
InBlock.gif        String OptionName = start->first;
InBlock.gif        String CurrentValue = start->second.currentValue;
InBlock.gif        StringVector PossibleValues = start->second.possibleValues;
InBlock.gif        int c=0;
InBlock.gif        while (c < (int) PossibleValues.size())
ExpandedSubBlockStart.gif        {
InBlock.gif            String OneValue = PossibleValues.at(c);
InBlock.gif            c++;
ExpandedSubBlockEnd.gif        }

InBlock.gif    start++;
ExpandedBlockEnd.gif    }
    
None.gif     // end boilerplate

 this is the magic! here is where we take the window that has been previously been created and attach ogre to it.
None.gifmRoot->initialise( false,"Some Window Title");
None.gif    NameValuePairList misc;
None.gif    misc["externalWindowHandle"] = StringConverter::toString( (size_t)hWnd);
None.gif    mRenderWindow = mRoot->createRenderWindow( "My sub render window", 800, 600,  false, &misc );

 create a scene manager
None.gif //  choose sm
None.gif
    mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "mSceneMgr");
None.gif    mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

This is so we can have scripts work and the mesh is properly rendered.
None.gifResourceGroupManager::getSingleton().initialiseAllResourceGroups();

 Load a mesh that is located in the ./media directory.
None.gifEntity *ent1 = mSceneMgr->createEntity( "ogre", "ogrehead.mesh" );
None.gif        SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
None.gif        node1->attachObject( ent1 );

 Create a camera so we can look at his lovely mug.
None.gif //  --------------------
None.gif    
//  Create the camera
None.gif
    mCamera = mSceneMgr->createCamera("PlayerCam");
None.gif     //  Position it at 500 in Z direction
None.gif
    mCamera->setPosition(Ogre::Vector3(0,0,500));
None.gif     //  Look back along -Z
None.gif
    mCamera->lookAt(Ogre::Vector3(0,0,-300));
None.gif    mCamera->setNearClipDistance(5);
None.gif     //  Set the viewport
None.gif
    mViewPort = mRenderWindow->addViewport(mCamera);
None.gif    mViewPort->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 0.0f, 1.0f)); 
None.gif
None.gif    ShowWindow(hWnd, nCmdShow);
None.gif    UpdateWindow(hWnd);
None.gif
None.gif    
None.gif    hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_OGRE32);
None.gif
None.gif     //  Main message loop:
None.gif
     while (GetMessage(&msg, NULL, 0, 0)) 
ExpandedBlockStart.gif     {       
InBlock.gif                //placing renderOneFrame seems to allow for a clean shutdown.
InBlock.gif                
//thanks to user lakin for that hint.
InBlock.gif
        if (mRoot->renderOneFrame()) 
ExpandedSubBlockStart.gif        {
InBlock.gif            TranslateMessage(&msg);
InBlock.gif            DispatchMessage(&msg);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif
None.gif     return ( int) msg.wParam;
None.gif}
None.gif
None.gif
None.gifATOM MyRegisterClass(HINSTANCE hInstance)
ExpandedBlockStart.gif {
InBlock.gif    WNDCLASSEX wcex;
InBlock.gif
InBlock.gif    wcex.cbSize = sizeof(WNDCLASSEX); 
InBlock.gif
InBlock.gif    wcex.style            = CS_HREDRAW | CS_VREDRAW;
InBlock.gif    wcex.lpfnWndProc    = (WNDPROC)WndProc;
InBlock.gif    wcex.cbClsExtra        = 0;
InBlock.gif    wcex.cbWndExtra        = 0;
InBlock.gif    wcex.hInstance        = hInstance;
InBlock.gif    wcex.hIcon            = LoadIcon(hInstance, (LPCTSTR)IDI_OGRE32);
InBlock.gif    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
InBlock.gif    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
InBlock.gif    wcex.lpszMenuName    = NULL;
InBlock.gif    wcex.lpszClassName    = szWindowClass;
InBlock.gif    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
InBlock.gif
InBlock.gif    return RegisterClassEx(&wcex);
ExpandedBlockEnd.gif}

None.gif
None.gifBOOL InitInstance(HINSTANCE hInstance,  int nCmdShow)
ExpandedBlockStart.gif {
InBlock.gif   HWND hWnd;
InBlock.gif
InBlock.gif   hInst = hInstance; // Store instance handle in our global variable
InBlock.gif

InBlock.gif   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
InBlock.gif      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
InBlock.gif
InBlock.gif   if (!hWnd)
ExpandedSubBlockStart.gif   {
InBlock.gif      return FALSE;
ExpandedSubBlockEnd.gif   }

InBlock.gif
InBlock.gif   ShowWindow(hWnd, nCmdShow);
InBlock.gif   UpdateWindow(hWnd);
InBlock.gif
InBlock.gif   return TRUE;
ExpandedBlockEnd.gif}

None.gif
None.gifLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
ExpandedBlockStart.gif {
InBlock.gif    int wmId, wmEvent;
InBlock.gif    PAINTSTRUCT ps;
InBlock.gif    HDC hdc;
InBlock.gif
InBlock.gif    switch (message) 
ExpandedSubBlockStart.gif    {
InBlock.gif    case WM_COMMAND:
InBlock.gif        wmId    = LOWORD(wParam); 
InBlock.gif        wmEvent = HIWORD(wParam); 
InBlock.gif        // Parse the menu selections:
InBlock.gif
        switch (wmId)
ExpandedSubBlockStart.gif        {
InBlock.gif        case IDM_EXIT:

 I was told to do this. This may or may not be necessary.
None.gif        mRoot->detachRenderTarget(mRenderWindow);
None.gif            DestroyWindow(hWnd);
None.gif             break;
None.gif         default:
None.gif             return DefWindowProc(hWnd, message, wParam, lParam);
None.gif        }
None.gif         break;
None.gif     case WM_PAINT:
None.gif        hdc = BeginPaint(hWnd, &ps);
None.gif         //  TODO: Add any drawing code heredot.gif
None.gif

None.gif        EndPaint(hWnd, &ps);
None.gif         break;
None.gif     case WM_DESTROY:
None.gif 
None.gif        PostQuitMessage(0);
None.gif         break;

 Returning 1 will cause the screen not flicker when the window is being resized.
None.gif case WM_ERASEBKGND:
None.gif       return 1;

 Handle resizing the window. one of the things this program does not do is display full screen. This should be relatively simple to implement. Also the section is direct translation of the WxWindows code that was posted to forum.
None.gif case WM_SIZE:
None.gif         if (mCamera) 
ExpandedBlockStart.gif        
InBlock.gif            RECT rect; 
InBlock.gif            GetClientRect(hWnd,&rect); 
InBlock.gif
InBlock.gif            // notify "render window" instance 
InBlock.gif
            mRenderWindow->windowMovedOrResized(); 
InBlock.gif
InBlock.gif            // Adjust camera's aspect ratio, too 
InBlock.gif
            if ((rect.bottom - rect.top) != 0 && mCamera != 0) 
InBlock.gif                mCamera->setAspectRatio((Ogre::Real)mRenderWindow->getWidth() / (Ogre::Real)mRenderWindow->getHeight()); 
InBlock.gif            mCamera->yaw(Radian(0));
InBlock.gif            Root::getSingletonPtr()->renderOneFrame(); 
ExpandedBlockEnd.gif        }

None.gif
None.gif         break;
None.gif     default:
None.gif         return DefWindowProc(hWnd, message, wParam, lParam);
None.gif    }
None.gif     return 0;
None.gif}
None.gif
None.gif #endif
目录
相关文章
|
10月前
用IAR打开STM8时,出现“Unable to create configuration 'Debug' using tool chain ‘STM8’
用IAR打开STM8时,出现“Unable to create configuration 'Debug' using tool chain ‘STM8’
234 0
|
Java 开发工具 Android开发
Android Studio 解决:error adding symbols: File in wrong format clang++.exe: error: linker command...
错误日志: Error:FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:externalNativeBuildDebug'.
6399 0
|
11月前
Qt5Error:msvc-version.conf loaded but QMAKE_MSC_VER ins‘t set
Qt5Error:msvc-version.conf loaded but QMAKE_MSC_VER ins‘t set
224 0
|
C++
VS2010编译:_WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
VS2010编译:_WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
175 0
运行QtDesigner.exe报错:it could not find or load the Qt platform plugin “windows“
运行QtDesigner.exe报错:it could not find or load the Qt platform plugin “windows“
运行QtDesigner.exe报错:it could not find or load the Qt platform plugin “windows“
|
C语言
Qt Creator新安装后运行一个程序后,出现错误:Error while building/deploying project dict-qt (kit: Desktop Qt 5.10.0 MinGW 32bit) When executing step "qmake"
1、环境介绍:在windows10 Pro下,当前Qt Creator版本,如下图所示: 2、问题描述:当用Qt Creator新建一个工程后,按Ctrl + R 构建/部署时,出现问题,问题截图如下: 3、解决方案:这是由于Qt Creator打开的工程文件夹的绝对路径中存在中文字符,只需将工...
5660 0
|
新零售 测试技术 Python
Robot Framework - Variable file
RF导入变量文件 在Setting中导入 Setting中导入变量文件时,和导入外部资源文件类似。变量文件的路径可以包含参数,如果一个变量文件接受参数,那么它们也可以是变量。
1325 0