Last active
May 4, 2019 02:56
-
-
Save gszauer/5718416 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#define WIN32_EXTRA_LEAN | |
#include <windows.h> | |
#include <cmath> | |
#include <gl/gl.h> | |
// #pragma comment(lib, "opengl32.lib") | |
// #pragma comment( linker, "/subsystem:windows" ) | |
#define WINDOW_WIDTH 800 | |
#define WINDOW_HEIGHT 600 | |
#define THROTTLE_FPS 1 | |
#define TARGET_FPS 60 | |
#define WND_CLASSNAME L"GLWindow" | |
#define WND_TITLE L"OpenGL Enabled Window" | |
#define START_FULLSCREEN false | |
void Initialize() {} | |
void Update() {} | |
void Render(); | |
void Shutdown() {} | |
void Suspend(bool paused) {} | |
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam); | |
bool CheckIfAlreadyRunning(); | |
void OpenGLUnbindContext(HWND hwnd, HDC hdc, HGLRC hglrc); | |
void OpenGLResetProjection(HWND hwnd); | |
HGLRC OpenGLBindContext(HDC hdc); | |
void ToggleFullscreen(HWND hwnd); | |
void SetDisplayMode(int width, int height, int bpp, int refreshRate); | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { | |
if (!hPrevInstance) { | |
if (CheckIfAlreadyRunning()) { | |
return FALSE; | |
} | |
} | |
#if THROTTLE_FPS | |
const int SKIP_TICKS = 1000 / TARGET_FPS; | |
DWORD next_game_tick = GetTickCount(); | |
int sleep_time = 0; | |
#endif | |
WNDCLASSEX wndclass; | |
wndclass.cbSize = sizeof(WNDCLASSEX); | |
wndclass.style = CS_HREDRAW | CS_VREDRAW; | |
wndclass.lpfnWndProc = WndProc; | |
wndclass.cbClsExtra = 0; | |
wndclass.cbWndExtra = sizeof(char*) * 2; // Store 2 pointers for screen toggling | |
wndclass.hInstance = hInstance; | |
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); | |
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); | |
wndclass.lpszMenuName = 0; | |
wndclass.lpszClassName = WND_CLASSNAME; | |
RegisterClassEx(&wndclass); | |
RECT windowRect; | |
SetRect(&windowRect, (GetSystemMetrics(SM_CXSCREEN) / 2) - (WINDOW_WIDTH / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) - (WINDOW_HEIGHT / 2), (GetSystemMetrics(SM_CXSCREEN) / 2) + (WINDOW_WIDTH / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) + (WINDOW_HEIGHT / 2)); | |
AdjustWindowRectEx(&windowRect, WS_VISIBLE | WS_OVERLAPPEDWINDOW, FALSE, 0); | |
// No resize style: (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) | |
HWND hwnd = CreateWindowEx(0, WND_CLASSNAME, WND_TITLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, szCmdLine); | |
HDC hdc = GetDC(hwnd); | |
HGLRC hglrc = OpenGLBindContext(hdc); | |
// Set togle variables BEFORE first fullscreen test | |
bool fullScreen = START_FULLSCREEN; | |
SetWindowLongPtr(hwnd, 0, (LONG_PTR)&fullScreen); | |
SetWindowLongPtr(hwnd, sizeof(char*), (LONG_PTR)&windowRect); | |
if (fullScreen) { | |
fullScreen = false; | |
ToggleFullscreen(hwnd); | |
} | |
Initialize(); | |
ShowWindow(hwnd, SW_SHOW); | |
UpdateWindow(hwnd); | |
OpenGLResetProjection(hwnd); | |
MSG msg; | |
while (true) { | |
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { | |
if (msg.message == WM_QUIT) | |
break; | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
#if THROTTLE_FPS | |
next_game_tick += SKIP_TICKS; | |
sleep_time = next_game_tick - GetTickCount(); | |
if (sleep_time >= 0) | |
Sleep(sleep_time); | |
#endif | |
Update(); | |
Render(); | |
SwapBuffers(hdc); | |
} | |
Shutdown(); | |
OpenGLUnbindContext(hwnd, hdc, hglrc); | |
return (int)msg.wParam; | |
} | |
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { | |
switch (iMsg) { | |
case WM_CREATE: | |
break; | |
case WM_CLOSE: | |
DestroyWindow(hwnd); | |
break; | |
case WM_DESTROY: | |
PostQuitMessage(0); | |
break; | |
case WM_KEYDOWN: | |
case WM_SYSKEYDOWN: | |
if (wParam == VK_RETURN) | |
if ((HIWORD(lParam) & KF_ALTDOWN)) | |
ToggleFullscreen(hwnd); | |
break; | |
case WM_SIZE: | |
OpenGLResetProjection(hwnd); | |
break; | |
case WM_ACTIVATE: | |
if (LOWORD(wParam) != WA_INACTIVE) | |
Suspend(false); | |
else | |
Suspend(true); | |
break; | |
case WM_SYSKEYUP: | |
case WM_SYSCHAR: | |
case WM_PAINT: | |
case WM_ERASEBKGND: | |
return 0; | |
} | |
return DefWindowProc(hwnd, iMsg, wParam, lParam); | |
} | |
HGLRC OpenGLBindContext(HDC hdc) { | |
PIXELFORMATDESCRIPTOR pfd; | |
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); | |
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); | |
pfd.nVersion = 1; | |
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; | |
pfd.iPixelType = PFD_TYPE_RGBA; | |
pfd.cColorBits = 24; | |
pfd.cDepthBits = 32; | |
pfd.cStencilBits = 8; | |
pfd.iLayerType = PFD_MAIN_PLANE; | |
int pixelFormat = ChoosePixelFormat(hdc, &pfd); | |
SetPixelFormat(hdc, pixelFormat, &pfd); | |
HGLRC context = wglCreateContext(hdc); | |
wglMakeCurrent(hdc, context); | |
return context; | |
} | |
void OpenGLUnbindContext(HWND hwnd, HDC hdc, HGLRC hglrc) { | |
wglMakeCurrent(NULL, NULL); | |
wglDeleteContext(hglrc); | |
ReleaseDC(hwnd, hdc); | |
} | |
bool CheckIfAlreadyRunning(void) { | |
HWND hWnd = FindWindow(WND_CLASSNAME, WND_TITLE); | |
if (hWnd) { | |
if (IsIconic(hWnd)) | |
ShowWindow(hWnd, SW_RESTORE); | |
SetForegroundWindow(hWnd); | |
return true; | |
} | |
return false; | |
} | |
void ToggleFullscreen(HWND hwnd) { | |
bool* fullScreen = (bool*)GetWindowLongPtr(hwnd, 0); | |
RECT* windowRect = (RECT*)GetWindowLongPtr(hwnd, sizeof(char*)); | |
if (!(*fullScreen)) { | |
GetWindowRect(hwnd, windowRect); | |
HDC hdc = GetDC(hwnd); | |
SetDisplayMode(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), GetDeviceCaps(hdc, BITSPIXEL), GetDeviceCaps(hdc, VREFRESH)); | |
SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP); | |
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); | |
SetWindowPos(hwnd, 0, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_NOZORDER); | |
ShowCursor(FALSE); | |
ReleaseDC(hwnd, hdc); | |
*fullScreen = true; | |
} | |
else { | |
SetDisplayMode(0, 0, 0, 0); | |
SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); | |
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); | |
int iWindowWidth = windowRect->right - windowRect->left; | |
int iWindowHeight = windowRect->bottom - windowRect->top; | |
SetWindowPos(hwnd, 0, windowRect->left, windowRect->top, iWindowWidth, iWindowHeight, SWP_NOZORDER); | |
ShowCursor(TRUE); | |
*fullScreen = false; | |
} | |
OpenGLResetProjection(hwnd); | |
} | |
void SetDisplayMode(int width, int height, int bpp, int refreshRate) { | |
if (width == 0 && height == 0 && bpp == 0 && refreshRate == 0) { | |
ChangeDisplaySettings(NULL, 0); | |
return; | |
} | |
DEVMODE dm; | |
dm.dmSize = sizeof(DEVMODE); | |
int i = 0; | |
while (EnumDisplaySettings(NULL, i++, &dm)) { | |
if (dm.dmPelsWidth == width && dm.dmPelsHeight == height && | |
dm.dmBitsPerPel == bpp && dm.dmDisplayFrequency == refreshRate) { | |
if (ChangeDisplaySettings(&dm, CDS_TEST) == DISP_CHANGE_SUCCESSFUL) { | |
ChangeDisplaySettings(&dm, CDS_FULLSCREEN); | |
return; | |
} | |
} | |
} | |
} | |
void OpenGLResetProjection(HWND hwnd) { | |
const float openGLNear = 0.1f; | |
const float openGLFar = 1000.0f; | |
RECT window = { 0 }; | |
GetClientRect(hwnd, &window); | |
glViewport(0, 0, window.right - window.left, window.bottom - window.top); | |
float fov = 62.0f; | |
float aspect = (float)(window.right - window.left) / (float)(window.bottom - window.top); | |
float top = openGLNear * float(tanf(fov * 3.14159265f / 360.0f)); | |
float bottom = -1.0f * top; | |
float right = bottom * aspect; | |
float left = top * aspect; | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glFrustum(left, right, bottom, top, openGLNear, openGLFar); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
} | |
void Render() { | |
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |
glMatrixMode(GL_MODELVIEW); | |
glPushMatrix(); | |
glLoadIdentity(); | |
glTranslatef(0.0f, 0.0f, -6.0f); | |
glBegin(GL_TRIANGLES); | |
glColor3f(1.0f, 0.0f, 0.0f); | |
glVertex3f(0.0f, 1.0f, 0.0f); | |
glColor3f(0.0f, 1.0f, 0.0f); | |
glVertex3f(-1.0f, -1.0f, 1.0f); | |
glColor3f(0.0f, 0.0f, 1.0f); | |
glVertex3f(1.0f, -1.0f, 1.0f); | |
glEnd(); | |
glPopMatrix(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#define WIN32_EXTRA_LEAN | |
#include <windows.h> | |
#include <cstdio> | |
#include <cmath> | |
#include "glad.h" | |
#include <gl/gl.h> | |
// #pragma comment(lib, "opengl32.lib") | |
#pragma comment( linker, "/subsystem:windows" ) | |
#define WINDOW_WIDTH 800 | |
#define WINDOW_HEIGHT 600 | |
#define THROTTLE_FPS 1 | |
#define TARGET_FPS 60 | |
#define WND_CLASSNAME L"GLWindow" | |
#define WND_TITLE L"OpenGL Enabled Window" | |
#define START_FULLSCREEN false | |
void Initialize(); | |
void Update() {} | |
void Render(); | |
void Shutdown(); | |
void Suspend(bool paused) {} | |
unsigned int CompieShader(); | |
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam); | |
bool CheckIfAlreadyRunning(); | |
void OpenGLUnbindContext(HWND hwnd, HDC hdc, HGLRC hglrc); | |
void OpenGLResetProjection(HWND hwnd); | |
HGLRC OpenGLBindContext(HDC hdc, HWND hwnd); | |
void ToggleFullscreen(HWND hwnd); | |
void SetDisplayMode(int width, int height, int bpp, int refreshRate); | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { | |
if (!hPrevInstance) { | |
if (CheckIfAlreadyRunning()) { | |
return FALSE; | |
} | |
} | |
#if THROTTLE_FPS | |
const int SKIP_TICKS = 1000 / TARGET_FPS; | |
DWORD next_game_tick = GetTickCount(); | |
int sleep_time = 0; | |
#endif | |
WNDCLASSEX wndclass; | |
wndclass.cbSize = sizeof(WNDCLASSEX); | |
wndclass.style = CS_HREDRAW | CS_VREDRAW; | |
wndclass.lpfnWndProc = WndProc; | |
wndclass.cbClsExtra = 0; | |
wndclass.cbWndExtra = sizeof(char*) * 3; // Store 3 pointers for screen toggling | |
wndclass.hInstance = hInstance; | |
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); | |
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); | |
wndclass.lpszMenuName = 0; | |
wndclass.lpszClassName = WND_CLASSNAME; | |
RegisterClassEx(&wndclass); | |
RECT windowRect; | |
SetRect(&windowRect, (GetSystemMetrics(SM_CXSCREEN) / 2) - (WINDOW_WIDTH / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) - (WINDOW_HEIGHT / 2), (GetSystemMetrics(SM_CXSCREEN) / 2) + (WINDOW_WIDTH / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) + (WINDOW_HEIGHT / 2)); | |
AdjustWindowRectEx(&windowRect, WS_VISIBLE | WS_OVERLAPPEDWINDOW, FALSE, 0); | |
// No resize style: (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) | |
HWND hwnd = CreateWindowEx(0, WND_CLASSNAME, WND_TITLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, szCmdLine); | |
// Set togle variables BEFORE first fullscreen test | |
bool fullScreen = START_FULLSCREEN; | |
SetWindowLongPtr(hwnd, 0, (LONG_PTR)&fullScreen); | |
SetWindowLongPtr(hwnd, sizeof(char*), (LONG_PTR)&windowRect); | |
SetWindowLongPtr(hwnd, sizeof(char*) * 2, (LONG_PTR)0); | |
HDC hdc = GetDC(hwnd); | |
HGLRC hglrc = OpenGLBindContext(hdc, hwnd); | |
if (fullScreen) { | |
fullScreen = false; | |
ToggleFullscreen(hwnd); | |
} | |
Initialize(); | |
ShowWindow(hwnd, SW_SHOW); | |
UpdateWindow(hwnd); | |
OpenGLResetProjection(hwnd); | |
MSG msg; | |
while (true) { | |
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { | |
if (msg.message == WM_QUIT) | |
break; | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
#if THROTTLE_FPS | |
next_game_tick += SKIP_TICKS; | |
sleep_time = next_game_tick - GetTickCount(); | |
if (sleep_time >= 0) | |
Sleep(sleep_time); | |
#endif | |
Update(); | |
Render(); | |
SwapBuffers(hdc); | |
} | |
Shutdown(); | |
OpenGLUnbindContext(hwnd, hdc, hglrc); | |
return (int)msg.wParam; | |
} | |
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { | |
switch (iMsg) { | |
case WM_CREATE: | |
break; | |
case WM_CLOSE: | |
DestroyWindow(hwnd); | |
break; | |
case WM_DESTROY: | |
PostQuitMessage(0); | |
break; | |
case WM_KEYDOWN: | |
case WM_SYSKEYDOWN: | |
if (wParam == VK_RETURN) | |
if ((HIWORD(lParam) & KF_ALTDOWN)) | |
ToggleFullscreen(hwnd); | |
break; | |
case WM_SIZE: | |
OpenGLResetProjection(hwnd); | |
break; | |
case WM_ACTIVATE: | |
if (LOWORD(wParam) != WA_INACTIVE) | |
Suspend(false); | |
else | |
Suspend(true); | |
break; | |
case WM_SYSKEYUP: | |
case WM_SYSCHAR: | |
case WM_PAINT: | |
case WM_ERASEBKGND: | |
return 0; | |
} | |
return DefWindowProc(hwnd, iMsg, wParam, lParam); | |
} | |
HGLRC OpenGLBindContext(HDC hdc, HWND hwnd) { | |
PIXELFORMATDESCRIPTOR pfd; | |
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); | |
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); | |
pfd.nVersion = 1; | |
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; | |
pfd.iPixelType = PFD_TYPE_RGBA; | |
pfd.cColorBits = 24; | |
pfd.cDepthBits = 32; | |
pfd.cStencilBits = 8; | |
pfd.iLayerType = PFD_MAIN_PLANE; | |
int pixelFormat = ChoosePixelFormat(hdc, &pfd); | |
SetPixelFormat(hdc, pixelFormat, &pfd); | |
HGLRC context = wglCreateContext(hdc); | |
wglMakeCurrent(hdc, context); | |
if (!gladLoadGL()) { | |
OutputDebugStringA("Could not initialize GLAD"); | |
} | |
else { | |
char output[125]; | |
sprintf(output, "OpenGL Version %d.%d loaded", GLVersion.major, GLVersion.minor); | |
OutputDebugStringA(output); | |
} | |
SetWindowLongPtr(hwnd, sizeof(char*) * 2, (LONG_PTR)1); | |
return context; | |
} | |
void OpenGLUnbindContext(HWND hwnd, HDC hdc, HGLRC hglrc) { | |
//glad | |
wglMakeCurrent(NULL, NULL); | |
wglDeleteContext(hglrc); | |
ReleaseDC(hwnd, hdc); | |
} | |
bool CheckIfAlreadyRunning(void) { | |
HWND hWnd = FindWindow(WND_CLASSNAME, WND_TITLE); | |
if (hWnd) { | |
if (IsIconic(hWnd)) | |
ShowWindow(hWnd, SW_RESTORE); | |
SetForegroundWindow(hWnd); | |
return true; | |
} | |
return false; | |
} | |
void ToggleFullscreen(HWND hwnd) { | |
bool* fullScreen = (bool*)GetWindowLongPtr(hwnd, 0); | |
RECT* windowRect = (RECT*)GetWindowLongPtr(hwnd, sizeof(char*)); | |
if (!(*fullScreen)) { | |
GetWindowRect(hwnd, windowRect); | |
HDC hdc = GetDC(hwnd); | |
SetDisplayMode(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), GetDeviceCaps(hdc, BITSPIXEL), GetDeviceCaps(hdc, VREFRESH)); | |
SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP); | |
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); | |
SetWindowPos(hwnd, 0, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_NOZORDER); | |
ShowCursor(FALSE); | |
ReleaseDC(hwnd, hdc); | |
*fullScreen = true; | |
} | |
else { | |
SetDisplayMode(0, 0, 0, 0); | |
SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); | |
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); | |
int iWindowWidth = windowRect->right - windowRect->left; | |
int iWindowHeight = windowRect->bottom - windowRect->top; | |
SetWindowPos(hwnd, 0, windowRect->left, windowRect->top, iWindowWidth, iWindowHeight, SWP_NOZORDER); | |
ShowCursor(TRUE); | |
*fullScreen = false; | |
} | |
OpenGLResetProjection(hwnd); | |
} | |
void SetDisplayMode(int width, int height, int bpp, int refreshRate) { | |
if (width == 0 && height == 0 && bpp == 0 && refreshRate == 0) { | |
ChangeDisplaySettings(NULL, 0); | |
return; | |
} | |
DEVMODE dm; | |
dm.dmSize = sizeof(DEVMODE); | |
int i = 0; | |
while (EnumDisplaySettings(NULL, i++, &dm)) { | |
if (dm.dmPelsWidth == width && dm.dmPelsHeight == height && | |
dm.dmBitsPerPel == bpp && dm.dmDisplayFrequency == refreshRate) { | |
if (ChangeDisplaySettings(&dm, CDS_TEST) == DISP_CHANGE_SUCCESSFUL) { | |
ChangeDisplaySettings(&dm, CDS_FULLSCREEN); | |
return; | |
} | |
} | |
} | |
} | |
void OpenGLResetProjection(HWND hwnd) { | |
char* intialized = (char*)GetWindowLongPtr(hwnd, sizeof(char*) * 2); | |
if (intialized == 0) { | |
return; | |
} | |
const float openGLNear = 0.1f; | |
const float openGLFar = 1000.0f; | |
RECT window = { 0 }; | |
GetClientRect(hwnd, &window); | |
glViewport(0, 0, window.right - window.left, window.bottom - window.top); | |
float fov = 62.0f; | |
float aspect = (float)(window.right - window.left) / (float)(window.bottom - window.top); | |
float top = openGLNear * float(tanf(fov * 3.14159265f / 360.0f)); | |
float bottom = -1.0f * top; | |
float right = bottom * aspect; | |
float left = top * aspect; | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glFrustum(left, right, bottom, top, openGLNear, openGLFar); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
} | |
/// Application | |
unsigned int g_nVBO; | |
unsigned int g_nShaderProgram; | |
unsigned int CompieShader() { | |
int success; | |
char infoLog[512]; | |
const char* vertexShaderSource = "#version 330 core \n\ | |
layout(location = 0) in vec3 aPos; \n\ | |
void main() { \n\ | |
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); \n\ | |
}"; | |
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); | |
glCompileShader(vertexShader); | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) { | |
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | |
OutputDebugStringA(infoLog); | |
} | |
const char* fragmentShaderSource = "#version 330 core \n\ | |
out vec4 FragColor;\n\ | |
void main() {\n\ | |
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); \n\ | |
}"; | |
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); | |
glCompileShader(fragmentShader); | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) { | |
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | |
OutputDebugStringA(infoLog); | |
} | |
unsigned int shaderProgram; | |
shaderProgram = glCreateProgram(); | |
glAttachShader(shaderProgram, vertexShader); | |
glAttachShader(shaderProgram, fragmentShader); | |
glLinkProgram(shaderProgram); | |
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); | |
if (!success) { | |
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); | |
OutputDebugStringA(infoLog); | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
return shaderProgram; | |
} | |
void Initialize() { | |
g_nShaderProgram = CompieShader(); | |
float vertices[] = { | |
-0.5f, -0.5f, 0.0f, | |
0.5f, -0.5f, 0.0f, | |
0.0f, 0.5f, 0.0f | |
}; | |
glGenBuffers(1, &g_nVBO); | |
glBindBuffer(GL_ARRAY_BUFFER, g_nVBO); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
} | |
void Shutdown() { | |
glDeleteBuffers(1, &g_nVBO); | |
glDeleteShader(g_nShaderProgram); | |
} | |
void Render() { | |
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |
glUseProgram(g_nShaderProgram); | |
glBindBuffer(GL_ARRAY_BUFFER, g_nVBO); | |
// This could be replaced with a vao, but i like manually specifying these | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); | |
glEnableVertexAttribArray(0); | |
glDrawArrays(GL_TRIANGLES, 0, 3); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glUseProgram(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment