Esempio n. 1
0
static int luaEngineApplyScreenSettings(lua_State *L){
	script().syncFrom(NULL);

	if(conf->sizeX==conf->sizeXTEMP &&
		conf->sizeY==conf->sizeYTEMP &&
		conf->bitDepth==conf->bitDepthTEMP &&
		conf->windowed==conf->windowedTEMP){
		return 0;
	}

	ScreenMode fixed;
	fixed.x=conf->sizeXTEMP;
	fixed.y=conf->sizeYTEMP;
	fixed.bitDepth=conf->bitDepthTEMP;
	
	if(!conf->windowedTEMP){
		fixed=hardware.validateScreenMode(conf->sizeXTEMP,conf->sizeYTEMP,conf->bitDepthTEMP);
	}
	
	ChangeScreenResolution(fixed.x,fixed.y,fixed.bitDepth,!conf->windowedTEMP);
	
	conf->sizeX=fixed.x;
	conf->sizeY=fixed.y;
	conf->bitDepth=fixed.bitDepth;
	conf->windowed=conf->windowedTEMP;

	return 0;
}
Esempio n. 2
0
BOOL CreateWindowGL (GL_Window* window)									// This Code Creates Our OpenGL Window
{
	DWORD windowStyle = WS_OVERLAPPEDWINDOW;							// Define Our Window Style
	DWORD windowExtendedStyle = WS_EX_APPWINDOW;						// Define The Window's Extended Style

//Hide windows' mouse cursor
	//ShowCursor(FALSE);


	PIXELFORMATDESCRIPTOR pfd =											// pfd Tells Windows How We Want Things To Be
	{
		sizeof (PIXELFORMATDESCRIPTOR),									// Size Of This Pixel Format Descriptor
		1,																// Version Number
		PFD_DRAW_TO_WINDOW |											// Format Must Support Window
		PFD_SUPPORT_OPENGL |											// Format Must Support OpenGL
		PFD_DOUBLEBUFFER,												// Must Support Double Buffering
		PFD_TYPE_RGBA,													// Request An RGBA Format
		window->init.bitsPerPixel,										// Select Our Color Depth
		0, 0, 0, 0, 0, 0,												// Color Bits Ignored
		0,																// No Alpha Buffer
		0,																// Shift Bit Ignored
		0,																// No Accumulation Buffer
		0, 0, 0, 0,														// Accumulation Bits Ignored
		16,																// 16Bit Z-Buffer (Depth Buffer)  
		0,																// No Stencil Buffer
		0,																// No Auxiliary Buffer
		PFD_MAIN_PLANE,													// Main Drawing Layer
		0,																// Reserved
		0, 0, 0															// Layer Masks Ignored
	};

	RECT windowRect = {0, 0, window->init.width, window->init.height};	// Define Our Window Coordinates

	GLuint PixelFormat;													// Will Hold The Selected Pixel Format

	if (window->init.isFullScreen == TRUE)								// Fullscreen Requested, Try Changing Video Modes
	{
		if (ChangeScreenResolution (window->init.width, window->init.height, window->init.bitsPerPixel) == FALSE)
		{
			// Fullscreen Mode Failed.  Run In Windowed Mode Instead
			MessageBox (HWND_DESKTOP, "Mode Switch Failed.\nRunning In Windowed Mode.", "Error", MB_OK | MB_ICONEXCLAMATION);
			window->init.isFullScreen = FALSE;							// Set isFullscreen To False (Windowed Mode)
		}
		else															// Otherwise (If Fullscreen Mode Was Successful)
		{
			windowStyle = WS_POPUP;										// Set The WindowStyle To WS_POPUP (Popup Window)
			windowExtendedStyle |= WS_EX_TOPMOST;						// Set The Extended Window Style To WS_EX_TOPMOST
		}																// (Top Window Covering Everything Else)
	}
	else																// If Fullscreen Was Not Selected
	{
		// Adjust Window, Account For Window Borders
		AdjustWindowRectEx (&windowRect, windowStyle, 0, windowExtendedStyle);
	}

	// Create The OpenGL Window
	window->hWnd = CreateWindowEx (windowExtendedStyle,					// Extended Style
								   window->init.application->className,	// Class Name
								   window->init.title,					// Window Title
								   windowStyle,							// Window Style
								   0, 0,								// Window X,Y Position
								   windowRect.right - windowRect.left,	// Window Width
								   windowRect.bottom - windowRect.top,	// Window Height
								   HWND_DESKTOP,						// Desktop Is Window's Parent
								   0,									// No Menu
								   window->init.application->hInstance, // Pass The Window Instance
								   window);

	if (window->hWnd == 0)												// Was Window Creation A Success?
	{
		return FALSE;													// If Not Return False
	}

	window->hDC = GetDC (window->hWnd);									// Grab A Device Context For This Window
	if (window->hDC == 0)												// Did We Get A Device Context?
	{
		// Failed
		DestroyWindow (window->hWnd);									// Destroy The Window
		window->hWnd = 0;												// Zero The Window Handle
		return FALSE;													// Return False
	}

	PixelFormat = ChoosePixelFormat (window->hDC, &pfd);				// Find A Compatible Pixel Format
	if (PixelFormat == 0)												// Did We Find A Compatible Format?
	{
		// Failed
		ReleaseDC (window->hWnd, window->hDC);							// Release Our Device Context
		window->hDC = 0;												// Zero The Device Context
		DestroyWindow (window->hWnd);									// Destroy The Window
		window->hWnd = 0;												// Zero The Window Handle
		return FALSE;													// Return False
	}

	if (SetPixelFormat (window->hDC, PixelFormat, &pfd) == FALSE)		// Try To Set The Pixel Format
	{
		// Failed
		ReleaseDC (window->hWnd, window->hDC);							// Release Our Device Context
		window->hDC = 0;												// Zero The Device Context
		DestroyWindow (window->hWnd);									// Destroy The Window
		window->hWnd = 0;												// Zero The Window Handle
		return FALSE;													// Return False
	}

	window->hRC = wglCreateContext (window->hDC);						// Try To Get A Rendering Context
	if (window->hRC == 0)												// Did We Get A Rendering Context?
	{
		// Failed
		ReleaseDC (window->hWnd, window->hDC);							// Release Our Device Context
		window->hDC = 0;												// Zero The Device Context
		DestroyWindow (window->hWnd);									// Destroy The Window
		window->hWnd = 0;												// Zero The Window Handle
		return FALSE;													// Return False
	}

	// Make The Rendering Context Our Current Rendering Context
	if (wglMakeCurrent (window->hDC, window->hRC) == FALSE)
	{
		// Failed
		wglDeleteContext (window->hRC);									// Delete The Rendering Context
		window->hRC = 0;												// Zero The Rendering Context
		ReleaseDC (window->hWnd, window->hDC);							// Release Our Device Context
		window->hDC = 0;												// Zero The Device Context
		DestroyWindow (window->hWnd);									// Destroy The Window
		window->hWnd = 0;												// Zero The Window Handle
		return FALSE;													// Return False
	}

	ShowWindow (window->hWnd, SW_NORMAL);								// Make The Window Visible
	window->isVisible = TRUE;											// Set isVisible To True

	ReshapeGL (window->init.width, window->init.height);				// Reshape Our GL Window

	ZeroMemory (window->keys, sizeof (Keys));							// Clear All Keys

	window->lastTickCount = GetTickCount ();							// Get Tick Count

	return TRUE;														// Window Creating Was A Success
																		// Initialization Will Be Done In WM_CREATE
}
Esempio n. 3
0
BOOL WindowFrame::CreateWindowGL (GL_Window* window)									
{
	DWORD windowStyle = WS_OVERLAPPEDWINDOW;							// 设置窗口类型为一般的弹出式窗口
	DWORD windowExtendedStyle = WS_EX_APPWINDOW;						// 设置窗口的扩展属性

	PIXELFORMATDESCRIPTOR pfd =											// pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
	{																	
		sizeof (PIXELFORMATDESCRIPTOR),									// 上述格式描述符的大小
		1,																// 版本号
		PFD_DRAW_TO_WINDOW |											// 格式支持窗口
		PFD_SUPPORT_OPENGL |											// 格式必须支持OpenGL
		PFD_DOUBLEBUFFER,												// 必须支持双缓冲
		PFD_TYPE_RGBA,													// 申请 RGBA 格式
		window->init.bitsPerPixel,										// 选定色彩深度
		0, 0, 0, 0, 0, 0,												// 忽略的色彩位
		0,																// 无Alpha缓存
		0,																// 忽略Shift Bit
		0,																// 无累加缓存
		0, 0, 0, 0,														// 忽略聚集位
		16,																// 16位 Z-缓存 (深度缓存) 
		0,																// 无蒙板缓存
		0,																// 无辅助缓存
		PFD_MAIN_PLANE,													// 主绘图层
		0,																// 不使用重叠层
		0, 0, 0															// 忽略层遮罩
	};

	RECT windowRect = {0, 0, window->init.width, window->init.height};	// 记录窗口的大小

	GLuint PixelFormat;													// 将保存的像素格式

	if (window->isFullScreen == TRUE)								    // 如果为全屏模式
	{
		if (ChangeScreenResolution (window->init.width, window->init.height, window->init.bitsPerPixel) == FALSE)
		{			
			MessageBox (HWND_DESKTOP, "模式切换失败\n在窗口模式下运行", "错误", MB_OK | MB_ICONEXCLAMATION);
			window->isFullScreen = FALSE;							    // 设置isFullscreen为False
		}		
		else															
		{
			ShowCursor(FALSE);											// 不显示光标
			windowStyle = WS_POPUP;										// 设置窗口模式为弹出式窗口
			windowExtendedStyle |= WS_EX_TOPMOST;						// 设置窗口的扩展模式为最顶层窗口
		}																
	}
	else																// 如果不为全屏模式
	{		
		AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle); //调整窗口大小,以容纳边框等窗口部件
	}
	
	window->hWnd = CreateWindowEx(windowExtendedStyle,					// 扩展窗体风格
								   window->init.application->className,	// 类名字
								   window->init.title,					// 窗口标题
								   windowStyle,							// 必须的窗体风格属性
								   0, 0,								// 窗口位置
								   windowRect.right - windowRect.left,	// 计算调整好的窗口宽度
								   windowRect.bottom - windowRect.top,	// 计算调整好的窗口高度
								   HWND_DESKTOP,						// 无父窗口
								   0,									// 无菜单
								   window->init.application->hInstance, // 实例
								   window);								// 向window的WM_CREATE传递window结构
																		
	if (window->hWnd == 0)												// 窗口创建是否成功	
	{
		return FALSE;													// 不成功则返回
	}

	window->hDC = GetDC (window->hWnd);									// 返回设备描述表
	if (window->hDC == 0)												// 是否成功获得设备描述表
	{		
		DestroyWindow (window->hWnd);									// 删除窗口
		window->hWnd = 0;												// 设置窗口句柄为0
		return FALSE;													// 返回失败
	}

	PixelFormat = ChoosePixelFormat (window->hDC, &pfd);				// 选择一种相容的像素格式
	if (PixelFormat == 0)												// 是否获得相容的像素格式
	{		
		ReleaseDC (window->hWnd, window->hDC);							// 释放设备描述表
		window->hDC = 0;												// 设置窗口设备描述表为0
		DestroyWindow (window->hWnd);									// 删除窗口
		window->hWnd = 0;												// 设置窗口句柄为0
		return FALSE;													// 返回错误
	}

	if (SetPixelFormat (window->hDC, PixelFormat, &pfd) == FALSE)		// 设置像素格式
	{		
		ReleaseDC (window->hWnd, window->hDC);							// 释放设备描述表
		window->hDC = 0;												// 设置窗口设备描述表为0
		DestroyWindow (window->hWnd);									// 删除窗口
		window->hWnd = 0;												// 设置窗口句柄为0
		return FALSE;													// 返回错误
	}

	window->hRC = wglCreateContext (window->hDC);						// 设置OpenGL渲染描述表
	if (window->hRC == 0)												// 如果没有成功创建
	{
		ReleaseDC (window->hWnd, window->hDC);							// 释放设备描述表
		window->hDC = 0;												// 设置窗口设备描述表为0
		DestroyWindow (window->hWnd);									// 删除窗口
		window->hWnd = 0;												// 设置窗口句柄为0
		return FALSE;													// 返回错误
	}

	if (wglMakeCurrent (window->hDC, window->hRC) == FALSE)				// 设置RC为当前的OpenGL的渲染描述表
	{
		wglDeleteContext (window->hRC);									// 删除当前的OpenGL渲染描述表
		window->hRC = 0;												// 释放设备描述表
		ReleaseDC (window->hWnd, window->hDC);							// 设置窗口设备描述表为0
		window->hDC = 0;												// 删除窗口
		DestroyWindow (window->hWnd);									// 设置窗口句柄为0
		window->hWnd = 0;												// 返回错误
		return FALSE;													
	}

	ShowWindow (window->hWnd, SW_NORMAL);								// 显示窗口
	window->isVisible = TRUE;											// 设置窗口为可见

	ReshapeGL (window->init.width, window->init.height);				// 根据窗口大小,调整OpenGL对应的窗口大小
	ZeroMemory (window->keys, sizeof (Keys));							// 初始化按键记录表	

	return TRUE;														// 窗口创建完毕,成功返回																		
}
/*
    PsychOSOpenOnscreenWindow()
    
    Creates the pixel format and the context objects and then instantiates the context onto the screen.
    
    -The pixel format and the context are stored in the target specific field of the window recored.  Close
    should clean up by destroying both the pixel format and the context.
    
    -We mantain the context because it must be be made the current context by drawing functions to draw into 
    the specified window.
    
    -We maintain the pixel format object because there seems to be now way to retrieve that from the context.
    
    -To tell the caller to clean up PsychOSOpenOnscreenWindow returns FALSE if we fail to open the window. It 
    would be better to just issue an PsychErrorExit() and have that clean up everything allocated outside of
    PsychOpenOnscreenWindow().
*/
boolean PsychOSOpenOnscreenWindow(PsychScreenSettingsType *screenSettings, PsychWindowRecordType *windowRecord, int numBuffers, int stereomode, int conserveVRAM)
{
  RECT winRec;
  PsychRectType             screenrect;
  CGDirectDisplayID         cgDisplayID;
  int         pf;
  unsigned int nNumFormats;
  HDC         hDC;
  HWND        hWnd;
  WNDCLASS    wc;
  PIXELFORMATDESCRIPTOR pfd;
  int         attribs[48];
  int         attribcount;
  float       fattribs[2]={0,0};
  int x, y, width, height, i, bpc;
  GLenum      glerr;
  DWORD flags;
  boolean fullscreen = FALSE;
  DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  // The WS_EX_NOACTIVATE flag prevents the window from grabbing keyboard focus. That way,
  // the new Java-GetChar can do its job.
  DWORD windowExtendedStyle = WS_EX_APPWINDOW | 0x08000000; // const int WS_EX_NOACTIVATE = 0x08000000;

	 // Init to safe default:
    windowRecord->targetSpecific.glusercontextObject = NULL;
    
    // Map the logical screen number to a device handle for the corresponding
    // physical display device: CGDirectDisplayID is currently typedef'd to a
    // HDC windows hardware device context handle.
    PsychGetCGDisplayIDFromScreenNumber(&cgDisplayID, screenSettings->screenNumber);

    // Check if this should be a fullscreen window:
    PsychGetScreenRect(screenSettings->screenNumber, screenrect);
    if (PsychMatchRect(screenrect, windowRecord->rect)) {
      // This is supposed to be a fullscreen window with the dimensions of
      // the current display/desktop:
      // Switch system to fullscreen-mode without changing any settings:
      fullscreen = ChangeScreenResolution(screenSettings->screenNumber, 0, 0, 0, 0);
    }
    else {
      // Window size different from current screen size:
      // A regular desktop window with borders and control icons is requested, e.g., for debugging:
      fullscreen = FALSE;
    }

	 // Special case for explicit multi-display setup under Windows when opening a window on
	 // screen zero. We enforce the fullscreen - flag, aka a borderless top level window. This way,
    // if anything of our automatic full-desktop window emulation code goes wrong on exotic setups,
    // the user can still enforce a suitably positioned and sized borderless toplevel window.
    if (PsychGetNumDisplays()>2 && screenSettings->screenNumber == 0) fullscreen = TRUE;

    if (fullscreen) {
      windowStyle = WS_POPUP;		      // Set The WindowStyle To WS_POPUP (Popup Window without borders)
      windowExtendedStyle |= WS_EX_TOPMOST;   // Set The Extended Window Style To WS_EX_TOPMOST
    }
    else {
      windowStyle |= WS_OVERLAPPEDWINDOW;
      windowExtendedStyle |= WS_EX_TOPMOST;   // Set The Extended Window Style To WS_EX_TOPMOST
    }

    // Define final position and size of window:
    x=windowRecord->rect[kPsychLeft];
    y=windowRecord->rect[kPsychTop];
    width=PsychGetWidthFromRect(windowRecord->rect);
    height=PsychGetHeightFromRect(windowRecord->rect);

    // Register our own window class for Psychtoolbox onscreen windows:
    // Only register the window class once - use hInstance as a flag.
    if (!hInstance) {
      hInstance = GetModuleHandle(NULL);
      wc.style         = CS_OWNDC;
      wc.lpfnWndProc   = WndProc;
      wc.cbClsExtra    = 0;
      wc.cbWndExtra    = 0;
      wc.hInstance     = hInstance;
      wc.hIcon         = LoadIcon(hInstance, IDI_WINLOGO);
      wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
      wc.hbrBackground = NULL;
      wc.lpszMenuName  = NULL;
      wc.lpszClassName = "PTB-OpenGL";

      if (!RegisterClass(&wc)) {
		  hInstance = 0;
        printf("\nPTB-ERROR[Register Windowclass failed]: Unknown error, Win32 specific.\n\n");
        return(FALSE);
      }
    }

    //if (PSYCH_DEBUG == PSYCH_ON) printf("Creating Window...\n");

    // Adjust window bounds to account for the window borders if we are in non-fullscreen mode:
    if (!fullscreen) {
      winRec.left=x; winRec.top=y; winRec.right=x+width; winRec.bottom=y+height;
      AdjustWindowRectEx(&winRec, windowStyle, 0, windowExtendedStyle);
      x=winRec.left; y=winRec.top; width=winRec.right - winRec.left; height=winRec.bottom - winRec.top;
    }

    // Window class registered: Create a window of this class with some specific properties:
    hWnd = CreateWindowEx(windowExtendedStyle,
			  "PTB-OpenGL",
			  "PTB Onscreen window",
			  windowStyle,
			  x, y, width, height, NULL, NULL, hInstance, NULL);

    if (hWnd == NULL) {
        printf("\nPTB-ERROR[CreateWindow() failed]: Unknown error, Win32 specific.\n\n");
        return(FALSE);
    }

    // Retrieve device context for the window:
    hDC = GetDC(hWnd);

    // Setup optional flags for pixelformat:
    flags = 0;
    // Init pfd to zero:
    memset(&pfd, 0, sizeof(pfd));
    attribcount = 0;

    attribs[attribcount++]=0x2001; // WGL_DRAW_TO_WINDOW_ARB
    attribs[attribcount++]=GL_TRUE;
    attribs[attribcount++]=0x2010; // WGL_SUPPORT_OPENGL_ARB
    attribs[attribcount++]=GL_TRUE;
    attribs[attribcount++]=0x2007; // WGL_SWAP_METHOD_ARB
    attribs[attribcount++]=0x2028; // WGL_SWAP_EXCHANGE_ARB
    attribs[attribcount++]=0x2013; // WGL_PIXEL_TYPE_ARB
    
    // Select either floating point or fixed point framebuffer:
    if (windowRecord->depth == 64 || windowRecord->depth == 128) {
      // Request a floating point drawable instead of a fixed-point one:
      attribs[attribcount++]=WGL_TYPE_RGBA_FLOAT_ARB;
    }
    else {
      // Request standard fixed point drawable:
      attribs[attribcount++]=0x202B; // WGL_TYPE_RGBA_ARB
    }
    
    // Select requested depth per color component 'bpc' for each channel:
    bpc = 8; // We default to 8 bpc == RGBA8
    if (windowRecord->depth == 30)  { bpc = 10; printf("PTB-INFO: Trying to enable at least 10 bpc fixed point framebuffer.\n"); }
    if (windowRecord->depth == 64)  { bpc = 16; printf("PTB-INFO: Trying to enable 16 bpc floating point framebuffer.\n"); }
    if (windowRecord->depth == 128) { bpc = 32; printf("PTB-INFO: Trying to enable 32 bpc floating point framebuffer.\n"); }
    
    // Set up color depth for each channel:
    attribs[attribcount++]=WGL_RED_BITS_ARB;
    attribs[attribcount++]=bpc;
    attribs[attribcount++]=WGL_GREEN_BITS_ARB;
    attribs[attribcount++]=bpc;
    attribs[attribcount++]=WGL_BLUE_BITS_ARB;
    attribs[attribcount++]=bpc;
    attribs[attribcount++]=WGL_ALPHA_BITS_ARB;
    // Alpha channel has only 2 bpc in the fixed point bpc=10 case, i.e. RGBA=8882.
    attribs[attribcount++]=(bpc == 10) ? 2 : bpc;
    
    
    // Stereo display support: If stereo display output is requested with OpenGL native stereo,
    // we request a stereo-enabled rendering context.
    if(stereomode==kPsychOpenGLStereo) {
      flags = flags | PFD_STEREO;
      attribs[attribcount++]=0x2012; // WGL_STEREO_ARB
      attribs[attribcount++]=GL_TRUE;
    }
    
    // Double buffering requested?
    if(numBuffers>=2) {
      // Enable double-buffering:
      flags = flags | PFD_DOUBLEBUFFER;
      attribs[attribcount++]=0x2011; // WGL_DOUBLE_BUFFER_ARB
      attribs[attribcount++]=GL_TRUE;
      
      // AUX buffers for Flip-Operations needed?
      if ((conserveVRAM & kPsychDisableAUXBuffers) == 0) {
	// Allocate one or two (mono vs. stereo) AUX buffers for new "don't clear" mode of Screen('Flip'):
	// Not clearing the framebuffer after "Flip" is implemented by storing a backup-copy of
	// the backbuffer to AUXs before flip and restoring the content from AUXs after flip.
	pfd.cAuxBuffers=(stereomode==kPsychOpenGLStereo || stereomode==kPsychCompressedTLBRStereo || stereomode==kPsychCompressedTRBLStereo) ? 2 : 1;
	attribs[attribcount++]=0x2024; // WGL_AUX_BUFFERS_ARB
	attribs[attribcount++]=pfd.cAuxBuffers;
      }
    }
    
    //if (PSYCH_DEBUG == PSYCH_ON) printf("Device context is %p\n", hDC);
    
    // Build pixelformat descriptor:
    pfd.nSize        = sizeof(pfd);
    pfd.nVersion     = 1;
    pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_SWAP_EXCHANGE |flags;  // Want OpenGL capable window with bufferswap via page-flipping...
    pfd.iPixelType   = PFD_TYPE_RGBA; // Want a RGBA pixel format.
    pfd.cColorBits   = 32;            // 32 bpp at least...
    pfd.cAlphaBits   = 8;             // Want a 8 bit alpha-buffer.
    
    // Support for OpenGL 3D rendering requested?
    if (PsychPrefStateGet_3DGfx()) {
      // Yes. Allocate and attach a 24bit depth buffer and 8 bit stencil buffer:
      pfd.cDepthBits = 24;
      pfd.cStencilBits = 8;
      attribs[attribcount++]=0x2022; // WGL_DEPTH_BITS_ARB
      attribs[attribcount++]=24;
      attribs[attribcount++]=0x2023; // WGL_STENCIL_BITS_ARB
      attribs[attribcount++]=8;
    }
    
    // Multisampled Anti-Aliasing requested?
    if (windowRecord->multiSample > 0) {
      // Request a multisample buffer:
      attribs[attribcount++]= 0x2041; // WGL_SAMPLE_BUFFERS_ARB
      attribs[attribcount++]= 1;
      // Request at least multiSample samples per pixel:
      attribs[attribcount++]= 0x2042; // WGL_SAMPLES_ARB
      attribs[attribcount++]= windowRecord->multiSample;
    }
    
    // Finalize attribs-array:
    attribs[attribcount++]= 0;
    
    //if (PSYCH_DEBUG == PSYCH_ON) printf("Choosing pixelformat\n");
    
    // Create pixelformat:
    // This is typical Microsoft brain-damage: We first need to create a window the
    // conventional old way just to be able to get a handle to the new wglChoosePixelFormat
    // method, which will us - after destroying and recreating the new window - allow to
    // select the pixelformat we actually want!
    
    // Step 1: Choose pixelformat old-style:
    pf = ChoosePixelFormat(hDC, &pfd);
    
    // Do we have a valid pixelformat?
    if (pf == 0) {
      // Nope. We give up!
      ReleaseDC(hDC, hWnd);
      DestroyWindow(hWnd);      
      printf("\nPTB-ERROR[ChoosePixelFormat() failed]: Unknown error, Win32 specific.\n\n");
      return(FALSE);
    }
    
    // Yes. Set it:
    if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
      ReleaseDC(hDC, hWnd);
      DestroyWindow(hWnd);      
      
      printf("\nPTB-ERROR[SetPixelFormat() failed]: Unknown error, Win32 specific.\n\n");
      return(FALSE);
    }
    
    // Ok, create and attach the rendering context.
    windowRecord->targetSpecific.contextObject = wglCreateContext(hDC);
    if (windowRecord->targetSpecific.contextObject == NULL) {
      ReleaseDC(hDC, hWnd);
      DestroyWindow(hWnd);
      
      printf("\nPTB-ERROR:[Context creation failed] Unknown, Win32 specific.\n\n");
      return(FALSE);
    }
    
    // Store the handles...
    windowRecord->targetSpecific.windowHandle = hWnd;
    windowRecord->targetSpecific.deviceContext = hDC;
    
    // Activate the rendering context:
    PsychOSSetGLContext(windowRecord);
    
    // Ok, the OpenGL rendering context is up and running. Auto-detect and bind all
    // available OpenGL extensions via GLEW:
    glerr = glewInit();
    if (GLEW_OK != glerr)
      {
	/* Problem: glewInit failed, something is seriously wrong. */
	printf("\nPTB-ERROR[GLEW init failed: %s]: Please report this to the forum. Will try to continue, but may crash soon!\n\n", glewGetErrorString(glerr));
	fflush(NULL);
      }
    else {
      if (PsychPrefStateGet_Verbosity()>4) printf("PTB-INFO: Using GLEW version %s for automatic detection of OpenGL extensions...\n", glewGetString(GLEW_VERSION));
    }
    
    DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
    
    if ((stereomode==kPsychOpenGLStereo) && ((pfd.dwFlags & PFD_STEREO)==0)) {
      // Ooops. Couldn't get the requested stereo-context from hardware :(
      ReleaseDC(hDC, hWnd);
      DestroyWindow(hWnd);
      
      printf("PTB-ERROR: OpenGL native stereo mode unavailable. Your hardware may not support it,\n"
	     "PTB-ERROR: or at least not on a flat-panel? Expect abortion of your script soon...");
      
      return(FALSE);
    }
    
	// Special debug override for faulty drivers with non-working extension:
	if (conserveVRAM & kPsychOverrideWglChoosePixelformat) wglChoosePixelFormatARB = NULL;

	// Step 2: Ok, we have an OpenGL rendering context with all known extensions bound:
	// Do we have (or want) support for wglChoosePixelFormatARB?
   // We skip use of it if we can do without it, i.e., when we don't need unusual framebuffer
   // configs (like non 8bpc fixed) and we don't need multisampling. This is a work-around
   // for hardware that has trouble (=driver bugs) with wglChoosePixelformat() in some modes, e.g., the NVidia
	// Quadro gfx card, which fails to enable quad-buffered stereo when using wglChoosePixelformat(),
	// but does so perfectly well when using the old-style ChoosePixelFormat(). 
	if ((wglChoosePixelFormatARB == NULL) || ((bpc==8) && (windowRecord->multiSample <= 0))) {
	  // Failed (==NULL) or disabled via override.
	  if ((wglChoosePixelFormatARB == NULL) && (PsychPrefStateGet_Verbosity() > 1)) printf("PTB-WARNING: Could not bind wglChoosePixelFormat - Extension. Some features will be unavailable, e.g., Anti-Aliasing and high precision framebuffers.\n");
	}
	else {
	  // Supported. We destroy the rendering context and window, then recreate it with
	  // the wglChoosePixelFormat - method...
	  wglMakeCurrent(NULL, NULL);

	  // Delete rendering context:
	  wglDeleteContext(windowRecord->targetSpecific.contextObject);
	  windowRecord->targetSpecific.contextObject=NULL;

      // Release device context:
      ReleaseDC(windowRecord->targetSpecific.deviceContext, windowRecord->targetSpecific.windowHandle);
      windowRecord->targetSpecific.deviceContext=NULL;

   	// Close & Destroy the window:
      DestroyWindow(windowRecord->targetSpecific.windowHandle);
      windowRecord->targetSpecific.windowHandle=NULL;

		// Ok, old window and stuff is dead. Create new window:
    	hWnd = CreateWindowEx(windowExtendedStyle, "PTB-OpenGL", "PTB Onscreen window", windowStyle,
			  						 x, y, width, height, NULL, NULL, hInstance, NULL);
    	if (hWnd == NULL) {
        printf("\nPTB-ERROR[CreateWindow() - II failed]: Unknown error, Win32 specific.\n\n");
        return(FALSE);
    	}

	   // Retrieve device context for the window:
    	hDC = GetDC(hWnd);

		pf = 0;
		nNumFormats=0;
		wglChoosePixelFormatARB(hDC, &attribs[0], NULL, 1, &pf, &nNumFormats);
      if (nNumFormats==0 && windowRecord->multiSample > 0) {
		 	// Failed. Probably due to too demanding multisample requirements: Lets lower them...
			for (i=0; i<attribcount && attribs[i]!=0x2042; i++);
			// Reduce requested number of samples/pixel and retry until we get one:
			while (nNumFormats==0 && windowRecord->multiSample > 0) {
				// printf("Failed for multisampling level %i nNum=%i\n", windowRecord->multiSample, nNumFormats);
				attribs[i+1]--;
	  			windowRecord->multiSample--;
				wglChoosePixelFormatARB(hDC, &attribs[0], NULL, 1, &pf, &nNumFormats);
			}
			// If we still do not get one with 0 samples per pixel, we can try to disable
			// multisampling completely:
			if (windowRecord->multiSample == 0 && nNumFormats==0) {
				// printf("Failed for multisampling level %i nNum=%i --> Disabling multisampling...\n", windowRecord->multiSample, nNumFormats);
				// We 0-Out all entries related to multi-sampling, including the
				// GL_SAMPLES_ARB and GL_SAMPLE_BUFFERS_ARB enums themselves:
				for (i=0; i<attribcount && attribs[i]!=0x2042; i++);
	  			attribs[i]=0;
	  			for (i=0; i<attribcount && attribs[i]!=0x2041; i++);
	  			attribs[i]=0;
	  			attribs[i+1]=0;
				wglChoosePixelFormatARB(hDC, &attribs[0], NULL, 1, &pf, &nNumFormats);
			}
      }

		if (nNumFormats==0 && numBuffers>=2) {
			// We still don't have a valid pixelformat, but double-buffering is enabled.
			// Let's try if we get one if we do not request any AUX-Buffers:
			for (i=0; i<attribcount && attribs[i]!=0x2024; i++);
			attribs[i+1] = 0; // Zero AUX-Buffers requested.
			wglChoosePixelFormatARB(hDC, &attribs[0], NULL, 1, &pf, &nNumFormats);
		}

		if (nNumFormats==0 && numBuffers>=2) {
			// We still don't have a valid pixelformat, but double-buffering is enabled.
			// Let's try if we get one if we do not request SWAP_EXCHANGED double buffering anymore:
			for (i=0; i<attribcount && attribs[i]!=0x2028; i++);
			attribs[i] = 0x202A; // WGL_SWAP_UNDEFINED_ARB
			wglChoosePixelFormatARB(hDC, &attribs[0], NULL, 1, &pf, &nNumFormats);
		}

		// Either we have a multisampled or non-multisampled format, or none. If we failed,
		// then we can not do anything anymore about it.

	   // Do we have a valid pixelformat?
      if (nNumFormats == 0) {
		   // Nope. We give up!
         ReleaseDC(hDC, hWnd);
         DestroyWindow(hWnd);      
         printf("\nPTB-ERROR[wglChoosePixelFormat() failed]: Unknown error, Win32 specific. Code: %i.\n\n", GetLastError());
         return(FALSE);
      }

      // Yes. Set it:
      if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
         ReleaseDC(hDC, hWnd);
         DestroyWindow(hWnd);      

         printf("\nPTB-ERROR[SetPixelFormat() - II failed]: Unknown error, Win32 specific.\n\n");
         return(FALSE);
      }

      // Ok, create and attach the rendering context.
      windowRecord->targetSpecific.contextObject = wglCreateContext(hDC);
      if (windowRecord->targetSpecific.contextObject == NULL) {
         ReleaseDC(hDC, hWnd);
         DestroyWindow(hWnd);

         printf("\nPTB-ERROR:[Context creation II failed] Unknown, Win32 specific.\n\n");
         return(FALSE);
      }
    
      // Store the handles...
      windowRecord->targetSpecific.windowHandle = hWnd;
      windowRecord->targetSpecific.deviceContext = hDC;

      // Activate the rendering context:
      PsychOSSetGLContext(windowRecord);

      DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

      if ((stereomode==kPsychOpenGLStereo) && ((pfd.dwFlags & PFD_STEREO)==0)) {
         // Ooops. Couldn't get the requested stereo-context from hardware :(
         ReleaseDC(hDC, hWnd);
         DestroyWindow(hWnd);

         printf("PTB-ERROR: OpenGL native stereo mode unavailable. Your hardware may not support it,\n"
	             "PTB-ERROR: or at least not on a flat-panel? Expect abortion of your script soon...");

         return(FALSE);
      }		
		// Done with final window and OpenGL context setup. We've got our final context enabled.
	 }

	 // Enable multisampling if this was requested:
    if (windowRecord->multiSample > 0) glEnable(0x809D); // 0x809D == GL_MULTISAMPLE_ARB
	 // Throw away any error-state this could have created on old hardware...
	 glGetError();

    // External 3D graphics support enabled? Or OpenGL quad-buffered stereo enabled?
	 // For the former, we need this code for OpenGL state isolation. For the latter we
    // need this code as workaround for Windows brain-damage. For some reason it helps
    // to properly shutdown stereo contexts on Windows...
	 if (PsychPrefStateGet_3DGfx() || stereomode == kPsychOpenGLStereo) {
		// Yes. We need to create an extra OpenGL rendering context for the external
		// OpenGL code to provide optimal state-isolation. The context shares all
		// heavyweight ressources likes textures, FBOs, VBOs, PBOs, display lists and
		// starts off as an identical copy of PTB's context as of here.
      windowRecord->targetSpecific.glusercontextObject = wglCreateContext(hDC);
		if (windowRecord->targetSpecific.glusercontextObject == NULL) {
         ReleaseDC(hDC, hWnd);
         DestroyWindow(hWnd);
			printf("\nPTB-ERROR[UserContextCreation failed]: Creating a private OpenGL context for Matlab OpenGL failed for unknown reasons.\n\n");
			return(FALSE);
		}

		wglMakeCurrent(windowRecord->targetSpecific.deviceContext, windowRecord->targetSpecific.glusercontextObject);
		wglMakeCurrent(windowRecord->targetSpecific.deviceContext, windowRecord->targetSpecific.contextObject);

		// Copy full state from our main context:
		if(!wglCopyContext(windowRecord->targetSpecific.contextObject, windowRecord->targetSpecific.glusercontextObject, GL_ALL_ATTRIB_BITS)) {
			// This is ugly, but not fatal...
			if (PsychPrefStateGet_Verbosity()>1) {
				printf("\nPTB-WARNING[wglCopyContext for user context failed]: Copying state to private OpenGL context for Matlab OpenGL failed for unknown reasons.\n\n");
			}
		}

	   // Enable ressource sharing with master context for this window:
		if (!wglShareLists(windowRecord->targetSpecific.contextObject, windowRecord->targetSpecific.glusercontextObject)) {
			// This is ugly, but not fatal...
			if (PsychPrefStateGet_Verbosity()>1) {
				printf("\nPTB-WARNING[wglShareLists for user context failed]: Ressource sharing with private OpenGL context for Matlab OpenGL failed for unknown reasons.\n\n");
			}		
		}

	 }

    // Finally, show our new window:
    ShowWindow(hWnd, SW_SHOW);

    // Give it higher priority than other applications windows:
    // Disabled: Interferes with JAVA-GetChar: SetForegroundWindow(hWnd);

    // Set the focus on it:
    // Disabled: Interferes with JAVA-GetChar: SetFocus(hWnd);

    // Capture the window if it is a fullscreen one: This window will receive all
    // mouse move and mouse button press events. Important for GetMouse() to work
    // properly...
    if (fullscreen) SetCapture(hWnd);

    // Increase our own open window counter:
    win32_windowcount++;

    // Some info for the user regarding non-fullscreen and ATI hw:
    if (!fullscreen && (strstr(glGetString(GL_VENDOR), "ATI"))) {
      printf("PTB-INFO: Some ATI graphics cards may not support proper syncing to vertical retrace when\n");
      printf("PTB-INFO: running in windowed mode (non-fullscreen). If PTB aborts with 'Synchronization failure'\n");
      printf("PTB-INFO: you can disable the sync test via call to Screen('Preference', 'SkipSyncTests', 1); .\n");
      printf("PTB-INFO: You won't get proper stimulus onset timestamps though, so windowed mode may be of limited use.\n");
    }

    // Dynamically bind the VSYNC extension:
    //if (strstr(glGetString(GL_EXTENSIONS), "WGL_EXT_swap_control")) {
      // Bind it:
      // wglSwapIntervalEXT=(PFNWGLEXTSWAPCONTROLPROC) wglGetProcAddress("wglSwapIntervalEXT");
    //}
    //else {
	 if (wglSwapIntervalEXT == NULL) {
      wglSwapIntervalEXT = NULL;
      printf("PTB-WARNING: Your graphics driver doesn't allow me to control syncing wrt. vertical retrace!\n");
      printf("PTB-WARNING: Please update your display graphics driver as soon as possible to fix this.\n");
      printf("PTB-WARNING: Until then, you can manually enable syncing to VBL somewhere in the display settings\n");
      printf("PTB-WARNING: tab of your machine.\n");
    }

    // Ok, we should be ready for OS independent setup...

    //printf("\nPTB-INFO: Low-level (Windoze) setup of onscreen window finished!\n");
    //fflush(NULL);

    // Well Done!
    return(TRUE);
}
Esempio n. 5
0
BOOL CreateWindowGL(GL_Window* window)									// 建立OpenGL窗口
{
	DWORD windowStyle = WS_OVERLAPPEDWINDOW;							// 设置窗口样式
	DWORD windowExtendedStyle = WS_EX_APPWINDOW;						// 设置窗口扩展样式

	PIXELFORMATDESCRIPTOR pfd =											// 像素格式描述符(pfd)的设置
	{
		sizeof(PIXELFORMATDESCRIPTOR),									// 像素的尺寸
		1,																// 版本号
		PFD_DRAW_TO_WINDOW |											// pfd必须支持窗口绘制
		PFD_SUPPORT_OPENGL |											// pfd必须支持OpenGL
		PFD_DOUBLEBUFFER,												// pfd必须支持双缓存
		PFD_TYPE_RGBA,													// 像素格式为RGBA
		window->init.bitsPerPixel,										// 设置颜色深度
		0, 0, 0, 0, 0, 0,												// 忽略颜色位数
		0,																// 无Alpha缓存
		0,																// 忽略偏移位
		0,																// 无累积缓存
		0, 0, 0, 0,														// 忽略累积缓存位 
		16,																// 深度缓存为16位 
		0,																// 无模板缓存
		0,																// 无辅助缓存
		PFD_MAIN_PLANE,													// 主要绘制层
		0,																// 保留位
		0, 0, 0															// 忽略层遮罩
	};

	RECT windowRect = {0, 0, window->init.width, window->init.height};	// 定义窗口大小

	GLuint PixelFormat;													// 保存像素格式

	if (window->init.isFullScreen == TRUE)								// 切换全屏
	{
		if (ChangeScreenResolution(window->init.width, window->init.height, window->init.bitsPerPixel) == FALSE)
		{
			// 全屏切换失败
			MessageBox(HWND_DESKTOP, "无法切换到全屏模式,在窗口模式下运行.\nMode Switch Failed,Running In Windowed Mode.", "Error", MB_OK | MB_ICONEXCLAMATION);
			window->init.isFullScreen = FALSE;							// 设置 isFullscreen 为FALSE
		}
		else															// 全屏切换成功
		{
			ShowCursor (FALSE);											// 隐藏鼠标
			windowStyle = WS_POPUP;										// 设置窗口样式
			windowExtendedStyle |= WS_EX_TOPMOST;						// 设置窗口扩展样式
		}
	}
	else
	{
		// 调整窗口大小,包括窗口边界
		AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle);
	}

	// 开始创建 OpenGL 窗口
	window->hWnd = CreateWindowEx(windowExtendedStyle,					// 窗口扩展样式
		window->init.application->className,// 应用程序类名
		window->init.title,					// 窗口标题
		windowStyle,						// 窗口样式
		0, 0,								// 窗口的 X,Y 坐标位置
		windowRect.right - windowRect.left,	// 窗口宽度
		windowRect.bottom - windowRect.top,	// 窗口高度
		HWND_DESKTOP,						// 父窗口为桌面
		0,									// 无菜单
		window->init.application->hInstance,// 传入应用程序实例 
		window);

	if (window->hWnd == 0)												// 窗口是否成功创建
	{
		return FALSE;													// 若失败,则返回FALSE
	}

	window->hDC = GetDC(window->hWnd);									// 取得当前窗口的设备描述表
	if (window->hDC == 0)												// 若未得到设备描述表
	{
		DestroyWindow(window->hWnd);									// 销毁该窗口
		window->hWnd = 0;												// 窗口句柄清零
		return FALSE;													// 返回FALSE
	}

	PixelFormat = ChoosePixelFormat(window->hDC, &pfd);					// 选择兼容的像素格式
	if (PixelFormat == 0)												// 若选择失败
	{
		ReleaseDC(window->hWnd, window->hDC);							// 释放设备描述表
		window->hDC = 0;												// 将设备描述表清零
		DestroyWindow(window->hWnd);									// 销毁窗口
		window->hWnd = 0;												// 窗口句柄清零
		return FALSE;													// 返回FALSE
	}

	if (SetPixelFormat(window->hDC, PixelFormat, &pfd) == FALSE)		// 设置像素格式并判断是否失败
	{
		ReleaseDC(window->hWnd, window->hDC);							// 释放设备描述表
		window->hDC = 0;												// 将设备描述表清零
		DestroyWindow(window->hWnd);									// 销毁窗口
		window->hWnd = 0;												// 窗口句柄清零
		return FALSE;													// 返回FALSE
	}

	window->hRC = wglCreateContext(window->hDC);						// 取得绘制描述表
	if (window->hRC == 0)												// 若未得到绘制描述表
	{
		ReleaseDC(window->hWnd, window->hDC);							// 释放设备描述表 
		window->hDC = 0;												// 将设备描述表清零
		DestroyWindow(window->hWnd);									// 销毁窗口
		window->hWnd = 0;												// 窗口句柄清零
		return FALSE;													// 返回FALSE
	}

	if (wglMakeCurrent(window->hDC, window->hRC) == FALSE)				// 设置绘制描述表并判断是否失败
	{
		wglDeleteContext(window->hRC);									// 删除绘制描述表
		window->hRC = 0;												// 将绘制描述表清零
		ReleaseDC(window->hWnd, window->hDC);							// 释放设备描述表
		window->hDC = 0;												// 将设备描述表清零
		DestroyWindow(window->hWnd);									// 销毁窗口
		window->hWnd = 0;												// 窗口句柄清零
		return FALSE;													// 返回FALSE
	}

	ShowWindow(window->hWnd, SW_NORMAL);								// 显示窗口
	ResizeWindowGL(window->init.width, window->init.height);			// 重设窗口
	ZeroMemory(window->keys, sizeof(Keys));								// 清空键盘缓冲区

	return TRUE;														// 窗口创建成功
}
Esempio n. 6
0
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HGLRC hRC;
	HDC hDC = NULL;
	int width, height;
	int x_screenLocation, y_screenLocation;
	static bool isMenu = true;

	const char RESHEADER[] = "Resolution";
	const char RESSAVEDHEADER[] = "Resolution Save...";
	const char RESWRTFAIL[] = "Game needs to be run from hard drive or other writeable media.";

	switch(message) {
		case WM_CREATE:
			hDC = GetDC(hwnd);			
			g_HDC = hDC;
			SetupPixelFormat(hDC);		
			hRC = wglCreateContext(hDC);
			wglMakeCurrent(hDC, hRC);

			// Initialise sphere chain to avoid crashes.
			for(counter = 0; counter < CHAINMAXLENGTH; counter++)
				ASphere[counter] = NULL;
			break;
		case WM_KEYDOWN:
			switch(wParam)
			{
				case VK_ESCAPE:
					switch(iFeatureIsInitialised)
					{
						case 1:
						case 2:
						case 3:
						case 4:
						case 5:
							currentMenu = 2;
							PostMessage(hwnd, ID_GAME_MENU, wParam, lParam);
							break;
						case 6:
						case 7:
						case 8:
							currentMenu = 3;
							PostMessage(hwnd, ID_GAME_MENU, wParam, lParam);
							break;
						case 9:
							currentMenu = 0;
							PostMessage(hwnd, ID_GAME_MENU, wParam, lParam);
							break;
						default:
							break;
					}
					break;
				case VK_F1:
					if(!isMenu)
					{
						if(WriteResFile(640, 480))
							MessageBox(NULL, "Game will now play at 640 x 480 resolution.", RESHEADER, MB_OK);
						else
							MessageBox(NULL, RESWRTFAIL, RESSAVEDHEADER, MB_OK);
						if(!CheckCurrentResolution(640, 480))
							ChangeScreenResolution(640, 480);
					}
					break;
				case VK_F2:
					if(!isMenu)
					{
						if(WriteResFile(800, 600))
							MessageBox(NULL, "Game will now play at 800 x 600 resolution.", RESHEADER, MB_OK);
						else
							MessageBox(NULL, RESWRTFAIL, RESSAVEDHEADER, MB_OK);
						if(!CheckCurrentResolution(800, 600))
							ChangeScreenResolution(800, 600);
					}
					break;
				case VK_F3:
					if(!isMenu)
					{
						if(WriteResFile(1024, 768))
							MessageBox(NULL, "Game will now play at 1024 x 768 resolution.", RESHEADER, MB_OK);
						else
							MessageBox(NULL, RESWRTFAIL, RESSAVEDHEADER, MB_OK);
						if(!CheckCurrentResolution(1024, 768))
							ChangeScreenResolution(1024, 768);
					}
					break;
				case VK_F4:
					if(!isMenu)
					{
						if(WriteResFile(1280, 1024))
							MessageBox(NULL, "Game will now play at 1280 x 1024 resolution.", RESHEADER, MB_OK);
						else
							MessageBox(NULL, RESWRTFAIL, RESSAVEDHEADER, MB_OK);
						if(!CheckCurrentResolution(1280, 1024))
							ChangeScreenResolution(1280, 1024);
					}
					break;
				default:
					break;
			}
			break;
		case WM_LBUTTONDOWN:
			Sleep(400);			// Retains mouse coords for 2/5 of a second to prevent filtering through to last menu.
			x_screenLocation = LOWORD(lParam); y_screenLocation = HIWORD(lParam);
			g_x_region = x_screenLocation; g_y_region = y_screenLocation;
			g_wParam = wParam; g_lParam = lParam;
			break;
		case ID_GAME_MENU:
			if(!CheckCurrentResolution(800, 600) && !windowed)
				ChangeScreenResolution(800, 600);
			DisablePriorOpenGLCommands();
			PlaySound(NULL, NULL, SND_NODEFAULT); // Stop previous sound!
			InitialiseAGUIMenu();
			PlayMenuMusic();
			iFeatureIsInitialised = 0;
			ShowCursor(true);
			isMenu = true;
			break;
		case SPHR_STANDARD:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildStandardSphereChain();
			PlayStandardMusic();
			iFeatureIsInitialised = 1;
			ShowCursor(false);
			isMenu = false;
			break;
		case SPHR_SUPBLAST:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildSphereChainWithPowerUp(0.0f, 0.0f, 0.7f, "supblast.bmp");
			PlaySupremeBlastMusic();
			iFeatureIsInitialised = 2;
			ShowCursor(false);
			isMenu = false;
			break;
		case SPHR_REBIRTH:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildSphereChainWithPowerUp(0.7f, 0.0f, 0.0f, "rebirth.bmp");
			PlayRebirthMusic();
			iFeatureIsInitialised = 3;
			ShowCursor(false);
			isMenu = false;
			break;
		case SPHR_SBREBTH:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildSphereChainWithPowerUp(0.7f, 0.0f, 0.7f, "sbrebirth.bmp");
			PlaySupaFlyMusic();
			iFeatureIsInitialised = 4;
			ShowCursor(false);
			isMenu = false;
			break;
		case SPHR_INVISIBL:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildSphereChainWithPowerUp(0.7f, 0.0f, 0.7f, "invisibility.bmp");
			PlayInvisibilityMusic();
			iFeatureIsInitialised = 5;
			ShowCursor(false);
			isMenu = false;
			break;
		case PU_SUPBLAST:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildPowerUp("supblast.bmp");
			PlaySupremeBlastMusic();
			iFeatureIsInitialised = 6;
			ShowCursor(false);
			isMenu = false;
			break;
		case PU_REBIRTH:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildPowerUp("rebirth.bmp");
			PlayRebirthMusic();
			iFeatureIsInitialised = 7;
			ShowCursor(false);
			isMenu = false;
			break;
		case PU_INVISIBL:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_BuildPowerUp("invisibility.bmp");
			PlayInvisibilityMusic();
			iFeatureIsInitialised = 8;
			ShowCursor(false);
			isMenu = false;
			break;
		case ENV_PAGOE:
			if(!windowed)
				FetchResolution();
			DisablePriorOpenGLCommands();
			dik_InitialisePostApocalypticGarderOfEden();
			PlayPAGoEMusic();
			iFeatureIsInitialised = 9;
			ShowCursor(false);
			isMenu = false;
			break;
		case WM_SIZE:
			height = HIWORD(lParam);
			width = LOWORD(lParam);

			if(height == 0)				
				height = 1;
			
			glViewport(0, 0, width, height);
			glMatrixMode(GL_PROJECTION);	
			glLoadIdentity();			
			
			gluPerspective(54.0f, (GLfloat) width/(GLfloat) height, 1.0f, 3000.0f);

			glMatrixMode(GL_MODELVIEW);	
			glLoadIdentity();			

			return 0;
			break;
		case WM_DESTROY:
			CleanUpLoadTextures();
			FreeChainMemory();
			DeleteDirectSoundResources();
			DeleteDirectInputResources();
			DisablePriorOpenGLCommands();
			DestroyFont();
			wglMakeCurrent(hDC, NULL);
			wglDeleteContext(hRC);
			PostQuitMessage(0);
			break;
		case WM_QUIT:			
			DestroyWindow(hwnd);	
			break;
		default:
			return DefWindowProc(hwnd, message, wParam, lParam);
			break;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}