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
|
FLAGS=-fPIC --shared
|
||||||
LIBS=-lX11 -lGL
|
|
||||||
FILES=src/openwindow.c deps/lib/glad.a
|
|
||||||
|
|
||||||
libopenwindow.so: glad.a
|
LINUX_FILES=src/openwindow.c deps/lib/glad_linux.a
|
||||||
gcc ${FLAGS} -o libopenwindow.so ${FILES}
|
|
||||||
|
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_FLAGS=-fPIC -c
|
||||||
GLAD_FILES=deps/src/glad.c
|
GLAD_FILES=deps/src/glad.c
|
||||||
|
|
||||||
glad.a: deps/src/glad.o
|
glad_linux.a: deps/src/glad.c
|
||||||
gcc ${GLAD_FLAGS} -o deps/src/glad.o ${GLAD_FILES}
|
gcc ${GLAD_FLAGS} -o deps/src/glad_linux.o ${GLAD_FILES}
|
||||||
ar rcs deps/lib/glad.a deps/src/glad.o
|
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 <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "deps/include/glad/glad.h"
|
||||||
|
#include "src/openwindow.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
@ -9,8 +12,6 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#undef Window
|
#undef Window
|
||||||
|
|
||||||
#include "src/openwindow.h"
|
|
||||||
|
|
||||||
void xevent(Window * w, XEvent xev) {
|
void xevent(Window * w, XEvent xev) {
|
||||||
switch (xev.type)
|
switch (xev.type)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +38,10 @@ void xevent(Window * w, XEvent xev) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
const char * fss =
|
const char * fss =
|
||||||
|
@ -52,22 +57,25 @@ int main(void)
|
||||||
{
|
{
|
||||||
Window w = openWindow("Window", 800, 600);
|
Window w = openWindow("Window", 800, 600);
|
||||||
|
|
||||||
|
// TODO: do this
|
||||||
|
#ifndef _WIN32
|
||||||
windowSetEventHandler(&w, xevent);
|
windowSetEventHandler(&w, xevent);
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
while (!w.close) {
|
while (!w.close)
|
||||||
|
{
|
||||||
windowHandleEvents(&w);
|
windowHandleEvents(&w);
|
||||||
|
|
||||||
glClearColor(1, 1, 1, 1);
|
glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glViewport(0, 0, 800, 600);
|
||||||
|
|
||||||
|
glColor3f(1.0, 0, 0);
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
glColor3f(1.0f, 0.0f, 0.0f);
|
|
||||||
glVertex2f(-0.5, -0.5);
|
glVertex2f(-0.5, -0.5);
|
||||||
glColor3f(0.0f, 1.0f, 0.0f);
|
|
||||||
glVertex2f(0.5, -0.5);
|
glVertex2f(0.5, -0.5);
|
||||||
glColor3f(0.0f, 0.0f, 1.0f);
|
|
||||||
glVertex2f(0.0, 0.5);
|
glVertex2f(0.0, 0.5);
|
||||||
glEnd();
|
glEnd();
|
||||||
glFlush();
|
|
||||||
|
|
||||||
windowDraw(w);
|
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
|
#ifndef _WIN32
|
||||||
|
|
||||||
#define GLLOADER glXGetProcAddress
|
|
||||||
|
|
||||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||||
|
|
||||||
bool checkGLXVersion(Window window) {
|
bool checkGLXVersion(Window window) {
|
||||||
|
@ -87,9 +85,9 @@ int initGLX(Window * window)
|
||||||
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
||||||
|
|
||||||
int context_attribs[] = {
|
int context_attribs[] = {
|
||||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
GLX_CONTEXT_MINOR_VERSION_ARB, 6,
|
||||||
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
window->glx.context = glXCreateContextAttribsARB(window->x.display, window->glx.config, 0, True, context_attribs);
|
window->glx.context = glXCreateContextAttribsARB(window->x.display, window->glx.config, 0, True, context_attribs);
|
||||||
|
@ -206,51 +204,122 @@ void closeWindow(Window window) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <windows.h>
|
#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)
|
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)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_CLOSE: {
|
case WM_KEYDOWN:
|
||||||
window->close = true;
|
{
|
||||||
return 0;
|
if (wParam == VK_ESCAPE) window->close = true;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
||||||
}
|
}
|
||||||
|
|
||||||
int initWGL(Window * window, const char * title, size_t width, size_t height) {
|
int init(Window * window, const char * title, size_t width, size_t height) {
|
||||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
window->wgl.instance = GetModuleHandle(NULL);
|
||||||
WNDCLASSEX wcex;
|
WNDCLASSEX wcex;
|
||||||
|
|
||||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
wcex.style = CS_OWNDC;
|
wcex.style = CS_CLASSDC;
|
||||||
wcex.lpfnWndProc = &DefWindowProc;
|
wcex.lpfnWndProc = wndProc;
|
||||||
wcex.cbClsExtra = 0;
|
wcex.cbClsExtra = 0;
|
||||||
wcex.cbWndExtra = 0;
|
wcex.cbWndExtra = 0;
|
||||||
wcex.hInstance = hInstance;
|
wcex.hInstance = window->wgl.instance;
|
||||||
wcex.hIcon = NULL;
|
wcex.hIcon = NULL;
|
||||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
wcex.hbrBackground = 0;
|
wcex.hbrBackground = 0;
|
||||||
wcex.lpszMenuName = NULL;
|
wcex.lpszMenuName = NULL;
|
||||||
wcex.lpszClassName = title;
|
wcex.lpszClassName = WND_CLASS_NAME;
|
||||||
wcex.hIconSm = NULL;
|
wcex.hIconSm = NULL;
|
||||||
wcex.lpfnWndProc = wndProc;
|
|
||||||
|
|
||||||
RegisterClassEx(&wcex);
|
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);
|
window->wgl.window = CreateWindow(
|
||||||
ShowWindow(window->w.window, SW_SHOW);
|
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;
|
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 openWindow(const char * name, size_t width, size_t height) {
|
||||||
Window w = {0};
|
Window w = {0};
|
||||||
|
|
||||||
if (initWGL(&w, name, width, height) < 0) {
|
if (init(&w, name, width, height) < 0) {
|
||||||
fprintf(stderr, "Failed to initialize egl!\n");
|
fprintf(stderr, "Failed to initialize wgl!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
initOpenGL();
|
if (initOpenGL() < 0) {
|
||||||
|
fprintf(stderr, "Failed to initialize window: GLAD/OPENGL error!\n");
|
||||||
eglMakeCurrent(w.egl.display, w.egl.surface, w.egl.surface, w.egl.context);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
return w;
|
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) {
|
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
|
#endif // _WIN32
|
||||||
|
|
||||||
int getOpenGLProcs(void) {
|
int getOpenGLProcs(void) {
|
||||||
return gladLoadGLLoader((GLADloadproc)GLLOADER);
|
return gladLoadGL();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,36 +38,41 @@ typedef struct Window {
|
||||||
bool close;
|
bool close;
|
||||||
} Window;
|
} 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);
|
Window openWindow(const char * name, size_t width, size_t height);
|
||||||
void windowDraw(Window window);
|
void windowDraw(Window window);
|
||||||
void windowSetEventHandler(Window * window, WindowEventHandler handler);
|
void windowSetEventHandler(Window * window, WindowEventHandler handler);
|
||||||
void windowHandleEvents(Window * window);
|
void windowHandleEvents(Window * window);
|
||||||
void closeWindow(Window w);
|
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_
|
#endif // _OPEN_WINDOW_H_
|
||||||
|
|
||||||
// TODO: Add all the error handling to the glx
|
// TODO: Add all the error handling to the glx
|
||||||
|
|
Loading…
Reference in New Issue