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

📄 sphereworld32.c

📁 OpeNGL超级宝典源代码. OpeNGL超级宝典源代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
// SphereWorld32.c
// OpenGL SuperBible
// Program by Richard S. Wright Jr.
// This program demonstrates a full featured robust Win32
// OpenGL framework

///////////////////////////////////////////////////////////////////////////////
// Include Files
#include <windows.h>                // Win32 Framework (No MFC)
#include <gl\gl.h>                  // OpenGL
#include <gl\glu.h>                 // GLU Library
#include <stdio.h>                  // Standard IO (sprintf)
#include "..\..\common\wglext.h"    // WGL Extension Header
#include "..\..\common\glext.h"	    // OpenGL Extension Header
#include "..\..\common\gltools.h"   // GLTools library
#include "resource.h"               // Dialog resources


// Initial rendering options specified by the user.
struct STARTUPOPTIONS {
    DEVMODE	devMode;			// Display mode to use
    int	 nPixelFormat;			// Pixel format to use
    int	 nPixelFormatMS;		// Multisampled pixel format
    BOOL bFullScreen;			// Full screen?
    BOOL bFSAA;
    BOOL bVerticalSync;
    };


///////////////////////////////////////////////////////////////////////////////
// Module globals
static HPALETTE hPalette = NULL;                // Palette Handle
static HINSTANCE ghInstance = NULL;             // Module Instance Handle
static LPCTSTR lpszAppName = "SphereWorld32";   // Name of App
static GLint nFontList;                         // Base display list for font
static struct STARTUPOPTIONS startupOptions;    // Startup options info
static LARGE_INTEGER CounterFrequency;
static LARGE_INTEGER FPSCount;
static LARGE_INTEGER CameraTimer;

#define NUM_SPHERES      30         // Number of Spheres
GLTFrame    spheres[NUM_SPHERES];   // Location of spheres
GLTFrame    frameCamera;            // Location and orientation of camera

// Light and material Data
GLfloat fLightPos[4]   = { -100.0f, 100.0f, 50.0f, 1.0f };  // Point source
GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 0.0f };
GLfloat fLowLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };

// Shadow matrix
GLTMatrix mShadowMatrix;

// Textures identifiers
#define GROUND_TEXTURE  0
#define TORUS_TEXTURE   1
#define SPHERE_TEXTURE  2
#define NUM_TEXTURES    3
GLuint  textureObjects[NUM_TEXTURES];
const char *szTextureFiles[] = {"grass.tga", "wood.tga", "orb.tga"};

// Sphere and torus display lists
GLuint  lTorusList, lSphereList;

///////////////////////////////////////////////////////////////////////////////
// Forward Declarations

// Declaration for Window procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
                                        WPARAM wParam, LPARAM	lParam);

// Startup Dialog Procedure
BOOL APIENTRY StartupDlgProc (HWND hDlg, UINT message, 
                                        UINT wParam, LONG lParam);

// Find the best available pixelformat, including if Multisample is available
void FindBestPF(HDC hDC, int *nRegularFormat, int *nMSFormat);

BOOL ShowStartupOptions(void);          // Initial startup dialog
void ChangeSize(GLsizei w, GLsizei h);  // Change projection and viewport
void RenderScene(void);                 // Draw everything
void SetupRC(HDC hDC);                  // Set up the rendering context
void ShutdownRC(void);                  // Shutdown the rendering context
HPALETTE GetOpenGLPalette(HDC hDC);     // Create a 3-3-2 palette
void DrawInhabitants(GLint nShadow);    // Draw inhabitants of the world
void DrawGround(void);                  // Draw the ground

///////////////////////////////////////////////////////////////////////////////
// Extension function pointers
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL;
PFNGLWINDOWPOS2IPROC glWindowPos2i = NULL;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;


//////////////////////////////////////////////////////////////
// Window has changed size. Reset to match window coordiantes
void ChangeSize(GLsizei w, GLsizei h)
	{
    GLfloat fAspect;

    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if(h == 0)
        h = 1;

    glViewport(0, 0, w, h);
        
    fAspect = (GLfloat)w / (GLfloat)h;

    // Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	
    // Set the clipping volume
    gluPerspective(35.0f, fAspect, 1.0f, 50.0f);
        
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();    
	}


