Prosty program w OpenGL

Przykładowy program wyświetlający sześcian w OPENGL

/*//
_                    _             _
| |    __ _ _ __ ___ | |__       _-(")-
| |   / _` | '_ ` _ \| '_ \    `%%%%%
| |__| (_| | | | |_| | |_) | _  // \\
|_____\__,_|_| |_| |_|_.__/_| |__  ___
                 | |   / _` | '_ \/ __|
                 | |__| (_| | |_) \__ \
 2018-05-24      |_____\__,_|_.__/|___/
//*/

#include 
#include 
#include 
#include "res.h"

#define IDT_REDRAW_FRAME 2018

void DrawAxes(float a) {
  glPushMatrix();
  glScalef(a, a, a);
  glBegin(GL_LINES);
  glColor3f(0.0, 0.0, 1.0);
  glVertex3f(-10, 0, 0);
  glVertex3f(+10, 0, 0);
  glColor3f(0.0, 1.0, 0.0);
  glVertex3f(0, -10, 0);
  glVertex3f(0, +10, 0);
  glColor3f(1.0, 0.0, 0.0);
  glVertex3f(0, 0, -10);
  glVertex3f(0, 0, +10);
  glEnd();
  glPopMatrix();
}

void DrawBox(float a, float b, float c) {
  glPushMatrix();
  glScalef(a/2, b/2, c/2);
  glBegin(GL_QUADS);
    glNormal3i(0, -1, 0);
    glVertex3i(-1, -1, -1);
    glVertex3i(-1, -1, +1);
    glVertex3i(+1, -1, +1);
    glVertex3i(+1, -1, -1);

    glNormal3i(0, +1, 0);
    glVertex3i(-1, +1, -1);
    glVertex3i(-1, +1, +1);
    glVertex3i(+1, +1, +1);
    glVertex3i(+1, +1, -1);

    glNormal3i(-1, 0, 0);
    glVertex3i(-1, -1, -1);
    glVertex3i(-1, -1, +1);
    glVertex3i(-1, +1, +1);
    glVertex3i(-1, +1, -1);

    glNormal3i(+1, 0, 0);
    glVertex3i(+1, -1, -1);
    glVertex3i(+1, -1, +1);
    glVertex3i(+1, +1, +1);
    glVertex3i(+1, +1, -1);

    glNormal3i(0, 0, -1);
    glVertex3i(-1, -1, -1);
    glVertex3i(-1, +1, -1);
    glVertex3i(+1, +1, -1);
    glVertex3i(+1, -1, -1);

    glNormal3i(0, 0, +1);
    glVertex3i(-1, -1, +1);
    glVertex3i(-1, +1, +1);
    glVertex3i(+1, +1, +1);
    glVertex3i(+1, -1, +1);
  glEnd();
  glPopMatrix();
}

void DrawFrame() {
  glClearColor(0.1, 0.1, 0.1, 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glLoadIdentity();
  glTranslatef(0.0, -2.0, -10.0);
  
  static float fAngle = 0.0;
  fAngle += 1;
  glRotatef(fAngle, 0, 1, 0);

  DrawAxes(1.0);

  glColor3f(0.0, 1.0, 0.0);
  DrawBox(2.0, 1.0, 1.0);
}

void InitOpenGL() {
  glEnable(GL_DEPTH_TEST);
}

INT_PTR OnWmClose(
  _In_ HWND   hwndDlg,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
) {
  DestroyWindow(hwndDlg);
  PostQuitMessage(0);
  return TRUE;
}

INT_PTR OnWmDestroy(
  _In_ HWND   hwndDlg,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
) {
  HGLRC hglrc = wglGetCurrentContext();
  HDC hdc = wglGetCurrentDC();
  wglMakeCurrent(NULL, NULL);
  wglDeleteContext(hglrc);
  ReleaseDC(hwndDlg,hdc);

  KillTimer(hwndDlg, IDT_REDRAW_FRAME);

  PostQuitMessage(0);
  return TRUE;
}

INT_PTR OnWmInitDialog(
  _In_ HWND   hwndDlg,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
) {
  HDC      hdc;
  HGLRC    hglrc;
  hdc = GetDC(hwndDlg);

  PIXELFORMATDESCRIPTOR pfd = {
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL,
    PFD_TYPE_RGBA,
    24,
    0,0,0,0,0,0,
    0,0,0,
    0,0,0,0,
    32,
    0,0,
    PFD_MAIN_PLANE,
    0,0,0,0
  };
  int iPixelFormat = ChoosePixelFormat(hdc, &pfd);
  SetPixelFormat(hdc, iPixelFormat, &pfd);

  if (hglrc = wglCreateContext(hdc)) {
    bool bHaveCurrentRC = wglMakeCurrent(hdc, hglrc);
  }

  InitOpenGL();

  return TRUE;
}

INT_PTR OnWmSize(
  _In_ HWND   hwndDlg,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
) {
  int iWidth = LOWORD(lParam);
  int iHeight = HIWORD(lParam);

  if (iHeight == 0) iHeight++;

  glViewport(0, 0, iWidth, iHeight);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, ((float)iWidth) / iHeight, 0.1, 100.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  return TRUE;
}

INT_PTR OnWmTimer(
  _In_ HWND   hwndDlg,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
) {
  switch (wParam) {
    case IDT_REDRAW_FRAME:
      DrawFrame();
      HDC hdc = wglGetCurrentDC();
      SwapBuffers(hdc);
      break;

  }
  return TRUE;
}

INT_PTR CALLBACK DialogProc(
  _In_ HWND   hwndDlg,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
)
{
  switch (uMsg) {
    case WM_INITDIALOG:
      return OnWmInitDialog(hwndDlg, uMsg, wParam, lParam);

    case WM_CLOSE:
      return OnWmClose(hwndDlg, uMsg, wParam, lParam);
    
    case WM_DESTROY:
      return OnWmDestroy(hwndDlg, uMsg, wParam, lParam);

    case WM_SIZE:
      return OnWmSize(hwndDlg, uMsg, wParam, lParam);

    case WM_TIMER:
      return OnWmTimer(hwndDlg, uMsg, wParam, lParam);
  }
  return FALSE;
}

int CALLBACK WinMain(
  _In_ HINSTANCE hInstance,
  _In_ HINSTANCE hPrevInstance,
  _In_ LPSTR     lpCmdLine,
  _In_ int       nCmdShow
) {
  HWND hwndMainDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);

  ShowWindow(hwndMainDialog,SW_SHOW);

  SetTimer(hwndMainDialog, IDT_REDRAW_FRAME, 1000 / 25, NULL);

  //Main loop
  MSG uMsg;
  BOOL bRet;
  while ((bRet=GetMessage(&uMsg, hwndMainDialog, 0, 0)) != 0) {
    TranslateMessage(&uMsg);
    DispatchMessage(&uMsg);
  }
  return uMsg.wParam;
}