added windowKeyPressed and windowKeyReleased
This commit is contained in:
parent
98af446a2f
commit
14342c8c9f
|
@ -0,0 +1,7 @@
|
||||||
|
lib/
|
||||||
|
main
|
||||||
|
main.exe
|
||||||
|
valgrind-out.txt
|
||||||
|
*.o
|
||||||
|
sample/
|
||||||
|
other/
|
12
Makefile
12
Makefile
|
@ -1,4 +1,4 @@
|
||||||
FLAGS=-fPIC --shared
|
FLAGS=-fPIC --shared -Wall -Wextra
|
||||||
|
|
||||||
LINUX_FILES=src/openwindow.c deps/lib/glad_linux.a
|
LINUX_FILES=src/openwindow.c deps/lib/glad_linux.a
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ all: libopenwindow.so libopenwindow.dll
|
||||||
|
|
||||||
libopenwindow.so: glad_linux.a
|
libopenwindow.so: glad_linux.a
|
||||||
mkdir -p ${OUTPUT}
|
mkdir -p ${OUTPUT}
|
||||||
gcc ${FLAGS} -o ${OUTPUT}libopenwindow.so ${LINUX_FILES}
|
gcc ${FLAGS} -o ${OUTPUT}libopenwindow.so ${LINUX_FILES} -lX11 -lGLX -lOpenGL
|
||||||
|
|
||||||
libopenwindow.dll: glad_windows.a
|
libopenwindow.dll: glad_windows.a
|
||||||
mkdir -p ${OUTPUT}
|
mkdir -p ${OUTPUT}
|
||||||
|
@ -21,9 +21,9 @@ GLAD_FLAGS=-fPIC -c
|
||||||
GLAD_FILES=deps/src/glad.c
|
GLAD_FILES=deps/src/glad.c
|
||||||
|
|
||||||
glad_linux.a: deps/src/glad.c
|
glad_linux.a: deps/src/glad.c
|
||||||
gcc ${GLAD_FLAGS} -o deps/src/glad_linux.o ${GLAD_FILES}
|
gcc ${GLAD_FLAGS} -o deps/lib/glad_linux.o ${GLAD_FILES}
|
||||||
ar rcs deps/lib/glad_linux.a deps/src/glad_linux.o
|
ar rcs deps/lib/glad_linux.a deps/lib/glad_linux.o
|
||||||
|
|
||||||
glad_windows.a: deps/src/glad.c
|
glad_windows.a: deps/src/glad.c
|
||||||
x86_64-w64-mingw32-gcc ${GLAD_FLAGS} -o deps/src/glad_windows.o ${GLAD_FILES}
|
x86_64-w64-mingw32-gcc ${GLAD_FLAGS} -o deps/lib/glad_windows.o ${GLAD_FILES}
|
||||||
ar rcs deps/lib/glad_windows.a deps/src/glad_windows.o
|
ar rcs deps/lib/glad_windows.a deps/lib/glad_windows.o
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
The glad source code:
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013-2022 David Herberth
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
The Khronos Specifications:
|
||||||
|
|
||||||
|
Copyright (c) 2013-2020 The Khronos Group Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
The EGL Specification and various headers:
|
||||||
|
|
||||||
|
Copyright (c) 2007-2016 The Khronos Group Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and/or associated documentation files (the
|
||||||
|
"Materials"), to deal in the Materials without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Materials.
|
||||||
|
|
||||||
|
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
Binary file not shown.
Binary file not shown.
77
main.c
77
main.c
|
@ -1,81 +1,34 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "deps/include/glad/glad.h"
|
#include "GL/gl.h"
|
||||||
|
|
||||||
#include "src/openwindow.h"
|
#include "src/openwindow.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
|
|
||||||
#define Window X11Window
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#undef Window
|
|
||||||
|
|
||||||
void xevent(Window * w, XEvent xev) {
|
|
||||||
switch (xev.type)
|
|
||||||
{
|
|
||||||
case MotionNotify:
|
|
||||||
printf("motion: %d %d\n", xev.xbutton.x, xev.xbutton.y);
|
|
||||||
break;
|
|
||||||
case KeyRelease:
|
|
||||||
printf("release (%s)\n", XKeysymToString(XLookupKeysym(&xev.xkey, 0)));
|
|
||||||
break;
|
|
||||||
case KeyPress:
|
|
||||||
if (XLookupKeysym(&xev.xkey, 0) == XK_Escape) w->close = true;
|
|
||||||
printf("keypress (%s)\n", XKeysymToString(XLookupKeysym(&xev.xkey, 0)));
|
|
||||||
break;
|
|
||||||
case ButtonPress:
|
|
||||||
printf("BPress: state = %d, button = %d, x = %d, y = %d\n", xev.xbutton.state, xev.xbutton.button, xev.xbutton.x, xev.xbutton.y);
|
|
||||||
printf("Type=%d\n", (int)xev.xbutton.type);
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
printf("BRelease: state = %d, button = %d, x = %d, y = %d\n", xev.xbutton.state, xev.xbutton.button, xev.xbutton.x, xev.xbutton.y);
|
|
||||||
printf("Type=%d\n", (int)xev.xbutton.type);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Unknown event!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
const char * fss =
|
|
||||||
"#version 330 core\n"
|
|
||||||
"precision mediump float;"
|
|
||||||
"out vec4 FragColor;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" FragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
Window w = openWindow("Window", 800, 600);
|
Window * w = openWindow("Window", 800, 600);
|
||||||
|
|
||||||
// TODO: do this
|
while (!windowKeyPressed(w, WINDOW_KEY_ESC)) {
|
||||||
#ifndef _WIN32
|
windowHandleEvents(w);
|
||||||
windowSetEventHandler(&w, xevent);
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
while (!w.close)
|
if (windowKeyPressed(w, WINDOW_KEY_A))
|
||||||
{
|
printf("A is being pressed\n");
|
||||||
windowHandleEvents(&w);
|
|
||||||
|
|
||||||
glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
|
if (windowKeyReleased(w, WINDOW_KEY_A))
|
||||||
|
printf("A is being released\n");
|
||||||
|
|
||||||
|
glClearColor(0.1, 0.2, 0.3, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glViewport(0, 0, 800, 600);
|
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);
|
||||||
}
|
}
|
||||||
|
|
BIN
sample/x11
BIN
sample/x11
Binary file not shown.
256
sample/x11.c
256
sample/x11.c
|
@ -1,256 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
202
src/openwindow.c
202
src/openwindow.c
|
@ -1,6 +1,9 @@
|
||||||
|
// TODO: Add all the error handling to the glx part
|
||||||
|
|
||||||
#include "openwindow.h"
|
#include "openwindow.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int initOpenGL() {
|
int initOpenGL() {
|
||||||
if (getOpenGLProcs() == 0) return -1;
|
if (getOpenGLProcs() == 0) return -1;
|
||||||
|
@ -10,10 +13,34 @@ int initOpenGL() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OPENWINDOW_OPENGL_VERSSION_MAJOR 3
|
||||||
|
#define OPENWINDOW_OPENGL_VERSSION_MINOR 0
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||||
|
|
||||||
|
void windowDefaultEventHandler(Window * w, XEvent xev) {
|
||||||
|
switch (xev.type)
|
||||||
|
{
|
||||||
|
case KeyPress:
|
||||||
|
case KeyRelease:
|
||||||
|
XQueryKeymap(w->x.display, w->io.current);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void windowEventHandler(Window * w, XEvent event) {
|
||||||
|
if (w->eventHandler == NULL) {
|
||||||
|
windowDefaultEventHandler(w, event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w->eventHandler(w, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool checkGLXVersion(Window window) {
|
bool checkGLXVersion(Window window) {
|
||||||
int glx_major, glx_minor;
|
int glx_major, glx_minor;
|
||||||
|
|
||||||
|
@ -85,9 +112,9 @@ int initGLX(Window * window)
|
||||||
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
||||||
|
|
||||||
int context_attribs[] = {
|
int context_attribs[] = {
|
||||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
GLX_CONTEXT_MAJOR_VERSION_ARB, OPENWINDOW_OPENGL_VERSSION_MAJOR,
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 6,
|
GLX_CONTEXT_MINOR_VERSION_ARB, OPENWINDOW_OPENGL_VERSSION_MINOR,
|
||||||
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_CORE_PROFILE_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);
|
||||||
|
@ -97,6 +124,7 @@ int initGLX(Window * window)
|
||||||
|
|
||||||
int init(Window * window, const char * name, size_t width, size_t height) {
|
int init(Window * window, const char * name, size_t width, size_t height) {
|
||||||
window->x.display = XOpenDisplay(NULL);
|
window->x.display = XOpenDisplay(NULL);
|
||||||
|
|
||||||
if (window->x.display == NULL) {
|
if (window->x.display == NULL) {
|
||||||
fprintf(stderr, "Failed to open xdisplay!\n");
|
fprintf(stderr, "Failed to open xdisplay!\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -155,10 +183,11 @@ int init(Window * window, const char * name, size_t width, size_t height) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = calloc(1, sizeof(Window));
|
||||||
|
w->fps = WINDOW_DEFAULT_FPS;
|
||||||
|
|
||||||
if (init(&w, name, width, height) < 0) {
|
if (init(w, name, width, height) < 0) {
|
||||||
fprintf(stderr, "Failed to initialize window: X11 error!\n");
|
fprintf(stderr, "Failed to initialize window: X11 error!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -171,34 +200,65 @@ Window openWindow(const char * name, size_t width, size_t height) {
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void windowDraw(Window window) {
|
void windowSetFps(Window * window, uint32_t fps) {
|
||||||
glXSwapBuffers(window.x.display, window.x.window);
|
window->fps = fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void windowDraw(Window * window) {
|
||||||
|
glXSwapBuffers(window->x.display, window->x.window);
|
||||||
|
usleep(1 / window->fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void windowSetEventHandler(Window * window, WindowEventHandler handler) {
|
void windowSetEventHandler(Window * window, WindowEventHandler handler) {
|
||||||
window->eventHandler = handler;
|
window->eventHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void windowHandleEvents(Window * window) {
|
void resetIOState(Window * window) {
|
||||||
if (window->eventHandler == NULL) {
|
memcpy(window->io.last, window->io.current, WINDOW_KEY_COUNT);
|
||||||
fprintf(stderr, "Window event handler is not defined. Use `setEventHandler' to set it!\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XEvent xev;
|
|
||||||
|
|
||||||
if (XPending(window->x.display))
|
|
||||||
if (XCheckWindowEvent(window->x.display, window->x.window, window->x.eventMask, &xev))
|
|
||||||
window->eventHandler(window, xev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeWindow(Window window) {
|
void windowHandleEvents(Window * window) {
|
||||||
glXMakeCurrent(window.x.display, None, None);
|
XEvent xev = {0};
|
||||||
glXDestroyContext(window.x.display, window.glx.context);
|
|
||||||
|
|
||||||
XFreeColormap(window.x.display, window.x.cmap);
|
resetIOState(window);
|
||||||
XDestroyWindow(window.x.display, window.x.window);
|
|
||||||
XCloseDisplay(window.x.display);
|
while (XPending(window->x.display)) {
|
||||||
|
if (XCheckWindowEvent(window->x.display, window->x.window, window->x.eventMask, &xev)) {
|
||||||
|
if (window->eventHandler != NULL) {
|
||||||
|
window->eventHandler(window, xev);
|
||||||
|
} else {
|
||||||
|
windowEventHandler(window, xev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeWindow(Window * window) {
|
||||||
|
glXMakeCurrent(window->x.display, None, None);
|
||||||
|
glXDestroyContext(window->x.display, window->glx.context);
|
||||||
|
|
||||||
|
XFreeColormap(window->x.display, window->x.cmap);
|
||||||
|
XDestroyWindow(window->x.display, window->x.window);
|
||||||
|
XCloseDisplay(window->x.display);
|
||||||
|
free(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowKeyPressed(Window * window, char * key) {
|
||||||
|
KeySym keysym = XStringToKeysym(key);
|
||||||
|
if (keysym == NoSymbol) return false;
|
||||||
|
|
||||||
|
KeyCode keycode = XKeysymToKeycode(window->x.display, keysym);
|
||||||
|
|
||||||
|
return window->io.current[keycode / 8] & (1 << (keycode % 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowKeyReleased(Window * window, char * key) {
|
||||||
|
KeySym keysym = XStringToKeysym(key);
|
||||||
|
if (keysym == NoSymbol) return false;
|
||||||
|
|
||||||
|
KeyCode keycode = XKeysymToKeycode(window->x.display, keysym);
|
||||||
|
|
||||||
|
return (window->io.last[keycode / 8] & (1 << (keycode % 8))) && !(window->io.current[keycode / 8] & (1 << (keycode % 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -206,22 +266,37 @@ void closeWindow(Window window) {
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <GL/wgl.h>
|
#include <GL/wgl.h>
|
||||||
|
|
||||||
|
//TODO: Change this every time we open a window
|
||||||
#define WND_CLASS_NAME "OpenWindowWndClass"
|
#define WND_CLASS_NAME "OpenWindowWndClass"
|
||||||
|
|
||||||
LRESULT CALLBACK wndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
|
void windowDefaultEventHandler(Window * window, unsigned int event, WPARAM wParam, LPARAM lParam) {
|
||||||
{
|
(void) wParam;
|
||||||
Window * window = (Window *)(LONG_PTR)GetWindowLong(hwnd, GWLP_USERDATA);
|
(void) lParam;
|
||||||
|
|
||||||
switch (msg)
|
switch (event)
|
||||||
{
|
{
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
{
|
case WM_KEYUP:
|
||||||
if (wParam == VK_ESCAPE) window->close = true;
|
GetKeyboardState(window->io.current);
|
||||||
|
break;
|
||||||
|
case WM_TIMER:
|
||||||
|
InvalidateRect(window->wgl.window, NULL, FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK windowEventHandler(HWND hwnd, unsigned int event, WPARAM wParam, LPARAM lParam) {
|
||||||
|
Window * window = (Window *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||||
|
if (window == NULL) goto uninit;
|
||||||
|
|
||||||
|
if (window->eventHandler == NULL) {
|
||||||
|
windowDefaultEventHandler(window, event, wParam, lParam);
|
||||||
|
} else {
|
||||||
|
window->eventHandler(window, event, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
uninit:
|
||||||
|
return (DefWindowProc(hwnd, event, wParam, lParam));
|
||||||
}
|
}
|
||||||
|
|
||||||
int init(Window * window, const char * title, size_t width, size_t height) {
|
int init(Window * window, const char * title, size_t width, size_t height) {
|
||||||
|
@ -230,7 +305,7 @@ int init(Window * window, const char * title, size_t width, size_t height) {
|
||||||
|
|
||||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
wcex.style = CS_CLASSDC;
|
wcex.style = CS_CLASSDC;
|
||||||
wcex.lpfnWndProc = wndProc;
|
wcex.lpfnWndProc = windowEventHandler;
|
||||||
wcex.cbClsExtra = 0;
|
wcex.cbClsExtra = 0;
|
||||||
wcex.cbWndExtra = 0;
|
wcex.cbWndExtra = 0;
|
||||||
wcex.hInstance = window->wgl.instance;
|
wcex.hInstance = window->wgl.instance;
|
||||||
|
@ -254,14 +329,17 @@ int init(Window * window, const char * title, size_t width, size_t height) {
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
window->wgl.instance,
|
window->wgl.instance,
|
||||||
window
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (window->wgl.window == NULL) return -1;
|
if (window->wgl.window == NULL) {
|
||||||
|
fprintf(stderr, "Failed to create window!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ShowWindow(window->wgl.window, SW_SHOW);
|
ShowWindow(window->wgl.window, SW_SHOW);
|
||||||
|
|
||||||
SetWindowLong(window->wgl.window, GWLP_USERDATA, (LONG_PTR)window);
|
SetWindowLongPtr(window->wgl.window, GWLP_USERDATA, (LONG_PTR)window);
|
||||||
|
|
||||||
window->wgl.display = GetDC(window->wgl.window);
|
window->wgl.display = GetDC(window->wgl.window);
|
||||||
PIXELFORMATDESCRIPTOR pfd = {0};
|
PIXELFORMATDESCRIPTOR pfd = {0};
|
||||||
|
@ -300,12 +378,12 @@ int init(Window * window, const char * title, size_t width, size_t height) {
|
||||||
|
|
||||||
if (!wglMakeCurrent(window->wgl.display, tempContext)) return -1;
|
if (!wglMakeCurrent(window->wgl.display, tempContext)) return -1;
|
||||||
|
|
||||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)(void *)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||||
if (wglCreateContextAttribsARB == NULL) return -1;
|
if (wglCreateContextAttribsARB == NULL) return -1;
|
||||||
|
|
||||||
int attribs[] = {
|
int attribs[] = {
|
||||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
WGL_CONTEXT_MAJOR_VERSION_ARB, OPENWINDOW_OPENGL_VERSSION_MAJOR,
|
||||||
WGL_CONTEXT_MINOR_VERSION_ARB, 6,
|
WGL_CONTEXT_MINOR_VERSION_ARB, OPENWINDOW_OPENGL_VERSSION_MINOR,
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -321,13 +399,16 @@ int init(Window * window, const char * title, size_t width, size_t height) {
|
||||||
|
|
||||||
wglMakeCurrent(window->wgl.display, window->wgl.context);
|
wglMakeCurrent(window->wgl.display, window->wgl.context);
|
||||||
|
|
||||||
|
SetTimer(window->wgl.window, 1, (1 / window->fps) * 1000, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = calloc(1, sizeof(Window));
|
||||||
|
w->fps = WINDOW_DEFAULT_FPS;
|
||||||
|
|
||||||
if (init(&w, name, width, height) < 0) {
|
if (init(w, name, width, height) < 0) {
|
||||||
fprintf(stderr, "Failed to initialize wgl!\n");
|
fprintf(stderr, "Failed to initialize wgl!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -340,24 +421,45 @@ Window openWindow(const char * name, size_t width, size_t height) {
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void windowDraw(Window window) {
|
void windowDraw(Window * window) {
|
||||||
SwapBuffers(window.wgl.display);
|
SwapBuffers(window->wgl.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void windowSetEventHandler(Window * window, WindowEventHandler handler) {
|
||||||
|
window->eventHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetIOState(Window * window) {
|
||||||
|
memcpy(window->io.last, window->io.current, WINDOW_KEY_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void windowHandleEvents(Window * window) {
|
void windowHandleEvents(Window * window) {
|
||||||
MSG msg;
|
(void) window;
|
||||||
|
|
||||||
|
resetIOState(window);
|
||||||
|
|
||||||
|
MSG msg = {0};
|
||||||
GetMessage(&msg, NULL, 0, 0);
|
GetMessage(&msg, NULL, 0, 0);
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeWindow(Window window) {
|
void closeWindow(Window * window) {
|
||||||
wglMakeCurrent(NULL, NULL);
|
wglMakeCurrent(NULL, NULL);
|
||||||
wglDeleteContext(window.wgl.context);
|
wglDeleteContext(window->wgl.context);
|
||||||
ReleaseDC(window.wgl.window, window.wgl.display);
|
ReleaseDC(window->wgl.window, window->wgl.display);
|
||||||
|
|
||||||
DestroyWindow(window.wgl.window);
|
DestroyWindow(window->wgl.window);
|
||||||
UnregisterClass(WND_CLASS_NAME, window.wgl.instance);
|
UnregisterClass(WND_CLASS_NAME, window->wgl.instance);
|
||||||
|
free(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowKeyPressed(Window * window, int key) {
|
||||||
|
return window->io.current[key] & 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowKeyReleased(Window * window, int key) {
|
||||||
|
return (window->io.last[key] & 0x80) && !(window->io.current[key] & 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
115
src/openwindow.h
115
src/openwindow.h
|
@ -1,11 +1,18 @@
|
||||||
#ifndef _OPEN_WINDOW_H_
|
#ifndef _OPEN_WINDOW_H_
|
||||||
#define _OPEN_WINDOW_H_
|
#define _OPEN_WINDOW_H_
|
||||||
|
|
||||||
|
#define WINDOW_DEFAULT_FPS 60
|
||||||
|
|
||||||
|
#define WINDOW_KEY_COUNT 256
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../deps/include/glad/glad.h"
|
int gladLoadGL(void);
|
||||||
|
|
||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
@ -28,21 +35,53 @@ typedef struct {
|
||||||
long eventMask;
|
long eventMask;
|
||||||
} X11;
|
} X11;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char current[WINDOW_KEY_COUNT];
|
||||||
|
char last[WINDOW_KEY_COUNT];
|
||||||
|
} WindowIOState;
|
||||||
|
|
||||||
typedef struct Window Window;
|
typedef struct Window Window;
|
||||||
typedef void(* WindowEventHandler)(Window * w, XEvent xev);
|
typedef void(* WindowEventHandler)(Window * window, XEvent event);
|
||||||
|
|
||||||
typedef struct Window {
|
typedef struct Window {
|
||||||
|
WindowIOState io;
|
||||||
GLX glx;
|
GLX glx;
|
||||||
X11 x;
|
X11 x;
|
||||||
WindowEventHandler eventHandler;
|
WindowEventHandler eventHandler;
|
||||||
bool close;
|
uint32_t fps;
|
||||||
} Window;
|
} Window;
|
||||||
|
|
||||||
Window openWindow(const char * name, size_t width, size_t height);
|
#define WINDOW_KEY_Q ("q")
|
||||||
void windowDraw(Window window);
|
#define WINDOW_KEY_W ("w")
|
||||||
void windowSetEventHandler(Window * window, WindowEventHandler handler);
|
#define WINDOW_KEY_E ("e")
|
||||||
void windowHandleEvents(Window * window);
|
#define WINDOW_KEY_R ("r")
|
||||||
void closeWindow(Window w);
|
#define WINDOW_KEY_T ("t")
|
||||||
|
#define WINDOW_KEY_Y ("y")
|
||||||
|
#define WINDOW_KEY_U ("u")
|
||||||
|
#define WINDOW_KEY_I ("i")
|
||||||
|
#define WINDOW_KEY_O ("o")
|
||||||
|
#define WINDOW_KEY_P ("p")
|
||||||
|
#define WINDOW_KEY_A ("a")
|
||||||
|
#define WINDOW_KEY_S ("s")
|
||||||
|
#define WINDOW_KEY_D ("d")
|
||||||
|
#define WINDOW_KEY_F ("f")
|
||||||
|
#define WINDOW_KEY_G ("g")
|
||||||
|
#define WINDOW_KEY_H ("h")
|
||||||
|
#define WINDOW_KEY_J ("j")
|
||||||
|
#define WINDOW_KEY_K ("k")
|
||||||
|
#define WINDOW_KEY_L ("l")
|
||||||
|
#define WINDOW_KEY_Z ("z")
|
||||||
|
#define WINDOW_KEY_X ("x")
|
||||||
|
#define WINDOW_KEY_C ("c")
|
||||||
|
#define WINDOW_KEY_V ("v")
|
||||||
|
#define WINDOW_KEY_B ("b")
|
||||||
|
#define WINDOW_KEY_N ("n")
|
||||||
|
#define WINDOW_KEY_M ("m")
|
||||||
|
|
||||||
|
#define WINDOW_KEY_ESC ("Escape")
|
||||||
|
|
||||||
|
bool windowKeyPressed(Window * window, char * key);
|
||||||
|
bool windowKeyReleased(Window * window, char * key);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -55,24 +94,66 @@ typedef struct {
|
||||||
HGLRC context;
|
HGLRC context;
|
||||||
} WGL;
|
} WGL;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE current[WINDOW_KEY_COUNT];
|
||||||
|
BYTE last[WINDOW_KEY_COUNT];
|
||||||
|
} WindowIOState;
|
||||||
|
|
||||||
typedef struct Window Window;
|
typedef struct Window Window;
|
||||||
|
typedef void(* WindowEventHandler)(Window * window, unsigned int event, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
typedef struct Window {
|
typedef struct Window {
|
||||||
|
WindowIOState io;
|
||||||
WGL wgl;
|
WGL wgl;
|
||||||
//WindowEventHandler eventHandler;
|
WindowEventHandler eventHandler;
|
||||||
bool close;
|
uint32_t fps;
|
||||||
} Window;
|
} Window;
|
||||||
|
|
||||||
Window openWindow(const char * name, size_t width, size_t height);
|
#define WINDOW_KEY_Q ('Q')
|
||||||
void windowDraw(Window window);
|
#define WINDOW_KEY_W ('W')
|
||||||
void windowHandleEvents(Window * window);
|
#define WINDOW_KEY_E ('E')
|
||||||
void closeWindow(Window w);
|
#define WINDOW_KEY_R ('R')
|
||||||
|
#define WINDOW_KEY_T ('T')
|
||||||
|
#define WINDOW_KEY_Y ('Y')
|
||||||
|
#define WINDOW_KEY_U ('U')
|
||||||
|
#define WINDOW_KEY_I ('I')
|
||||||
|
#define WINDOW_KEY_O ('O')
|
||||||
|
#define WINDOW_KEY_P ('P')
|
||||||
|
#define WINDOW_KEY_A ('A')
|
||||||
|
#define WINDOW_KEY_S ('S')
|
||||||
|
#define WINDOW_KEY_D ('D')
|
||||||
|
#define WINDOW_KEY_F ('F')
|
||||||
|
#define WINDOW_KEY_G ('G')
|
||||||
|
#define WINDOW_KEY_H ('H')
|
||||||
|
#define WINDOW_KEY_J ('J')
|
||||||
|
#define WINDOW_KEY_K ('K')
|
||||||
|
#define WINDOW_KEY_L ('L')
|
||||||
|
#define WINDOW_KEY_Z ('Z')
|
||||||
|
#define WINDOW_KEY_X ('X')
|
||||||
|
#define WINDOW_KEY_C ('C')
|
||||||
|
#define WINDOW_KEY_V ('V')
|
||||||
|
#define WINDOW_KEY_B ('B')
|
||||||
|
#define WINDOW_KEY_N ('N')
|
||||||
|
#define WINDOW_KEY_M ('M')
|
||||||
|
|
||||||
|
#define WINDOW_KEY_ESC (VK_ESCAPE)
|
||||||
|
|
||||||
|
bool windowKeyPressed(Window * window, int key);
|
||||||
|
bool windowKeyReleased(Window * window, int key);
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
// depends on glad
|
Window * openWindow(const char * name, size_t width, size_t height);
|
||||||
|
void windowSetFps(Window * window, uint32_t fps);
|
||||||
|
void windowDraw(Window * window);
|
||||||
|
void windowSetEventHandler(Window * window, WindowEventHandler handler);
|
||||||
|
void windowHandleEvents(Window * window);
|
||||||
|
void closeWindow(Window * window);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WindowKeyPress = 0,
|
||||||
|
} WindowEvent;
|
||||||
|
|
||||||
int getOpenGLProcs(void);
|
int getOpenGLProcs(void);
|
||||||
|
|
||||||
#endif // _OPEN_WINDOW_H_
|
#endif // _OPEN_WINDOW_H_
|
||||||
|
|
||||||
// TODO: Add all the error handling to the glx
|
|
||||||
|
|
Loading…
Reference in New Issue