Alright, we have seen an OpenGL in C/C++ using GLUT but it is rarely used. Most of the people prefer Win32 to write an OpenGL application, mostly games.
Win32 is still the best game development platform for PC rather than other languages, such as .NET. But to write games using only Win32 is a lot of overhead, so you can use Simple DirectMedia Layer (SDL) library.
To get started with OpenGL using GLUT, read this article.
Win32 is still the best game development platform for PC rather than other languages, such as .NET. But to write games using only Win32 is a lot of overhead, so you can use Simple DirectMedia Layer (SDL) library.
To get started with OpenGL using GLUT, read this article.
See the Wikipedia page of Win32 API also: https://en.wikipedia.org/wiki/Windows_API
To get started with Win32, go through these articles -
- Getting Started With Windows Programming In C/C++
- Getting Started With Windows Programming In C/C++ : Basic Drawing
- Getting Started With Windows Programming In C/C++: Key Events
- Creating Custom Window In Win32
First, start Visual Studio and create Win32 Project from a Visual C++ list and give a name to the project. I have created OpenGL_Win32.
Once you create a project, you can see some predefined code in the editor of the file (OpenGL_Win32.cpp).
We need the above code so we don't need to write a code for creating a window.
First add the OpenGL headers.
Once you create a project, you can see some predefined code in the editor of the file (OpenGL_Win32.cpp).
- #include "stdafx.h"
- #include "OpenGL_Win32.h"
- #define MAX_LOADSTRING 100
- // Global Variables:
- HINSTANCE hInst; // current instance
- TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
- TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
- // Forward declarations of functions included in this code module:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
- int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
- _In_opt_ HINSTANCE hPrevInstance,
- _In_ LPTSTR lpCmdLine,
- _In_ int nCmdShow)
- {
- UNREFERENCED_PARAMETER(hPrevInstance);
- UNREFERENCED_PARAMETER(lpCmdLine);
- // TODO: Place code here.
- MSG msg;
- HACCEL hAccelTable;
- // Initialize global strings
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_WIN32PROJECT1, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- // Perform application initialization:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT1));
- // Main message loop:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return (int) msg.wParam;
- }
- //
- // FUNCTION: MyRegisterClass()
- //
- // PURPOSE: Registers the window class.
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32PROJECT1);
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
- return RegisterClassEx(&wcex);
- }
- //
- // FUNCTION: InitInstance(HINSTANCE, int)
- //
- // PURPOSE: Saves instance handle and creates main window
- //
- // COMMENTS:
- //
- // In this function, we save the instance handle in a global variable and
- // create and display the main program window.
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // Store instance handle in our global variable
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return FALSE;
- }
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return TRUE;
- }
- //
- // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
- //
- // PURPOSE: Processes messages for the main window.
- //
- // WM_COMMAND - process the application menu
- // WM_PAINT - Paint the main window
- // WM_DESTROY - post a quit message and return
- //
- //
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- switch (message)
- {
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // Parse the menu selections:
- switch (wmId)
- {
- case IDM_ABOUT:
- DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
- break;
- case IDM_EXIT:
- DestroyWindow(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- // TODO: Add any drawing code here...
- EndPaint(hWnd, &ps);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
- // Message handler for about box.
- INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- UNREFERENCED_PARAMETER(lParam);
- switch (message)
- {
- case WM_INITDIALOG:
- return (INT_PTR)TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
- }
- break;
- }
- return (INT_PTR)FALSE;
- }
First add the OpenGL headers.
- #include<stdio.h>
- #include<GL/gl.h>
- #include<GL/glu.h>
Then, we need to tell the compiler to link the OpenGL libraries.
- #pragma comment(lib, "opengl32.lib")
- #pragma comment(lib, "glu32.lib")
I'm also using the following variables to rotate the OpenGL objects.
- float angle = 0.0f;
- float X_angle = 1.0f, Y_angle = 0.0f, Z_angle = 0.0f;
Now, we have a window, so we need to create an OpenGL drawing surface on that window.
To do this, we need to set some pixel formats to that window.The pixel format will allow to enable the drawing of an OpenGL elements on it. First, declare the variable of PIXELFORMATDESCRIPTOR and set its fields. It has 26 fields. Most of the bits you can keep 0, but the flags, type, and size must be initialized.
Following is the function that returns the pixel format.
To do this, we need to set some pixel formats to that window.The pixel format will allow to enable the drawing of an OpenGL elements on it. First, declare the variable of PIXELFORMATDESCRIPTOR and set its fields. It has 26 fields. Most of the bits you can keep 0, but the flags, type, and size must be initialized.
Following is the function that returns the pixel format.
- //get pixel format descriptor
- PIXELFORMATDESCRIPTOR GetPixelFormatDescriptor()
- {
- PIXELFORMATDESCRIPTOR pfd;
- pfd.bReserved = 0;
- pfd.cAccumAlphaBits = 0;
- pfd.cAccumBits = 0;
- pfd.cAccumBlueBits = 0;
- pfd.cAccumGreenBits = 0;
- pfd.cAccumRedBits = 0;
- pfd.cAlphaBits = 0;
- pfd.cAlphaShift = 0;
- pfd.cAuxBuffers = 0;
- pfd.cBlueBits = 0;
- pfd.cBlueShift = 0;
- pfd.cColorBits = 32;
- pfd.cDepthBits = 32;
- pfd.cGreenBits = 0;
- pfd.cGreenShift = 0;
- pfd.cRedBits = 0;
- pfd.cRedShift = 0;
- pfd.cStencilBits = 0;
- pfd.dwDamageMask = 0;
- pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
- pfd.dwLayerMask = 0;
- pfd.dwVisibleMask = 0;
- pfd.iLayerType = 0;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- pfd.nVersion = 1;
- return pfd;
- }


Barutwanayo TheogenePosted Jan 29, 2018, 6:34 AM
Thanks very much for the artcile
Barutwanayo TheogenePosted Jan 29, 2018, 6:34 AM
Great man, nice things!