Simple Win32 Program

 

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

  
  
Render System = Direct3D9 Rendering Subsystem [ Direct3D9 Rendering Subsystem ] Allow NVPerfHUD = No Anti aliasing = None Floating-point mode = Fastest Full Screen = No Rendering Device = NVIDIA GeForce FX  5200 VSync = No Video Mode = 800  x  600  @  32 -bit colour [ OpenGL Rendering Subsystem ] Colour Depth = 32 Display Frequency = 60 FSAA = 0 Full Screen = Yes RTT Preferred Mode = FBO VSync = No Video Mode = 1024  x  768

Plugins.cfg

  
  
# Defines plugins to load # Define plugin folder PluginFolder = . # Define plugins Plugin = RenderSystem_Direct3D9

resources.cfg

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

stdafx.h

#pragma once


#define  WIN32_LEAN_AND_MEAN
#include 
< windows.h >
//  C RunTime Header Files
#include  < stdlib.h >
#include 
< malloc.h >
#include 
< memory.h >
#include 
< tchar.h >
#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.
//  ogre32.cpp : Defines the entry point for the application.
//

#include 
" stdafx.h "
#include 
" ogre32.h "
#define  MAX_LOADSTRING 100

//  Global Variables:
HINSTANCE hInst;             //  current instance
TCHAR szTitle[MAX_LOADSTRING];         //  The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];     //  the main window class name

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.

Root  * mRoot              =   0 ;   //  
SceneManager  * mSceneMgr  =   0 ;   //  
Camera  * mCamera          =   0 ;   //  
Viewport *  mViewPort      =   0
RenderWindow
*  mRenderWindow = 0

//  Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, 
int );
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int  APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     
int        nCmdShow)
{
     
// TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;
    HWND hWnd;
    
// Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_OGRE32, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    
    hInst 
= hInstance; // Store instance handle in our global variable

    hWnd 
= CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    
if (!hWnd)
    
{
        
return FALSE;
    }

create the root ogre system
mRoot  =   new  Root();

 load the configuration file why?
    ConfigFile cf;
    cf.load(
" resources.cfg " );

    ConfigFile::SectionIterator seci 
=  cf.getSectionIterator();

    String secName, typeName, archName;
    
while  (seci.hasMoreElements())
    
{
        secName 
= seci.peekNextKey();
        ConfigFile::SettingsMultiMap 
*settings = seci.getNext();
        ConfigFile::SettingsMultiMap::iterator i;
        
for (i = settings->begin(); i != settings->end(); ++i)
        
{
            typeName 
= i->first;
            archName 
= i->second;
            ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }

    }

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

        c
++// <-- oh how clever
    }

    
if ( ! foundit) 
        
return  FALSE;  // we didn't find it

    
// we found it, we might as well use it!
    mRoot -> setRenderSystem(selectedRenderSystem);

    selectedRenderSystem
-> setConfigOption( " Full Screen " , " No " );  
    selectedRenderSystem
-> setConfigOption( " Video Mode " , " 800 x 600 @ 16-bit colour " );

    
// retrieve the config option map
    ConfigOptionMap comap  =  selectedRenderSystem -> getConfigOptions();

    
// and now we need to run through all of it
    ConfigOptionMap::const_iterator start  =  comap.begin();
    ConfigOptionMap::const_iterator end 
=  comap.end();
    
while (start  !=  end)
    
{
        String OptionName 
= start->first;
        String CurrentValue 
= start->second.currentValue;
        StringVector PossibleValues 
= start->second.possibleValues;
        
int c=0;
        
while (c < (int) PossibleValues.size())
        
{
            String OneValue 
= PossibleValues.at(c);
            c
++;
        }

    start
++;
    }
    
    
// end boilerplate

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

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

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

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

 Create a camera so we can look at his lovely mug.
//  --------------------
    
//  Create the camera
    mCamera  =  mSceneMgr -> createCamera( " PlayerCam " );
    
//  Position it at 500 in Z direction
    mCamera -> setPosition(Ogre::Vector3( 0 , 0 , 500 ));
    
//  Look back along -Z
    mCamera -> lookAt(Ogre::Vector3( 0 , 0 , - 300 ));
    mCamera
-> setNearClipDistance( 5 );
    
//  Set the viewport
    mViewPort  =  mRenderWindow -> addViewport(mCamera);
    mViewPort
-> setBackgroundColour(Ogre::ColourValue( 0.0f 0.0f 0.0f 1.0f )); 

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    
    hAccelTable 
=  LoadAccelerators(hInstance, (LPCTSTR)IDC_OGRE32);

    
//  Main message loop:
     while  (GetMessage( & msg, NULL,  0 0 )) 
    
{       
                
//placing renderOneFrame seems to allow for a clean shutdown.
                
//thanks to user lakin for that hint.
        if (mRoot->renderOneFrame()) 
        
{
            TranslateMessage(
&msg);
            DispatchMessage(
&msg);
        }

    }


    
return  ( int ) msg.wParam;
}


ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize 
= sizeof(WNDCLASSEX); 

    wcex.style            
= CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    
= (WNDPROC)WndProc;
    wcex.cbClsExtra        
= 0;
    wcex.cbWndExtra        
= 0;
    wcex.hInstance        
= hInstance;
    wcex.hIcon            
= LoadIcon(hInstance, (LPCTSTR)IDI_OGRE32);
    wcex.hCursor        
= LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    
= (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    
= NULL;
    wcex.lpszClassName    
= szWindowClass;
    wcex.hIconSm        
= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    
return RegisterClassEx(&wcex);
}


BOOL InitInstance(HINSTANCE hInstance, 
int  nCmdShow)
{
   HWND hWnd;

   hInst 
= hInstance; // Store instance handle in our global variable

   hWnd 
= CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 
0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   
if (!hWnd)
   
{
      
return FALSE;
   }


   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   
return TRUE;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    
switch (message) 
    
{
    
case WM_COMMAND:
        wmId    
= LOWORD(wParam); 
        wmEvent 
= HIWORD(wParam); 
        
// Parse the menu selections:
        switch (wmId)
        
{
        
case IDM_EXIT:

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

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

 Returning 1 will cause the screen not flicker when the window is being resized.
case  WM_ERASEBKGND:
      
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.
case  WM_SIZE:
        
if  (mCamera) 
        

            RECT rect; 
            GetClientRect(hWnd,
&rect); 

            
// notify "render window" instance 
            mRenderWindow->windowMovedOrResized(); 

            
// Adjust camera's aspect ratio, too 
            if ((rect.bottom - rect.top) != 0 && mCamera != 0
                mCamera
->setAspectRatio((Ogre::Real)mRenderWindow->getWidth() / (Ogre::Real)mRenderWindow->getHeight()); 
            mCamera
->yaw(Radian(0));
            Root::getSingletonPtr()
->renderOneFrame(); 
        }


        
break ;
    
default :
        
return  DefWindowProc(hWnd, message, wParam, lParam);
    }
    
return   0 ;
}

#endif
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值