///////////////////////////////////////////////////////////
// Draw the ground as a series of triangle strips
void DrawGround(void)
    {
    GLfloat fExtent = 20.0f;
    GLfloat fStep = 1.0f;
    GLfloat y = -0.4f;
    GLfloat iStrip, iRun;
    GLfloat s = 0.0f;
    GLfloat t = 0.0f;
    GLfloat texStep = 1.0f / (fExtent * .075f);
    
    // Ground is a tiling texture
    glBindTexture(GL_TEXTURE_2D, textureObjects[GROUND_TEXTURE]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    
    // Lay out strips and repeat textures coordinates
    for(iStrip = -fExtent; iStrip <= fExtent; iStrip += fStep)
        {
        t = 0.0f;
        glBegin(GL_TRIANGLE_STRIP);

            for(iRun = fExtent; iRun >= -fExtent; iRun -= fStep)
                {
                glTexCoord2f(s, t);
                glNormal3f(0.0f, 1.0f, 0.0f);   // All Point up
                glVertex3f(iStrip, y, iRun);
                
                glTexCoord2f(s + texStep, t);
                glNormal3f(0.0f, 1.0f, 0.0f);   // All Point up
                glVertex3f(iStrip + fStep, y, iRun);
                
                t += texStep;
                }
        glEnd();
        s += texStep;
        }
    }

///////////////////////////////////////////////////////////////////////
// Draw random inhabitants and the rotating torus/sphere duo
void DrawInhabitants(GLint nShadow)
    {
    static GLfloat yRot = 0.0f;         // Rotation angle for animation
    GLint i;

    if(nShadow == 0)
        {
        yRot += 0.5f;
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        }
    else
        glColor4f(0.0f, 0.0f, .0f, .75f);  // Shadow color
  
        
    // Draw the randomly located spheres
    glBindTexture(GL_TEXTURE_2D, textureObjects[SPHERE_TEXTURE]);
    for(i = 0; i < NUM_SPHERES; i++)
        {
        glPushMatrix();
        gltApplyActorTransform(&spheres[i]);
        glCallList(lSphereList);
        glPopMatrix();
        }

    glPushMatrix();
        glTranslatef(0.0f, 0.1f, -2.5f);
    
        glPushMatrix();
            glRotatef(-yRot * 2.0f, 0.0f, 1.0f, 0.0f);
            glTranslatef(1.0f, 0.0f, 0.0f);
            glCallList(lSphereList);
        glPopMatrix();
    
        if(nShadow == 0)
            {
            // Torus alone will be specular
            glMaterialfv(GL_FRONT, GL_SPECULAR, fBrightLight);
            }
        
        glRotatef(yRot, 0.0f, 1.0f, 0.0f);
        glBindTexture(GL_TEXTURE_2D, textureObjects[TORUS_TEXTURE]);
        glCallList(lTorusList);
        glMaterialfv(GL_FRONT, GL_SPECULAR, fNoLight);
    glPopMatrix();
    }


//////////////////////////////////////////////////
// Draw everything
void RenderScene(void)
	{
    static int iFrames = 0;   // Count frames to calculate fps ever 100 frames
    static float fps = 0.0f;  // Calculated fps

    // Clear the window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        
    glPushMatrix();
        gltApplyCameraTransform(&frameCamera);  // Move camera/world
        
        // Position light before any other transformations
        glLightfv(GL_LIGHT0, GL_POSITION, fLightPos);
        
        // Draw the ground
        glColor3f(1.0f, 1.0f, 1.0f);
        DrawGround();
        
        // Draw shadows first
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
        glDisable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_STENCIL_TEST);
        glPushMatrix();
            glMultMatrixf(mShadowMatrix);
            DrawInhabitants(1);
        glPopMatrix();
        glDisable(GL_STENCIL_TEST);
        glDisable(GL_BLEND);
        glEnable(GL_LIGHTING);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_DEPTH_TEST);
        
        // Draw inhabitants normally
        DrawInhabitants(0);
    glPopMatrix();


    // Calculate Frame Rate, once every 100 frames
    iFrames++;
    if(iFrames == 100)
        {
        float fTime;

		// Get the current count
		LARGE_INTEGER lCurrent;
		QueryPerformanceCounter(&lCurrent);

		fTime = (float)(lCurrent.QuadPart - FPSCount.QuadPart) /
										(float)CounterFrequency.QuadPart;
        fps = (float)iFrames / fTime;
      

        // Reset frame count and timer
        iFrames = 0;
        QueryPerformanceCounter(&FPSCount);
        }

	// If we have the window position extension, display
    // the frame rate, and tell if multisampling was enabled
    // and if the VSync is turned on.
    if(glWindowPos2i != NULL)
        {
        int iRow = 10;
        char cBuffer[64];

        // Turn off depth test, lighting, and texture mapping
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
        glDisable(GL_TEXTURE_2D);
       	glColor3f(1.0f, 1.0f, 1.0f);


        // Set position and display message
        glWindowPos2i(0, iRow);
    	glListBase(nFontList);
	    glCallLists (13, GL_UNSIGNED_BYTE, "OpenGL Rocks!"); 	
        iRow+= 20;

        // Display the frame rate
        sprintf(cBuffer,"FPS: %.1f", fps);
        glWindowPos2i(0, iRow);
        glCallLists(strlen(cBuffer), GL_UNSIGNED_BYTE, cBuffer);
        iRow += 20;

        // MultiSampled?
        if(startupOptions.bFSAA == TRUE && startupOptions.nPixelFormatMS != 0)
            {
            glWindowPos2i(0, iRow);
            glCallLists(25 ,GL_UNSIGNED_BYTE,"Multisampled Frame Buffer");
            iRow += 20;
            }

        // VSync?
        if(wglSwapIntervalEXT != NULL && startupOptions.bVerticalSync == TRUE)
            {
            glWindowPos2i(0, iRow);
            glCallLists(9 ,GL_UNSIGNED_BYTE, "VSync On");
            iRow += 20;
            }


        // Put everything back
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_TEXTURE_2D);
        }
	}

///////////////////////////////////////////////////////////////////////////////
// Setup. Create font/bitmaps, load textures, create display lists
void SetupRC(HDC hDC)
	{
    GLTVector3 vPoints[3] = {{ 0.0f, -0.4f, 0.0f },
                             { 10.0f, -0.4f, 0.0f },
                             { 5.0f, -0.4f, -5.0f }};
    int iSphere;
    int i;

	// Setup the Font characteristics
	HFONT hFont;
	LOGFONT logfont;

	logfont.lfHeight = -20;
	logfont.lfWidth = 0;
	logfont.lfEscapement = 0;
	logfont.lfOrientation = 0;
	logfont.lfWeight = FW_BOLD;
	logfont.lfItalic = FALSE;
	logfont.lfUnderline = FALSE;
	logfont.lfStrikeOut = FALSE;
	logfont.lfCharSet = ANSI_CHARSET;
	logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
	logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	logfont.lfQuality = DEFAULT_QUALITY;
	logfont.lfPitchAndFamily = DEFAULT_PITCH;
	strcpy(logfont.lfFaceName,"Arial");

	// Create the font and display list
	hFont = CreateFontIndirect(&logfont);
	SelectObject (hDC, hFont); 

	
	//Create display lists for glyphs 0 through 128
	nFontList = glGenLists(128);
	wglUseFontBitmaps(hDC, 0, 128, nFontList);

	DeleteObject(hFont);		// Don't need original font anymore
   
    // Grayish background
    glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]);
   
    // Clear stencil buffer with zero, increment by one whenever anybody
    // draws into it. When stencil function is enabled, only write where
    // stencil value is zero. This prevents the transparent shadow from drawing
    // over itself

⌨️ 快捷键说明

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