⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogl_benchmark_sphere.cpp

📁 一个VC编写的显示地球小程序员,可随鼠标移动转动
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//           Name: ogl_benchmark_sphere.cpp
//         Author: Kevin Harris (kevin@codesampler.com)
//  Last Modified: 02/01/05
//    Description: Renders a textured sphere using either Immediate Mode calls,
//                 Immediate Mode calls cached in a Display List, or as a 
//                 collection of geometric data stored in an interleaved 
//                 fashion within a Vertex Array.
//
//   Control Keys: Left Mouse Button - Spin the view.
//                 F1 - Decrease sphere precision.
//                 F2 - Increase sphere precision.
//                 F3 - Use Immediate mode
//                 F4 - Use a Display List
//                 F5 - Use a Vertex Array
//                 F6 - Perform Benchmarking
//                 F7 - Toggle wire-frame mode.
//-----------------------------------------------------------------------------

#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
// Do this to access M_PI, which is not officially part of the C/C++ standard.
#define _USE_MATH_DEFINES 
#include <math.h>
#include <sys/timeb.h>
#include <iostream>
#include <io.h>
#include <fcntl.h>
using namespace std;
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "resource.h"

//-----------------------------------------------------------------------------
// DEFINES
//-----------------------------------------------------------------------------
#define IMMEDIATE_MODE 0
#define DISPLAY_LIST   1
#define VERTEX_ARRAY   2

//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
HDC	      g_hDC       = NULL;
HGLRC     g_hRC       = NULL;
HWND      g_hWnd      = NULL;
HINSTANCE g_hInstance = NULL;

float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;

GLuint g_textureID = 0;
GLuint g_sphereDList;

bool g_bRenderInWireFrame = false;
GLuint  g_nCurrentMode = IMMEDIATE_MODE;
GLuint  g_nPrecision  = 100;
GLuint  g_nNumSphereVertices;
GLfloat g_fMarsSpin   = 0.0f;

// A custom data structure for our interleaved vertex attributes
// The interleaved layout will be, GL_T2F_N3F_V3F
struct Vertex
{
    float tu, tv;
    float nx, ny, nz;
    float vx, vy, vz;
};

Vertex *g_pSphereVertices = NULL; // Points to Vertex Array

//-----------------------------------------------------------------------------
// PROTOTYPES
//-----------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE g_hInstance,HINSTANCE hPrevInstance, 
				   LPSTR lpCmdLine, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND g_hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void redirectIOToConsole(void);
void loadTexture(void);
void init(void);
void render(void);
void shutDown(void);
void renderSphere(float cx, float cy, float cz, float r, int n);
void createSphereDisplayList();
void createSphereGeometry( float cx, float cy, float cz, float r, int n);
void setVertData(int index,float tu, float tv, float nx, float ny, float nz, 
                 float vx, float vy, float vz);
void doBenchmark(void);

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPSTR     lpCmdLine,
					int       nCmdShow )
{
    redirectIOToConsole();

	WNDCLASSEX winClass;
	MSG        uMsg;

    memset(&uMsg,0,sizeof(uMsg));

	winClass.lpszClassName = "MY_WINDOWS_CLASS";
	winClass.cbSize        = sizeof(WNDCLASSEX);
	winClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	winClass.lpfnWndProc   = WindowProc;
	winClass.hInstance     = hInstance;
    winClass.hIcon	       = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_ICON);
    winClass.hIconSm	   = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_ICON);
	winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	winClass.lpszMenuName  = NULL;
	winClass.cbClsExtra    = 0;
	winClass.cbWndExtra    = 0;
	
	if( !RegisterClassEx(&winClass) )
		return E_FAIL;

	g_hWnd = CreateWindowEx( NULL,"MY_WINDOWS_CLASS",
						    "OpenGL - Benchmark Sphere",
							WS_OVERLAPPEDWINDOW,
					 	    0,0, 640,480, NULL, NULL, g_hInstance, NULL );

	if( g_hWnd == NULL )
		return E_FAIL;

    ShowWindow( g_hWnd, nCmdShow );
    UpdateWindow( g_hWnd );

	init();

	while( uMsg.message != WM_QUIT )
	{
		if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
		{ 
			TranslateMessage( &uMsg );
			DispatchMessage( &uMsg );
		}
        else
		    render();
	}

	shutDown();

    UnregisterClass( "MY_WINDOWS_CLASS", g_hInstance );

	return uMsg.wParam;
}

//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT CALLBACK WindowProc( HWND   g_hWnd, 
							 UINT   msg, 
							 WPARAM wParam, 
							 LPARAM lParam )
{
    static POINT ptLastMousePosit;
	static POINT ptCurrentMousePosit;
	static bool bMousing;
    
    switch( msg )
	{
        case WM_KEYDOWN:
		{
			switch( wParam )
			{
				case VK_ESCAPE:
					PostQuitMessage(0);
					break;

                case VK_F1:
                    if( g_nPrecision > 5 )
                        g_nPrecision -= 2;

                    if( g_nCurrentMode == DISPLAY_LIST )
                    {
                        createSphereDisplayList();
                    }

                    if( g_nCurrentMode == VERTEX_ARRAY ||
                        g_nCurrentMode == IMMEDIATE_MODE)
                    {
                        createSphereGeometry( 0.0f, 0.0f, 0.0f, 1.5f, g_nPrecision );
                    }

                    cout << "Sphere Resolution = " << g_nPrecision << endl;
                    break;

                case VK_F2:
                    if( g_nPrecision < 30000 )
                        g_nPrecision += 2;

                    if( g_nCurrentMode == DISPLAY_LIST )
                    {
                        createSphereDisplayList();
                    }

                    if( g_nCurrentMode == VERTEX_ARRAY ||
                        g_nCurrentMode == IMMEDIATE_MODE )
                    {
                        createSphereGeometry( 0.0f, 0.0f, 0.0f, 1.5f, g_nPrecision );
                    }

                    cout << "Sphere Resolution = " << g_nPrecision << endl;
                    break;

                case VK_F3:
                    g_nCurrentMode = IMMEDIATE_MODE;
                    cout << "Render Method: Immediate Mode" << endl;
                    createSphereGeometry( 0.0f, 0.0f, 0.0f, 1.5f, g_nPrecision );
                    break;

                case VK_F4:
                    g_nCurrentMode = DISPLAY_LIST;
                    createSphereDisplayList();
                    cout << "Render Method: Display List" << endl;
                    break;

                case VK_F5:
                    g_nCurrentMode = VERTEX_ARRAY;
                    createSphereGeometry( 0.0f, 0.0f, 0.0f, 1.5f, g_nPrecision );
                    cout << "Render Method: Vertex Array" << endl;
                    break;

                case VK_F6:
                    cout << endl;
                    cout << "Benchmark Initiated - Standby..." << endl;
                    doBenchmark();
                    break;

                case VK_F7:
                    g_bRenderInWireFrame = !g_bRenderInWireFrame;
                    break;
			}
		}
        break;

        case WM_LBUTTONDOWN:
		{
			ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
            ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
			bMousing = true;
		}
		break;

		case WM_LBUTTONUP:
		{
			bMousing = false;
		}
		break;

		case WM_MOUSEMOVE:
		{
			ptCurrentMousePosit.x = LOWORD (lParam);
			ptCurrentMousePosit.y = HIWORD (lParam);

			if( bMousing )
			{
				g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
				g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
			}
			
			ptLastMousePosit.x = ptCurrentMousePosit.x;
            ptLastMousePosit.y = ptCurrentMousePosit.y;
		}
		break;

		case WM_CLOSE:
		{
			PostQuitMessage(0);	
		}

        case WM_DESTROY:
		{
            PostQuitMessage(0);
		}
        break;
		
		default:
		{
			return DefWindowProc( g_hWnd, msg, wParam, lParam );
		}
		break;
	}

	return 0;
}

//-----------------------------------------------------------------------------
// Name: redirectIOToConsole()
// Desc: 
//-----------------------------------------------------------------------------
void redirectIOToConsole( void )
{
    // Allocate a console so we can output some useful information.
    AllocConsole();

    // Get the handle for STDOUT's file system.
    HANDLE stdOutputHandle = GetStdHandle( STD_OUTPUT_HANDLE );

    // Redirect STDOUT to the new console by associating STDOUT's file 
    // descriptor with an existing operating-system file handle.
    int hConsoleHandle = _open_osfhandle( (intptr_t)stdOutputHandle, _O_TEXT );
    FILE *pFile = _fdopen( hConsoleHandle, "w" );
    *stdout = *pFile;
    setvbuf( stdout, NULL, _IONBF, 0 );

    // This call ensures that iostream and C run-time library operations occur  
    // in the order that they appear in source code.
    ios::sync_with_stdio();
}

//-----------------------------------------------------------------------------
// Name: loadTexture()
// Desc: 
//-----------------------------------------------------------------------------
void loadTexture( void )	
{
    AUX_RGBImageRec *pTextureImage = auxDIBImageLoad( ".\\mars.bmp" );

    if( pTextureImage != NULL )
    {
        glGenTextures( 1, &g_textureID );

        glBindTexture( GL_TEXTURE_2D, g_textureID );

        glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR );

        glTexImage2D( GL_TEXTURE_2D, 0, 3, pTextureImage->sizeX, pTextureImage->sizeY, 0,
            GL_RGB, GL_UNSIGNED_BYTE, pTextureImage->data );
    }

    if( pTextureImage )
    {
        if( pTextureImage->data )
            free( pTextureImage->data );

        free( pTextureImage );
    }
}

//-----------------------------------------------------------------------------
// Name: init()
// Desc: 
//-----------------------------------------------------------------------------
void init( void )
{
	GLuint PixelFormat;

	PIXELFORMATDESCRIPTOR pfd;
	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

    pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion   = 1;
    pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 16;
    pfd.cDepthBits = 16;
	
	g_hDC = GetDC( g_hWnd );
	PixelFormat = ChoosePixelFormat( g_hDC, &pfd );
	SetPixelFormat( g_hDC, PixelFormat, &pfd );
	g_hRC = wglCreateContext( g_hDC );
	wglMakeCurrent( g_hDC, g_hRC );

	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -