WIN32 实现OPenGL显示源码

本文档提供了一段使用WIN32 API来创建并初始化OpenGL上下文的源码,通过链接glaux.lib、opengl32.lib和glu32.lib库文件,实现了OpenGL的基本显示功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <windows.h>
#include <GL\gl.h>
#include <GL\glu.h>

struct sample_MATERIAL{
 GLfloat ambient[3];
 GLfloat diffuse[3];
 GLfloat specular[3];
 GLfloat emission[3];
 GLfloat alpha;
 GLfloat phExp;
 int   texture;
};

static sample_MATERIAL materials [4] = {
 {{0.117647f,0.117647f,0.117647f},	{0.752941f,0.752941f,0.752941f},	{0.752941f,0.752941f,0.752941f},	{0.0f,0.0f,0.0f},	1.0f,8.0f,-1}, //Explorer Default
 {{1.0f,0.0f,0.0f},	{1.0f,0.0f,0.0f},	{0.628627f,0.628627f,0.628627f},	{0.0f,0.0f,0.0f},	1.0f,4.0f,-1}, //red
 {{0.0f,1.0f,0.0f},	{0.0f,1.0f,0.0f},	{0.628627f,0.628627f,0.628627f},	{0.0f,0.0f,0.0f},	1.0f,4.0f,-1}, //green
 {{0.0f,0.470588f,1.0f},	{0.0f,0.470588f,1.0f},	{0.628627f,0.628627f,0.628627f},	{0.0f,0.0f,0.0f},	1.0f,4.0f,-1} //blue
};

// 6 Verticies
// 7 Texture Coordinates
// 5 Normals
// 8 Triangles

static BYTE face_indicies[8][9] = {
// Pyramid01
	{0,4,1 ,0,0,0 ,0,1,2 }, {1,4,2 ,0,0,0 ,3,4,2 }, {2,4,3 ,0,0,0 ,2,4,0 },
	{3,4,0 ,0,0,0 ,0,4,5 }
// Object-red
	, {5,2,3 ,1,1,1 ,6,0,2 }
// Object02-g
	, {5,3,0 ,2,2,2 ,6,0,2 }
// Object03-b
	, {5,1,2 ,3,3,3 ,6,0,2 }
// Object04
	, {5,0,1 ,4,4,4 ,6,0,2 }
};
static GLfloat vertices [6][3] = {
{-0.5f,-0.5f,-0.333333f},{0.5f,-0.5f,-0.333333f},{0.5f,0.5f,-0.333333f},
{-0.5f,0.5f,-0.333333f},{-1.49378e-08f,1.02206e-08f,-0.333333f},{-1.49378e-08f,1.02206e-08f,0.333333f}
};
static GLfloat normals [5][3] = {
{0.0f,0.0f,-1.0f},{0.0f,0.8f,0.6f},{-0.8f,0.0f,0.6f},
{0.8f,0.0f,0.6f},{0.0f,-0.8f,0.6f}
};
static GLfloat textures [7][2] = {
{0.0f,1.0f},{0.5f,0.5f},{1.0f,1.0f},
{1.0f,2.0f},{0.5f,1.5f},{0.0f,2.0f},
{0.5f,2.0f}
};
/*Material indicies*/
/*{material index,face count}*/
static int material_ref [5][2] = {
{0,4},
{1,1},
{2,1},
{3,1},
{0,1}
};
float sizex,sizey;
LONG WINAPI WndProc (HWND, UINT, WPARAM, LPARAM);
GLsizei glnWidth, glnHeight;
GLdouble gldAspect;
void SetDCPixelFormat (HWND,HDC);
void InitializeRC (void);
void DrawScene (HDC, UINT,UINT);

HPALETTE hPalette = NULL;
GLfloat nSize = 0.0f;
GLfloat nCol = 0.0f;
GLfloat nTop = 1.0f;
GLfloat nBottom = 0.0f;
int bFlag = 1;
char wndname[256]="";

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
{
    static char szAppName[] = "3D Exploration Exported APP";
    WNDCLASS wc;
    HWND hwnd;
    MSG msg;


    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC) WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;

    RegisterClass (&wc);

    hwnd = CreateWindow (szAppName, szAppName,
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
        HWND_DESKTOP, NULL, hInstance, NULL);

    ShowWindow (hwnd, nCmdShow);
    UpdateWindow (hwnd);

    while (GetMessage (&msg, NULL, 0, 0)) {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
    return msg.wParam;
}

/*
 *  WndProc processes messages to the main window.
 */

LONG WINAPI WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HDC hdc;
    static HGLRC hrc;
    PAINTSTRUCT ps;
    static UINT nAngle = 0;
    static UINT nAngle2 = 0;
    static UINT nTimer;
    int n;
                
    switch (msg) {
    
    case WM_CREATE:
        //
        // Create a rendering context and set a timer.
        //
        hdc = GetDC (hwnd);
        SetDCPixelFormat (hwnd,hdc);
        hrc = wglCreateContext (hdc);
        wglMakeCurrent (hdc, hrc);
        InitializeRC ();
        nTimer = SetTimer (hwnd, 1, 1, NULL);
        return 0;

    case WM_SIZE:
        //
        // Redefine the viewing volume and viewport when the window size
        // changes.
        //
        glnWidth = (GLsizei) LOWORD (lParam);
        glnHeight = (GLsizei) HIWORD (lParam);

        return 0;

    case WM_PAINT:{
        //
        // Draw the scene.
        //
        BeginPaint (hwnd, &ps);
        DrawScene (hdc, nAngle,nAngle2);
        EndPaint (hwnd, &ps);

        }return 0;

    case WM_TIMER:
        //
        // Update the rotation angle and force a repaint.
        //
        nAngle += 2;
        if (nAngle >= 360)
            nAngle -= 360;
        nAngle2 += 1;
        if (nAngle2 >= 360)
            nAngle2 -= 360;

		if (bFlag == 1)
			nSize += 0.05f;
			nCol += 0.01f;
			if (nSize >= nTop)
				bFlag = 0;

		if (bFlag == 0)
			nSize -= 0.05f;
			nCol -= 0.01f;
			if (nSize <= nBottom)
				bFlag = 1;

		InvalidateRect (hwnd, NULL, FALSE);
        return 0;

    case WM_QUERYNEWPALETTE:
        //
        // If the program is using a color palette, realize the palette
        // and update the client area when the window receives the input
        // focus.
        //
        if (hPalette != NULL) {
            if (n = RealizePalette (hdc))
                InvalidateRect (hwnd, NULL, FALSE);
            return n;
        }
        break;

    case WM_PALETTECHANGED:
        //
        // If the program is using a color palette, realize the palette
        // and update the colors in the client area when another program
        // realizes its palette.
        //
        if ((hPalette != NULL) && ((HWND) wParam != hwnd)) {
            if (RealizePalette (hdc))
                UpdateColors (hdc);
            return 0;
        }
        break;

    case WM_DESTROY:
        //
        // Clean up and terminate.
        //
        wglMakeCurrent (NULL, NULL);
        wglDeleteContext (hrc);
        ReleaseDC (hwnd, hdc);
        if (hPalette != NULL)
            DeleteObject (hPalette);
        KillTimer (hwnd, nTimer);
        PostQuitMessage (0);
        return 0;
    }
    return DefWindowProc (hwnd, msg, wParam, lParam);
}

/*
 *  SetDCPixelFormat sets the pixel format for a device context in
 *  preparation for creating a rendering context.
 *
 *  Input parameters:
 *    hdc = Device context handle
 *
 *  Returns:
 *    Nothing
 */

void SetDCPixelFormat (HWND hwnd,HDC hdc)
{
    HANDLE hHeap;
    int nColors, i;
    LPLOGPALETTE lpPalette;
    BYTE byRedMask, byGreenMask, byBlueMask;

    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof (PIXELFORMATDESCRIPTOR),             // Size of this structure
        1,                                          // Version number
        PFD_DRAW_TO_WINDOW |                        // Flags
        PFD_SUPPORT_OPENGL |
        PFD_GENERIC_ACCELERATED|
        PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,                              // RGBA pixel values
        24,                                         // 24-bit color
        0, 0, 0, 0, 0, 0,                           // Don't care about these
        0, 0,                                       // No alpha buffer
        0, 0, 0, 0, 0,                              // No accumulation buffer
        32,                                         // 32-bit depth buffer
        0,                                          // No stencil buffer
        0,                                          // No auxiliary buffers
        PFD_MAIN_PLANE,                             // Layer type
        0,                                          // Reserved (must be 0)
        0, 0, 0                                     // No layer masks
    };

    int nPixelFormat;

    nPixelFormat = ChoosePixelFormat (hdc, &pfd);
    SetPixelFormat (hdc, nPixelFormat, &pfd);

    if (pfd.dwFlags & PFD_NEED_PALETTE) {
        nColors = 1 << pfd.cColorBits;
        hHeap = GetProcessHeap ();

        (LPLOGPALETTE) lpPalette = (LPLOGPALETTE)HeapAlloc (hHeap, 0,
            sizeof (LOGPALETTE) + (nColors * sizeof (PALETTEENTRY)));

        lpPalette->palVersion = 0x300;
        lpPalette->palNumEntries = nColors;

        byRedMask = (1 << pfd.cRedBits) - 1;
        byGreenMask = (1 << pfd.cGreenBits) - 1;
        byBlueMask = (1 << pfd.cBlueBits) - 1;

        for (i=0; i<nColors; i++) {
            lpPalette->palPalEntry[i].peRed =
                (((i >> pfd.cRedShift) & byRedMask) * 255) / byRedMask;
            lpPalette->palPalEntry[i].peGreen =
                (((i >> pfd.cGreenShift) & byGreenMask) * 255) / byGreenMask;
            lpPalette->palPalEntry[i].peBlue =
                (((i >> pfd.cBlueShift) & byBlueMask) * 255) / byBlueMask;
            lpPalette->palPalEntry[i].peFlags = 0;
        }

        hPalette = CreatePalette (lpPalette);
        HeapFree (hHeap, 0, lpPalette);

        if (hPalette != NULL) {
            SelectPalette (hdc, hPalette, FALSE);
            RealizePalette (hdc);
        }
    }
}

/*
 *  InitializeRC initializes the current rendering context.
 *
 *  Input parameters:
 *    None
 *
 *  Returns:
 *    Nothing
 */


void InitializeRC (void)
{
    GLfloat glfLightAmbient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
    GLfloat glfLightDiffuse[] = { 1.2f, 1.2f, 1.2f, 1.0f };
    GLfloat glfLightSpecular[] = { 0.9f, 0.9f, 0.9f, 1.0f };

    //
    // Add a light to the scene.
    //

    glLightfv (GL_LIGHT0, GL_AMBIENT, glfLightAmbient);
    glLightfv (GL_LIGHT0, GL_DIFFUSE, glfLightDiffuse);
    glLightfv (GL_LIGHT0, GL_SPECULAR, glfLightSpecular);
    glEnable (GL_LIGHTING);
    glEnable (GL_LIGHT0);

    //
    // Enable depth testing and backface culling.
    //

    glEnable (GL_DEPTH_TEST);    
    glEnable (GL_CULL_FACE);

}
void MyMaterial(GLenum mode,GLfloat *f,GLfloat alpha)
{
 GLfloat d[4];
 d[0]=f[0];
 d[1]=f[1];
 d[2]=f[2];
 d[3]=alpha;
 glMaterialfv (GL_FRONT_AND_BACK,mode,d);
}
/*
 *  SelectMaterial uses OpenGL commands to define facet colors.
 *
 *  Returns:
 *    Nothing
 */

void SelectMaterial(int i)
{
  //
  // Define the reflective properties of the 3D Object faces.
  //
  glEnd();
  GLfloat alpha=materials[i].alpha;
  MyMaterial (GL_AMBIENT, materials[i].ambient,alpha);
  MyMaterial (GL_DIFFUSE, materials[i].diffuse,alpha);
  MyMaterial (GL_SPECULAR, materials[i].specular,alpha);
  MyMaterial (GL_EMISSION, materials[i].emission,alpha);
  glMaterialf (GL_FRONT_AND_BACK,GL_SHININESS,materials[i].phExp);
  glBegin(GL_TRIANGLES);

}
/*
 *  DrawScene uses OpenGL commands to draw a object.
 *
 *  Input parameters:
 *    hdc = Device context handle
 *    nAngle = Angle of rotation for object
 *
 *  Returns:
 *    Nothing
 */

void DrawScene (HDC hdc, UINT nAngle,UINT nAngle2)
{
        sizex=glnWidth;
        sizey=glnHeight;

        gldAspect = (GLdouble) glnWidth / (GLdouble) glnHeight;

        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        gluPerspective (30.0,           // Field-of-view angle
                        gldAspect,      // Aspect ratio of viewing volume
                        1.0,            // Distance to near clipping plane
                        10.0);          // Distance to far clipping plane

        glViewport (0, 0, glnWidth, glnHeight);
    //
    // Clear the color and depth buffers.
    //
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //
    // Define the modelview transformation.
    //
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
    glTranslatef (0.0f, 0.0f, -8.0f);
    glRotatef (30.0f, 1.0f, 0.0f, 0.0f);
    glRotatef ((GLfloat) nAngle, 0.0f, 1.0f, 0.0f);
    glRotatef ((GLfloat) nAngle2, 1.0f, 0.0f, 0.0f);
    glScalef (nSize+2.5f,nSize+2.5f,nSize+2.5f);  

	int mcount=0;
	int mindex=0;
	glBegin (GL_TRIANGLES);
	  for(int i=0;i<sizeof(face_indicies)/sizeof(face_indicies[0]);i++)
		{
      if(!mcount)
       {
        SelectMaterial(material_ref[mindex][0]);
        mcount=material_ref[mindex][1];
        mindex++;
       }
       mcount--;
		for(int j=0;j<3;j++)
		 {
		 int vi=face_indicies[i][j];
		 int ni=face_indicies[i][j+3];
		 int ti=face_indicies[i][j+6];
		 glNormal3f (normals[ni][0],normals[ni][1],normals[ni][2]);
		 glTexCoord2f(textures[ti][0],textures[ti][1]);
		 glVertex3f (vertices[vi][0],vertices[vi][1],vertices[vi][2]);
        }
       }
    glEnd ();

    //
    // Swap the buffers.
    //
    glFlush();
    SwapBuffers (hdc);
};


注意添加:

#pragma comment( lib, "glaux.lib")
#pragma comment( lib, "opengl32.lib" ) 
#pragma comment( lib, "glu32.lib" ) 
#pragma comment( lib, "glaux.lib" )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值