switched from egl to glx and wgl
This commit is contained in:
parent
c28c07dad4
commit
98af446a2f
30
Makefile
30
Makefile
|
@ -1,13 +1,29 @@
|
|||
FLAGS=-fPIC --shared
|
||||
LIBS=-lX11 -lGL
|
||||
FILES=src/openwindow.c deps/lib/glad.a
|
||||
|
||||
libopenwindow.so: glad.a
|
||||
gcc ${FLAGS} -o libopenwindow.so ${FILES}
|
||||
LINUX_FILES=src/openwindow.c deps/lib/glad_linux.a
|
||||
|
||||
WINDOWS_LIBS=-lopengl32 -lgdi32
|
||||
WINDOWS_FILES=src/openwindow.c deps/lib/glad_windows.a
|
||||
|
||||
OUTPUT=lib/
|
||||
|
||||
all: libopenwindow.so libopenwindow.dll
|
||||
|
||||
libopenwindow.so: glad_linux.a
|
||||
mkdir -p ${OUTPUT}
|
||||
gcc ${FLAGS} -o ${OUTPUT}libopenwindow.so ${LINUX_FILES}
|
||||
|
||||
libopenwindow.dll: glad_windows.a
|
||||
mkdir -p ${OUTPUT}
|
||||
x86_64-w64-mingw32-gcc ${FLAGS} -o ${OUTPUT}libopenwindow.dll ${WINDOWS_FILES} ${WINDOWS_LIBS}
|
||||
|
||||
GLAD_FLAGS=-fPIC -c
|
||||
GLAD_FILES=deps/src/glad.c
|
||||
|
||||
glad.a: deps/src/glad.o
|
||||
gcc ${GLAD_FLAGS} -o deps/src/glad.o ${GLAD_FILES}
|
||||
ar rcs deps/lib/glad.a deps/src/glad.o
|
||||
glad_linux.a: deps/src/glad.c
|
||||
gcc ${GLAD_FLAGS} -o deps/src/glad_linux.o ${GLAD_FILES}
|
||||
ar rcs deps/lib/glad_linux.a deps/src/glad_linux.o
|
||||
|
||||
glad_windows.a: deps/src/glad.c
|
||||
x86_64-w64-mingw32-gcc ${GLAD_FLAGS} -o deps/src/glad_windows.o ${GLAD_FILES}
|
||||
ar rcs deps/lib/glad_windows.a deps/src/glad_windows.o
|
||||
|
|
24
main.c
24
main.c
|
@ -1,6 +1,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "deps/include/glad/glad.h"
|
||||
#include "src/openwindow.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <X11/keysym.h>
|
||||
|
@ -9,8 +12,6 @@
|
|||
#include <X11/Xlib.h>
|
||||
#undef Window
|
||||
|
||||
#include "src/openwindow.h"
|
||||
|
||||
void xevent(Window * w, XEvent xev) {
|
||||
switch (xev.type)
|
||||
{
|
||||
|
@ -37,6 +38,10 @@ void xevent(Window * w, XEvent xev) {
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
const char * fss =
|
||||
|
@ -52,22 +57,25 @@ int main(void)
|
|||
{
|
||||
Window w = openWindow("Window", 800, 600);
|
||||
|
||||
// TODO: do this
|
||||
#ifndef _WIN32
|
||||
windowSetEventHandler(&w, xevent);
|
||||
#endif // _WIN32
|
||||
|
||||
while (!w.close) {
|
||||
while (!w.close)
|
||||
{
|
||||
windowHandleEvents(&w);
|
||||
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, 800, 600);
|
||||
|
||||
glColor3f(1.0, 0, 0);
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
glVertex2f(-0.5, -0.5);
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex2f(0.5, -0.5);
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
glVertex2f(0.0, 0.5);
|
||||
glEnd();
|
||||
glFlush();
|
||||
|
||||
windowDraw(w);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "deltatime.h"
|
||||
|
||||
struct timespec deltaTimeX1, deltaTimeX2;
|
||||
|
||||
#include <time.h>
|
||||
|
||||
double getDeltaTime() {
|
||||
clock_gettime(CLOCK_MONOTONIC, &deltaTimeX2);
|
||||
double dt = (deltaTimeX2.tv_sec - deltaTimeX1.tv_sec) + (deltaTimeX2.tv_nsec - deltaTimeX1.tv_nsec) / 1e9;
|
||||
deltaTimeX1 = deltaTimeX2;
|
||||
|
||||
return dt;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef DELTA_TIME_H_
|
||||
#define DELTA_TIME_H_
|
||||
|
||||
extern struct timespec deltaTimeX1, deltaTimeX2;
|
||||
|
||||
double getDeltaTime();
|
||||
|
||||
#endif // DELTA_TIME_H_
|
|
@ -0,0 +1,87 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "graphics.h"
|
||||
|
||||
#include "../deps/include/glad/glad.h"
|
||||
|
||||
const char * defaultVertexShader =
|
||||
"#version 330 core\n"
|
||||
"precision mediump float;"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"}";
|
||||
|
||||
const char * defaultFragmentShader =
|
||||
"#version 330 core\n"
|
||||
"precision mediump float;"
|
||||
"out vec4 FragColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
|
||||
"}";
|
||||
|
||||
void compileShader(GLuint program, const char * source, GLenum type) {
|
||||
GLint status = 0;
|
||||
|
||||
GLuint shader = glCreateShader(type);
|
||||
|
||||
glShaderSource(shader, 1, &source, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
|
||||
if (status != GL_TRUE) {
|
||||
fprintf(stderr, "Failed to compile %s shader!\n", type == GL_VERTEX_SHADER ? "vertex" : "fragment");
|
||||
|
||||
GLint len;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
char * infolog = (char*) malloc(len * sizeof(char));
|
||||
glGetShaderInfoLog(shader, len, NULL, infolog);
|
||||
fprintf(stderr, "Shader compilation error: %s\n", infolog);
|
||||
free(infolog);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glAttachShader(program, shader);
|
||||
}
|
||||
|
||||
void linkProgram(GLuint program) {
|
||||
int status = 0;
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
if (status != GL_TRUE) {
|
||||
fprintf(stderr, "Failed to link program!\n");
|
||||
|
||||
GLint len;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
|
||||
char * infolog = (char*) malloc(len * sizeof(char));
|
||||
glGetProgramInfoLog(program, len, NULL, infolog);
|
||||
fprintf(stderr, "Program linking error: %s", infolog);
|
||||
free(infolog);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Graphics createGraphics(const char * vss, const char * fss) {
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
if (vss == NULL) vss = defaultVertexShader;
|
||||
if (fss == NULL) fss = defaultFragmentShader;
|
||||
|
||||
compileShader(program, vss, GL_VERTEX_SHADER);
|
||||
compileShader(program, fss, GL_FRAGMENT_SHADER);
|
||||
|
||||
linkProgram(program);
|
||||
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
|
||||
return (Graphics) {
|
||||
.program = program,
|
||||
.vao = vao,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef GRAPHICS_H_
|
||||
#define GRAPHICS_H_
|
||||
|
||||
#include "../deps/include/glad/glad.h"
|
||||
|
||||
extern const char * defaultVertexShader, * defaultFragmentShader;
|
||||
|
||||
typedef struct {
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
} Graphics;
|
||||
|
||||
Graphics createGraphics(const char * vss, const char * fss);
|
||||
|
||||
#endif // GRAPHICS_H_
|
|
@ -0,0 +1,82 @@
|
|||
#include <windows.h>
|
||||
#include "../deps/include/glad/glad.h"
|
||||
#include <stdio.h>
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
HGLRC CreateOpenGLContext(HWND hwnd, HDC hdc) {
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 0,
|
||||
PFD_MAIN_PLANE, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
int pf = ChoosePixelFormat(hdc, &pfd);
|
||||
SetPixelFormat(hdc, pf, &pfd);
|
||||
return wglCreateContext(hdc);
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||
const char CLASS_NAME[] = "WGLSampleWindow";
|
||||
|
||||
WNDCLASS wc = {0};
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = CLASS_NAME;
|
||||
RegisterClass(&wc);
|
||||
|
||||
HWND hwnd = CreateWindowEx(0, CLASS_NAME, "OpenGL with WGL and GLAD", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
|
||||
|
||||
if (!hwnd) return -1;
|
||||
|
||||
HDC hdc = GetDC(hwnd);
|
||||
HGLRC hglrc = CreateOpenGLContext(hwnd, hdc);
|
||||
wglMakeCurrent(hdc, hglrc);
|
||||
|
||||
// Load OpenGL functions using GLAD
|
||||
if (!gladLoadGL()) {
|
||||
MessageBoxA(NULL, "Failed to initialize GLAD", "Error", MB_OK | MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
while (1) {
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT) goto cleanup;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
// OpenGL rendering
|
||||
glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
SwapBuffers(hdc);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(hglrc);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
DestroyWindow(hwnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (uMsg) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_DESTROY:
|
||||
return 0;
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,106 @@
|
|||
#include <windows.h>
|
||||
#include "../deps/include/glad/glad.h"
|
||||
|
||||
LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (msg) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
WNDCLASSEX wcex = {0};
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_CLASSDC;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = GetModuleHandle(NULL);
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = 0;
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = "OpenGL";
|
||||
wcex.hIconSm = NULL;
|
||||
|
||||
if (!RegisterClassEx(&wcex)) {
|
||||
MessageBox(NULL, "Failed to register window class", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HWND hwnd = CreateWindow("OpenGL", "OpenGL", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, GetModuleHandle(NULL), NULL);
|
||||
|
||||
if (hwnd == NULL) {
|
||||
MessageBox(NULL, "Failed to create window", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HDC hdc = GetDC(hwnd);
|
||||
if (hdc == NULL) {
|
||||
MessageBox(NULL, "Failed to get device context", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd = {0};
|
||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 32;
|
||||
pfd.cDepthBits = 24;
|
||||
pfd.cStencilBits = 8;
|
||||
|
||||
int format = ChoosePixelFormat(hdc, &pfd);
|
||||
if (format == 0) {
|
||||
MessageBox(NULL, "Failed to choose pixel format", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(hdc, format, &pfd)) {
|
||||
MessageBox(NULL, "Failed to set pixel format", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HGLRC hrc = wglCreateContext(hdc);
|
||||
if (hrc == NULL) {
|
||||
MessageBox(NULL, "Failed to create OpenGL context", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(hdc, hrc)) {
|
||||
MessageBox(NULL, "Failed to make OpenGL context current", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)wglGetProcAddress)) {
|
||||
MessageBox(NULL, "Failed to load OpenGL functions", "Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (1) {
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
if (msg.message == WM_QUIT) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
SwapBuffers(hdc);
|
||||
}
|
||||
}
|
||||
|
||||
wglDeleteContext(hrc);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
DestroyWindow(hwnd);
|
||||
UnregisterClass("OpenGL", GetModuleHandle(NULL));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Binary file not shown.
|
@ -0,0 +1,107 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "../deps/include/glad/glad.h"
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
printf("AAA\n");
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Register the window class
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "GLSample", NULL };
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
// Create the window
|
||||
HWND hWnd = CreateWindowEx(
|
||||
0,
|
||||
"GLSample",
|
||||
"OpenGL Sample",
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
256,
|
||||
256,
|
||||
NULL,
|
||||
NULL,
|
||||
GetModuleHandle(NULL),
|
||||
NULL
|
||||
);
|
||||
|
||||
// Enable OpenGL
|
||||
HDC hDC = GetDC(hWnd);
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
32,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
int iFormat = ChoosePixelFormat(hDC, &pfd);
|
||||
SetPixelFormat(hDC, iFormat, &pfd);
|
||||
|
||||
// Create the OpenGL context
|
||||
HGLRC hRC = wglCreateContext(hDC);
|
||||
wglMakeCurrent(hDC, hRC);
|
||||
|
||||
gladLoadGLLoader((GLADloadproc)wglGetProcAddress);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
// Clear the screen
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw a triangle
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
glVertex2f(-0.5f, -0.5f);
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex2f(0.5f, -0.5f);
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
glVertex2f(0.0f, 0.5f);
|
||||
glEnd();
|
||||
|
||||
// Swap buffers
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
|
||||
// Disable OpenGL
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(hRC);
|
||||
ReleaseDC(hWnd, hDC);
|
||||
|
||||
// Clean up
|
||||
UnregisterClass("GLSample", GetModuleHandle(NULL));
|
||||
return msg.wParam;
|
||||
}
|
||||
|
Binary file not shown.
|
@ -0,0 +1,152 @@
|
|||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
// Global variables
|
||||
HINSTANCE hInstance;
|
||||
HWND hWnd;
|
||||
HDC hDC;
|
||||
HGLRC hRC;
|
||||
|
||||
// Forward declarations
|
||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
void EnableOpenGL(HWND, HDC*, HGLRC*);
|
||||
void DisableOpenGL(HWND, HDC, HGLRC);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
// Register the window class
|
||||
WNDCLASSEX wc = {
|
||||
sizeof(WNDCLASSEX),
|
||||
CS_CLASSDC,
|
||||
WndProc,
|
||||
0L,
|
||||
0L,
|
||||
hInst,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"GLSample",
|
||||
NULL
|
||||
};
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
// Create the window
|
||||
hWnd = CreateWindowEx(
|
||||
0,
|
||||
"GLSample",
|
||||
"OpenGL Sample",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
256,
|
||||
256,
|
||||
NULL,
|
||||
NULL,
|
||||
hInst,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Enable OpenGL
|
||||
EnableOpenGL(hWnd, &hDC, &hRC);
|
||||
|
||||
// Show the window
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
// Disable OpenGL
|
||||
DisableOpenGL(hWnd, hDC, hRC);
|
||||
|
||||
// Clean up
|
||||
UnregisterClass("GLSample", hInstance);
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_SIZE:
|
||||
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hWnd, &ps);
|
||||
|
||||
// Clear the screen
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw a triangle
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
glVertex2f(-0.5f, -0.5f);
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex2f(0.5f, -0.5f);
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
glVertex2f(0.0f, 0.5f);
|
||||
glEnd();
|
||||
|
||||
// Swap buffers
|
||||
SwapBuffers(hDC);
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EnableOpenGL(HWND hWnd, HDC* hDC, HGLRC* hRC)
|
||||
{
|
||||
*hDC = GetDC(hWnd);
|
||||
|
||||
// Set the pixel format
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
32,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
int iFormat = ChoosePixelFormat(*hDC, &pfd);
|
||||
SetPixelFormat(*hDC, iFormat, &pfd);
|
||||
|
||||
// Create the OpenGL context
|
||||
*hRC = wglCreateContext(*hDC);
|
||||
wglMakeCurrent(*hDC, *hRC);
|
||||
}
|
||||
|
||||
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
|
||||
{
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(hRC);
|
||||
ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,256 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||
|
||||
// Helper to check for extension string presence. Adapted from:
|
||||
// http://www.opengl.org/resources/features/OGLextensions/
|
||||
static bool isExtensionSupported(const char *extList, const char *extension)
|
||||
{
|
||||
const char *start;
|
||||
const char *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = strchr(extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return false;
|
||||
|
||||
/* It takes a bit of care to be fool-proof about parsing the
|
||||
OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
etc. */
|
||||
for (start=extList;;) {
|
||||
where = strstr(start, extension);
|
||||
|
||||
if (!where)
|
||||
break;
|
||||
|
||||
terminator = where + strlen(extension);
|
||||
|
||||
if ( where == start || *(where - 1) == ' ' )
|
||||
if ( *terminator == ' ' || *terminator == '\0' )
|
||||
return true;
|
||||
|
||||
start = terminator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Display *display = XOpenDisplay(NULL);
|
||||
|
||||
if (!display)
|
||||
{
|
||||
printf("Failed to open X display\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Get a matching FB config
|
||||
static int visual_attribs[] =
|
||||
{
|
||||
GLX_X_RENDERABLE , True,
|
||||
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE , GLX_RGBA_BIT,
|
||||
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
|
||||
GLX_RED_SIZE , 8,
|
||||
GLX_GREEN_SIZE , 8,
|
||||
GLX_BLUE_SIZE , 8,
|
||||
GLX_ALPHA_SIZE , 8,
|
||||
GLX_DEPTH_SIZE , 24,
|
||||
GLX_STENCIL_SIZE , 8,
|
||||
GLX_DOUBLEBUFFER , True,
|
||||
//GLX_SAMPLE_BUFFERS , 1,
|
||||
//GLX_SAMPLES , 4,
|
||||
None
|
||||
};
|
||||
|
||||
int glx_major, glx_minor;
|
||||
|
||||
// FBConfigs were added in GLX version 1.3.
|
||||
if ( !glXQueryVersion( display, &glx_major, &glx_minor ) ||
|
||||
( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
|
||||
{
|
||||
printf("Invalid GLX version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf( "Getting matching framebuffer configs\n" );
|
||||
int fbcount;
|
||||
GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount);
|
||||
if (!fbc)
|
||||
{
|
||||
printf( "Failed to retrieve a framebuffer config\n" );
|
||||
exit(1);
|
||||
}
|
||||
printf( "Found %d matching FB configs.\n", fbcount );
|
||||
|
||||
// Pick the FB config/visual with the most samples per pixel
|
||||
printf( "Getting XVisualInfos\n" );
|
||||
int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
|
||||
|
||||
int i;
|
||||
for (i=0; i<fbcount; ++i)
|
||||
{
|
||||
XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] );
|
||||
if ( vi )
|
||||
{
|
||||
int samp_buf, samples;
|
||||
glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
|
||||
glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples );
|
||||
|
||||
printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
|
||||
" SAMPLES = %d\n",
|
||||
i, vi -> visualid, samp_buf, samples );
|
||||
|
||||
if ( best_fbc < 0 || samp_buf && samples > best_num_samp )
|
||||
best_fbc = i, best_num_samp = samples;
|
||||
if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
|
||||
worst_fbc = i, worst_num_samp = samples;
|
||||
}
|
||||
XFree( vi );
|
||||
}
|
||||
|
||||
GLXFBConfig bestFbc = fbc[ best_fbc ];
|
||||
|
||||
// Be sure to free the FBConfig list allocated by glXChooseFBConfig()
|
||||
XFree( fbc );
|
||||
|
||||
// Get a visual
|
||||
XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
|
||||
printf( "Chosen visual ID = 0x%x\n", vi->visualid );
|
||||
|
||||
printf( "Creating colormap\n" );
|
||||
XSetWindowAttributes swa;
|
||||
Colormap cmap;
|
||||
swa.colormap = cmap = XCreateColormap( display,
|
||||
RootWindow( display, vi->screen ),
|
||||
vi->visual, AllocNone );
|
||||
swa.background_pixmap = None ;
|
||||
swa.border_pixel = 0;
|
||||
swa.event_mask = StructureNotifyMask;
|
||||
|
||||
printf( "Creating window\n" );
|
||||
Window win = XCreateWindow( display, RootWindow( display, vi->screen ),
|
||||
0, 0, 100, 100, 0, vi->depth, InputOutput,
|
||||
vi->visual,
|
||||
CWBorderPixel|CWColormap|CWEventMask, &swa );
|
||||
if ( !win )
|
||||
{
|
||||
printf( "Failed to create window.\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Done with the visual info data
|
||||
XFree( vi );
|
||||
|
||||
XStoreName( display, win, "GL 3.0 Window" );
|
||||
|
||||
printf( "Mapping window\n" );
|
||||
XMapWindow( display, win );
|
||||
|
||||
// Get the default screen's GLX extension list
|
||||
//const char *glxExts = glXQueryExtensionsString( display,
|
||||
// DefaultScreen( display ) );
|
||||
|
||||
// NOTE: It is not necessary to create or make current to a context before
|
||||
// calling glXGetProcAddressARB
|
||||
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
|
||||
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
|
||||
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
||||
|
||||
GLXContext ctx = 0;
|
||||
|
||||
// Install an X error handler so the application won't exit if GL 3.0
|
||||
// context allocation fails.
|
||||
//
|
||||
// Note this error handler is global. All display connections in all threads
|
||||
// of a process use the same error handler, so be sure to guard against other
|
||||
// threads issuing X commands while this code is running.
|
||||
//ctxErrorOccurred = false;
|
||||
//int (*oldHandler)(Display*, XErrorEvent*) =
|
||||
// XSetErrorHandler(&ctxErrorHandler);
|
||||
|
||||
// Check for the GLX_ARB_create_context extension string and the function.
|
||||
// If either is not present, use GLX 1.3 context creation method.
|
||||
//if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
|
||||
// !glXCreateContextAttribsARB )
|
||||
//{
|
||||
// printf( "glXCreateContextAttribsARB() not found"
|
||||
// " ... using old-style GLX context\n" );
|
||||
// ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
|
||||
//} else
|
||||
//{
|
||||
int context_attribs[] =
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
None
|
||||
};
|
||||
|
||||
printf( "Creating context\n" );
|
||||
ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
|
||||
True, context_attribs );
|
||||
|
||||
// Sync to ensure any errors generated are processed.
|
||||
//XSync( display, False );
|
||||
//if (ctxErrorOccurred && !ctx)
|
||||
//{
|
||||
// context_attribs[1] = 1;
|
||||
// context_attribs[3] = 0;
|
||||
|
||||
// ctxErrorOccurred = false;
|
||||
|
||||
// printf( "Failed to create GL 3.0 context"
|
||||
// " ... using old-style GLX context\n" );
|
||||
// ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
|
||||
// True, context_attribs );
|
||||
//}
|
||||
//}
|
||||
|
||||
//XSync( display, False );
|
||||
//XSetErrorHandler( oldHandler );
|
||||
|
||||
//if ( ctxErrorOccurred || !ctx )
|
||||
//{
|
||||
// printf( "Failed to create an OpenGL context\n" );
|
||||
// exit(1);
|
||||
//}
|
||||
|
||||
printf( "Making context current\n" );
|
||||
glXMakeCurrent( display, win, ctx );
|
||||
|
||||
const GLubyte * v = glGetString(GL_VERSION);
|
||||
printf("%s\n", v);
|
||||
|
||||
glClearColor( 0, 0.5, 1, 1 );
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
glXSwapBuffers ( display, win );
|
||||
|
||||
sleep( 1 );
|
||||
|
||||
glClearColor ( 1, 0.5, 0, 1 );
|
||||
glClear ( GL_COLOR_BUFFER_BIT );
|
||||
glXSwapBuffers ( display, win );
|
||||
|
||||
sleep( 1 );
|
||||
|
||||
glXMakeCurrent( display, 0, 0 );
|
||||
glXDestroyContext( display, ctx );
|
||||
|
||||
XDestroyWindow( display, win );
|
||||
XFreeColormap( display, cmap );
|
||||
XCloseDisplay( display );
|
||||
|
||||
return 0;
|
||||
}
|
148
src/openwindow.c
148
src/openwindow.c
|
@ -12,8 +12,6 @@ int initOpenGL() {
|
|||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define GLLOADER glXGetProcAddress
|
||||
|
||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||
|
||||
bool checkGLXVersion(Window window) {
|
||||
|
@ -87,9 +85,9 @@ int initGLX(Window * window)
|
|||
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
||||
|
||||
int context_attribs[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 6,
|
||||
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
None
|
||||
};
|
||||
window->glx.context = glXCreateContextAttribsARB(window->x.display, window->glx.config, 0, True, context_attribs);
|
||||
|
@ -206,51 +204,122 @@ void closeWindow(Window window) {
|
|||
#else
|
||||
|
||||
#include <windows.h>
|
||||
#include <GL/wgl.h>
|
||||
|
||||
#define GLLOADER wglGetProcAddress
|
||||
#define WND_CLASS_NAME "OpenWindowWndClass"
|
||||
|
||||
LRESULT CALLBACK wndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
Window * window = (Window *)GetWindowLong(hwnd, GWLP_USERDATA);
|
||||
Window * window = (Window *)(LONG_PTR)GetWindowLong(hwnd, GWLP_USERDATA);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE: {
|
||||
window->close = true;
|
||||
return 0;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
if (wParam == VK_ESCAPE) window->close = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
||||
}
|
||||
|
||||
int initWGL(Window * window, const char * title, size_t width, size_t height) {
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
int init(Window * window, const char * title, size_t width, size_t height) {
|
||||
window->wgl.instance = GetModuleHandle(NULL);
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_OWNDC;
|
||||
wcex.lpfnWndProc = &DefWindowProc;
|
||||
wcex.style = CS_CLASSDC;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hInstance = window->wgl.instance;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = 0;
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = title;
|
||||
wcex.lpszClassName = WND_CLASS_NAME;
|
||||
wcex.hIconSm = NULL;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
|
||||
RegisterClassEx(&wcex);
|
||||
RECT rect = { 0, 0, width, height };
|
||||
int style = WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
|
||||
AdjustWindowRect(&rect, style, FALSE);
|
||||
|
||||
window->w.window = CreateWindow(title, "example", style, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, GetModuleHandle(NULL), window);
|
||||
ShowWindow(window->w.window, SW_SHOW);
|
||||
window->wgl.window = CreateWindow(
|
||||
WND_CLASS_NAME,
|
||||
title,
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
width,
|
||||
height,
|
||||
NULL,
|
||||
NULL,
|
||||
window->wgl.instance,
|
||||
window
|
||||
);
|
||||
|
||||
SetWindowLong(window->w.window, GWLP_USERDATA, (LONG)window);
|
||||
if (window->wgl.window == NULL) return -1;
|
||||
|
||||
ShowWindow(window->wgl.window, SW_SHOW);
|
||||
|
||||
SetWindowLong(window->wgl.window, GWLP_USERDATA, (LONG_PTR)window);
|
||||
|
||||
window->wgl.display = GetDC(window->wgl.window);
|
||||
PIXELFORMATDESCRIPTOR pfd = {0};
|
||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 32;
|
||||
pfd.cRedBits = 0;
|
||||
pfd.cRedShift = 0;
|
||||
pfd.cGreenBits = 0;
|
||||
pfd.cGreenShift = 0;
|
||||
pfd.cBlueBits = 0;
|
||||
pfd.cBlueShift = 0;
|
||||
pfd.cAlphaBits = 0;
|
||||
pfd.cAlphaShift = 0;
|
||||
pfd.cAccumBits = 0;
|
||||
pfd.cAccumRedBits = 0;
|
||||
pfd.cAccumGreenBits = 0;
|
||||
pfd.cAccumBlueBits = 0;
|
||||
pfd.cAccumAlphaBits = 0;
|
||||
pfd.cDepthBits = 24;
|
||||
pfd.cStencilBits = 8;
|
||||
pfd.cAuxBuffers = 0;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
pfd.bReserved = 0;
|
||||
pfd.dwLayerMask = 0;
|
||||
pfd.dwVisibleMask = 0;
|
||||
pfd.dwDamageMask = 0;
|
||||
|
||||
int format = ChoosePixelFormat(window->wgl.display, &pfd);
|
||||
SetPixelFormat(window->wgl.display, format, &pfd);
|
||||
|
||||
HGLRC tempContext = wglCreateContext(window->wgl.display);
|
||||
if (tempContext == NULL) return -1;
|
||||
|
||||
if (!wglMakeCurrent(window->wgl.display, tempContext)) return -1;
|
||||
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
if (wglCreateContextAttribsARB == NULL) return -1;
|
||||
|
||||
int attribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 6,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
window->wgl.context = wglCreateContextAttribsARB(window->wgl.display, 0, attribs);
|
||||
if (window->wgl.context == NULL) {
|
||||
fprintf(stderr, "Failed to create wgl context!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
wglMakeCurrent(window->wgl.display, NULL);
|
||||
wglDeleteContext(tempContext);
|
||||
|
||||
wglMakeCurrent(window->wgl.display, window->wgl.context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,24 +327,41 @@ int initWGL(Window * window, const char * title, size_t width, size_t height) {
|
|||
Window openWindow(const char * name, size_t width, size_t height) {
|
||||
Window w = {0};
|
||||
|
||||
if (initWGL(&w, name, width, height) < 0) {
|
||||
fprintf(stderr, "Failed to initialize egl!\n");
|
||||
if (init(&w, name, width, height) < 0) {
|
||||
fprintf(stderr, "Failed to initialize wgl!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
initOpenGL();
|
||||
|
||||
eglMakeCurrent(w.egl.display, w.egl.surface, w.egl.surface, w.egl.context);
|
||||
if (initOpenGL() < 0) {
|
||||
fprintf(stderr, "Failed to initialize window: GLAD/OPENGL error!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
void windowDraw(Window window) {
|
||||
SwapBuffers(window.wgl.display);
|
||||
}
|
||||
|
||||
void windowHandleEvents(Window * window) {
|
||||
MSG msg;
|
||||
GetMessage(&msg, NULL, 0, 0);
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
void closeWindow(Window window) {
|
||||
DestroyWindow(window.w.window);
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(window.wgl.context);
|
||||
ReleaseDC(window.wgl.window, window.wgl.display);
|
||||
|
||||
DestroyWindow(window.wgl.window);
|
||||
UnregisterClass(WND_CLASS_NAME, window.wgl.instance);
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
int getOpenGLProcs(void) {
|
||||
return gladLoadGLLoader((GLADloadproc)GLLOADER);
|
||||
return gladLoadGL();
|
||||
}
|
||||
|
|
|
@ -38,36 +38,41 @@ typedef struct Window {
|
|||
bool close;
|
||||
} Window;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
} WGL;
|
||||
|
||||
typedef struct {
|
||||
HDC display;
|
||||
HWND window;
|
||||
} Windows;
|
||||
|
||||
typedef struct Window Window;
|
||||
|
||||
typedef struct Window {
|
||||
WGL wgl;
|
||||
Windows x;
|
||||
WindowEventHandler eventHandler;
|
||||
bool close;
|
||||
} Window;
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
// depends on glad
|
||||
int getOpenGLProcs(void);
|
||||
|
||||
Window openWindow(const char * name, size_t width, size_t height);
|
||||
void windowDraw(Window window);
|
||||
void windowSetEventHandler(Window * window, WindowEventHandler handler);
|
||||
void windowHandleEvents(Window * window);
|
||||
void closeWindow(Window w);
|
||||
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
HINSTANCE instance;
|
||||
HDC display;
|
||||
HWND window;
|
||||
HGLRC context;
|
||||
} WGL;
|
||||
|
||||
typedef struct Window Window;
|
||||
|
||||
typedef struct Window {
|
||||
WGL wgl;
|
||||
//WindowEventHandler eventHandler;
|
||||
bool close;
|
||||
} Window;
|
||||
|
||||
Window openWindow(const char * name, size_t width, size_t height);
|
||||
void windowDraw(Window window);
|
||||
void windowHandleEvents(Window * window);
|
||||
void closeWindow(Window w);
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
// depends on glad
|
||||
int getOpenGLProcs(void);
|
||||
|
||||
#endif // _OPEN_WINDOW_H_
|
||||
|
||||
// TODO: Add all the error handling to the glx
|
||||
|
|
Loading…
Reference in New Issue