From ed7dc61897db3f6aedd38a707fa4b1173645cff2 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 29 Sep 2025 08:20:45 +0000 Subject: [PATCH] OpenGL git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@61 b9cfdab3-6d41-4d17-bbe4-086880011989 --- GNUmakefile | 18 +++++--- examples/example.c | 5 ++- examples/opengl.c | 61 ++++++++++++++++++++++++++ include/Mw/Milsko.h | 1 + include/Mw/OpenGL.h | 21 +++++++++ include/Mw/TypeDefs.h | 3 +- src/button.c | 1 - src/opengl.c | 100 ++++++++++++++++++++++++++++++++++++++++++ src/window.c | 1 - 9 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 examples/opengl.c create mode 100644 include/Mw/OpenGL.h create mode 100644 src/opengl.c diff --git a/GNUmakefile b/GNUmakefile index a498f59..e5a1fc1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,14 +13,14 @@ L_LIBS = $(LIBS) E_CFLAGS = $(CFLAGS) E_LDFLAGS = $(LDFLAGS) -Lsrc -E_LIBS = $(LIBS) -lMw +E_LIBS = $(LIBS) -lMw $(GL) L_OBJS = src/ds.o src/core.o src/default.o src/draw.o src/lowlevel.o src/font.o -L_OBJS += src/window.o src/button.o +L_OBJS += src/window.o src/button.o src/opengl.o ifeq ($(TARGET),NetBSD) -L_CFLAGS += -I/usr/X11R7/include -I/usr/pkg/include -L_LDFLAGS += -L/usr/X11R7/lib -L/usr/pkg/lib -Wl,-R/usr/X11R7/lib -Wl,-R/usr/pkg/lib +CFLAGS += -I/usr/X11R7/include -I/usr/pkg/include +LDFLAGS += -L/usr/X11R7/lib -L/usr/pkg/lib -Wl,-R/usr/X11R7/lib -Wl,-R/usr/pkg/lib UNIX = 1 else ifeq ($(TARGET),Linux) UNIX = 1 @@ -33,7 +33,9 @@ endif ifeq ($(UNIX),1) L_CFLAGS += -DUSE_X11 L_OBJS += src/x11.o -L_LIBS += -lX11 +L_LIBS += -lX11 -lGL + +GL = -lGL E_LIBS += -lm @@ -43,13 +45,15 @@ else ifeq ($(WINDOWS),1) L_CFLAGS += -DUSE_GDI L_LDFLAGS += -Wl,--out-implib,src/libMw.lib L_OBJS += src/gdi.o -L_LIBS += -lgdi32 +L_LIBS += -lgdi32 -lopengl32 + +GL = -lopengl32 SO = .dll EXEC = .exe endif -EXAMPLES = examples/example$(EXEC) examples/rotate$(EXEC) +EXAMPLES = examples/example$(EXEC) examples/rotate$(EXEC) examples/opengl$(EXEC) .PHONY: all format clean lib examples diff --git a/examples/example.c b/examples/example.c index 62a680b..54da546 100644 --- a/examples/example.c +++ b/examples/example.c @@ -14,12 +14,13 @@ void handler(MwWidget handle, void* user_data, void* call_data){ void resize(MwWidget handle, void* user_data, void* call_data){ unsigned int w, h; - w = MwGetInteger(handle, MwNwidth); - h = MwGetInteger(handle, MwNheight); (void)user_data; (void)call_data; + w = MwGetInteger(handle, MwNwidth); + h = MwGetInteger(handle, MwNheight); + MwVaApply(button, MwNwidth, w - 50 * 2, MwNheight, h - 125 - 50 * 3, diff --git a/examples/opengl.c b/examples/opengl.c new file mode 100644 index 0000000..0353610 --- /dev/null +++ b/examples/opengl.c @@ -0,0 +1,61 @@ +/* $Id$ */ + +#include + +#include + +MwWidget window, opengl; +int ow, oh; + +void resize(MwWidget handle, void* user_data, void* call_data){ + unsigned int w, h; + + (void)user_data; + (void)call_data; + + w = MwGetInteger(handle, MwNwidth); + h = MwGetInteger(handle, MwNheight); + + MwVaApply(opengl, + MwNwidth, (ow = w - 100), + MwNheight, (oh = h - 100), + NULL); +} + +void tick(MwWidget handle, void* user_data, void* call_data){ + (void)handle; + (void)user_data; + (void)call_data; + + MwOpenGLMakeCurrent(opengl); + + glViewport(0, 0, ow, oh); + glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glBegin(GL_TRIANGLES); + glColor3f(1, 0, 0); glVertex2f(0, 0.8); + glColor3f(0, 1, 0); glVertex2f(-0.8, -0.8); + glColor3f(0, 0, 1); glVertex2f(0.8, -0.8); + glEnd(); + + MwOpenGLSwapBuffer(opengl); +} + +int main(){ + window = MwVaCreateWidget(MwWindowClass, "main", NULL, 0, 0, 400, 400, + MwNtitle, "hello world", + NULL); + opengl = MwCreateWidget(MwOpenGLClass, "opengl", window, 50, 50, (ow = 300), (oh = 300)); + + MwAddUserHandler(window, MwNresizeHandler, resize, NULL); + MwAddUserHandler(window, MwNtickHandler, tick, NULL); + + MwLoop(window); +} diff --git a/include/Mw/Milsko.h b/include/Mw/Milsko.h index 052b589..be88652 100644 --- a/include/Mw/Milsko.h +++ b/include/Mw/Milsko.h @@ -13,5 +13,6 @@ #include #include +#include #endif diff --git a/include/Mw/OpenGL.h b/include/Mw/OpenGL.h new file mode 100644 index 0000000..49a448a --- /dev/null +++ b/include/Mw/OpenGL.h @@ -0,0 +1,21 @@ +/* $Id$ */ +#ifndef __MW_OPENGL_H__ +#define __MW_OPENGL_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +MWDECL MwClass MwOpenGLClass; + +MWDECL void MwOpenGLMakeCurrent(MwWidget handle); +MWDECL void MwOpenGLSwapBuffer(MwWidget handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index a851901..e56e570 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -63,6 +63,8 @@ struct _MwWidget { int pressed; int close; + void* internal; + MwIntegerKeyValue* integer; MwTextKeyValue* text; MwUserHandlerKeyValue* handler; @@ -70,7 +72,6 @@ struct _MwWidget { #endif struct _MwClass { - void* opaque; MwHandler create; MwHandler destroy; MwHandler draw; diff --git a/src/button.c b/src/button.c index 934acc0..b176b41 100644 --- a/src/button.c +++ b/src/button.c @@ -36,7 +36,6 @@ static void click(MwWidget handle) { } MwClassRec MwButtonClassRec = { - NULL, /* opaque */ create, /* create */ NULL, /* destroy */ draw, /* draw */ diff --git a/src/opengl.c b/src/opengl.c new file mode 100644 index 0000000..98b4588 --- /dev/null +++ b/src/opengl.c @@ -0,0 +1,100 @@ +/* $Id$ */ +#include + +#ifdef _WIN32 +#include +#else +#include +#include +#endif +#include + +#ifdef _WIN32 +typedef struct opengl { + HDC dc; + HGLRC gl; +} opengl_t; +#else +typedef struct opengl { + XVisualInfo* visual; + GLXContext gl; +} opengl_t; +#endif + +static void create(MwWidget handle) { + opengl_t* o = malloc(sizeof(*o)); +#ifdef _WIN32 + PIXELFORMATDESCRIPTOR pfd; + int pf; + + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.cDepthBits = 32; + pfd.cColorBits = 32; + + o->dc = GetDC(handle->lowlevel->hWnd); + + pf = ChoosePixelFormat(o->dc, &pfd); + SetPixelFormat(o->dc, pf, &pfd); + + o->gl = wglCreateContext(o->dc); +#else + int attribs[5]; + + attribs[0] = GLX_RGBA; + attribs[1] = GLX_DOUBLEBUFFER; + attribs[2] = GLX_DEPTH_SIZE; + attribs[3] = 24; + attribs[4] = None; + + /* XXX: fix this */ + o->visual = glXChooseVisual(handle->lowlevel->display, DefaultScreen(handle->lowlevel->display), attribs); + o->gl = glXCreateContext(handle->lowlevel->display, o->visual, NULL, GL_TRUE); +#endif + handle->internal = o; + + MwSetDefault(handle); +} + +static void destroy(MwWidget handle) { + opengl_t* o = (opengl_t*)handle->internal; +#ifdef _WIN32 + wglMakeCurrent(NULL, NULL); + DeleteDC(o->dc); + wglDeleteContext(o->gl); +#else + glXMakeCurrent(handle->lowlevel->display, None, NULL); + glXDestroyContext(handle->lowlevel->display, o->gl); +#endif + free(o); +} + +MwClassRec MwOpenGLClassRec = { + create, /* create */ + destroy, /* destroy */ + NULL, /* draw */ + NULL /* click */ +}; +MwClass MwOpenGLClass = &MwOpenGLClassRec; + +void MwOpenGLMakeCurrent(MwWidget handle) { + opengl_t* o = (opengl_t*)handle->internal; +#ifdef _WIN32 + wglMakeCurrent(o->dc, o->gl); +#else + glXMakeCurrent(handle->lowlevel->display, handle->lowlevel->window, o->gl); +#endif +} + +void MwOpenGLSwapBuffer(MwWidget handle) { + opengl_t* o = (opengl_t*)handle->internal; +#ifdef _WIN32 + SwapBuffers(o->dc); +#else + (void)o; + + glXSwapBuffers(handle->lowlevel->display, handle->lowlevel->window); +#endif +} diff --git a/src/window.c b/src/window.c index 806fe28..fd63827 100644 --- a/src/window.c +++ b/src/window.c @@ -20,7 +20,6 @@ static void draw(MwWidget handle) { } MwClassRec MwWindowClassRec = { - NULL, /* opaque */ create, /* create */ NULL, /* destroy */ draw, /* draw */