Skip to content

Instantly share code, notes, and snippets.

@gszauer
Last active May 4, 2019 02:56
Show Gist options
  • Save gszauer/5718416 to your computer and use it in GitHub Desktop.
Save gszauer/5718416 to your computer and use it in GitHub Desktop.
#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();
}
#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