forked from pyrite-dev/milsko
mac opengl support. proper coordinate flipping
This commit is contained in:
parent
f700e90d23
commit
db577bb01f
7 changed files with 610 additions and 390 deletions
|
|
@ -1,78 +1,89 @@
|
|||
#define TITLE "cube"
|
||||
#include "glutlayer.c"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
|
||||
static double deg = 0;
|
||||
|
||||
static void draw(void) {
|
||||
int i;
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
int i;
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(deg, 1, 0, 0);
|
||||
glRotatef(deg, 0, 1, 0);
|
||||
glRotatef(deg, 0, 0, 1);
|
||||
glPushMatrix();
|
||||
glRotatef(deg, 1, 0, 0);
|
||||
glRotatef(deg, 0, 1, 0);
|
||||
glRotatef(deg, 0, 0, 1);
|
||||
|
||||
for(i = 0; i < 6; i++) {
|
||||
if(i == 0) glColor3f(1, 0, 0);
|
||||
if(i == 1) glColor3f(0, 1, 0);
|
||||
if(i == 2) glColor3f(1, 1, 0);
|
||||
if(i == 3) glColor3f(0, 0, 1);
|
||||
if(i == 4) glColor3f(1, 0, 1);
|
||||
if(i == 5) glColor3f(0, 1, 1);
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (i == 0)
|
||||
glColor3f(1, 0, 0);
|
||||
if (i == 1)
|
||||
glColor3f(0, 1, 0);
|
||||
if (i == 2)
|
||||
glColor3f(1, 1, 0);
|
||||
if (i == 3)
|
||||
glColor3f(0, 0, 1);
|
||||
if (i == 4)
|
||||
glColor3f(1, 0, 1);
|
||||
if (i == 5)
|
||||
glColor3f(0, 1, 1);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glNormal3f(0, 1, 0);
|
||||
glVertex3f(-1, 1, -1);
|
||||
glVertex3f(-1, 1, 1);
|
||||
glVertex3f(1, 1, 1);
|
||||
glVertex3f(1, 1, -1);
|
||||
glEnd();
|
||||
glBegin(GL_QUADS);
|
||||
glNormal3f(0, 1, 0);
|
||||
glVertex3f(-1, 1, -1);
|
||||
glVertex3f(-1, 1, 1);
|
||||
glVertex3f(1, 1, 1);
|
||||
glVertex3f(1, 1, -1);
|
||||
glEnd();
|
||||
|
||||
if(i < 3) glRotatef(90, 0, 0, 1);
|
||||
if(i == 3) glRotatef(90, 1, 0, 0);
|
||||
if(i == 4) glRotatef(180, 0, 0, 1);
|
||||
}
|
||||
glPopMatrix();
|
||||
if (i < 3)
|
||||
glRotatef(90, 0, 0, 1);
|
||||
if (i == 3)
|
||||
glRotatef(90, 1, 0, 0);
|
||||
if (i == 4)
|
||||
glRotatef(180, 0, 0, 1);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void idle(void) {
|
||||
deg += 1.0;
|
||||
}
|
||||
static void idle(void) { deg += 1.0; }
|
||||
|
||||
static void reshape(int width, int height) {
|
||||
GLfloat lpos[4];
|
||||
GLfloat lpos[4];
|
||||
|
||||
lpos[0] = 1;
|
||||
lpos[1] = 1;
|
||||
lpos[2] = 1;
|
||||
lpos[3] = 0;
|
||||
lpos[0] = 1;
|
||||
lpos[1] = 1;
|
||||
lpos[2] = 1;
|
||||
lpos[3] = 0;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (double)width / height, 1, 100);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (double)width / height, 1, 100);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(2, 2, 2, 0, 0, 0, 0, 1, 0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(2, 2, 2, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
|
||||
}
|
||||
|
||||
static void init(void) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
}
|
||||
|
||||
static void key(int k) {
|
||||
(void)k;
|
||||
}
|
||||
static void key(int k) { (void)k; }
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@
|
|||
- (void)destroy;
|
||||
|
||||
- (NSWindow *)parentWindow;
|
||||
- (NSView *)getView;
|
||||
|
||||
@end
|
||||
#define OBJC(x) x
|
||||
|
|
|
|||
|
|
@ -5,17 +5,24 @@
|
|||
#ifndef __MW_WIDGET_OPENGL_H__
|
||||
#define __MW_WIDGET_OPENGL_H__
|
||||
|
||||
#include <Mw/Core.h>
|
||||
#include <Mw/MachDep.h>
|
||||
#include <Mw/TypeDefs.h>
|
||||
#include <Mw/Core.h>
|
||||
|
||||
#if !defined(MW_OPENGL_NO_INCLUDE) && !defined(__gl_h_)
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#else
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
|
||||
#ifndef GLAPIENTRY
|
||||
#define GLAPIENTRY APIENTRY
|
||||
|
|
@ -36,7 +43,7 @@ MWDECL MwClass MwOpenGLClass;
|
|||
* @param handle Widget
|
||||
*/
|
||||
MwInline void MwOpenGLMakeCurrent(MwWidget handle) {
|
||||
MwVaWidgetExecute(handle, "mwOpenGLMakeCurrent", NULL);
|
||||
MwVaWidgetExecute(handle, "mwOpenGLMakeCurrent", NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -45,10 +52,10 @@ MwInline void MwOpenGLMakeCurrent(MwWidget handle) {
|
|||
* @param name Name
|
||||
* @return Procedure
|
||||
*/
|
||||
MwInline void* MwOpenGLGetProcAddress(MwWidget handle, const char* name) {
|
||||
void* out;
|
||||
MwVaWidgetExecute(handle, "mwOpenGLGetProcAddress", &out, name);
|
||||
return out;
|
||||
MwInline void *MwOpenGLGetProcAddress(MwWidget handle, const char *name) {
|
||||
void *out;
|
||||
MwVaWidgetExecute(handle, "mwOpenGLGetProcAddress", &out, name);
|
||||
return out;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -56,7 +63,7 @@ MwInline void* MwOpenGLGetProcAddress(MwWidget handle, const char* name) {
|
|||
* @param handle Widget
|
||||
*/
|
||||
MwInline void MwOpenGLSwapBuffer(MwWidget handle) {
|
||||
MwVaWidgetExecute(handle, "mwOpenGLSwapBuffer", NULL);
|
||||
MwVaWidgetExecute(handle, "mwOpenGLSwapBuffer", NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -50,7 +50,14 @@ if (grep(/^cocoa$/, @backends)) {
|
|||
add_cflags("-DUSE_COCOA");
|
||||
new_object("src/backend/cocoa.m");
|
||||
|
||||
$gl_libs = "-lGL -lGLU";
|
||||
if (param_get("opengl")) {
|
||||
new_object("src/widget/opengl_cocoa.m");
|
||||
}
|
||||
|
||||
# tim cook my man literally everybody and their mother who knows what opengl is knows its deprecated on macos and i'm not having you spam the console with this
|
||||
add_cflags("-DGL_SILENCE_DEPRECATION");
|
||||
|
||||
$gl_libs = "-framework OpenGL";
|
||||
}
|
||||
|
||||
if (param_get("stb-image")) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,29 @@
|
|||
#pragma clang push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
static CGRect rectFlip(CGRect originFrame) {
|
||||
NSScreen *zeroScreen = NSScreen.screens[0];
|
||||
double screenHeight = zeroScreen.frame.size.height;
|
||||
double originY = originFrame.origin.y;
|
||||
double frameHeight = originFrame.size.height;
|
||||
double destinationY = screenHeight - (originY + frameHeight);
|
||||
CGRect destinationFrame = originFrame;
|
||||
destinationFrame.origin.y = destinationY;
|
||||
if (destinationFrame.origin.x < 0)
|
||||
destinationFrame.origin.x = 0;
|
||||
if (destinationFrame.origin.y < 0)
|
||||
destinationFrame.origin.y = 0;
|
||||
if (destinationFrame.size.width < 0)
|
||||
destinationFrame.size.width = 0;
|
||||
if (destinationFrame.size.height < 0)
|
||||
destinationFrame.size.height = 0;
|
||||
return destinationFrame;
|
||||
}
|
||||
|
||||
static CGPoint pointFlip(CGPoint point) {
|
||||
return rectFlip(NSMakeRect(point.x, point.y, 0, 0)).origin;
|
||||
}
|
||||
|
||||
@implementation MilskoCocoaPixmap
|
||||
|
||||
+ (MilskoCocoaPixmap *)newWithWidth:(int)width height:(int)height {
|
||||
|
|
@ -70,8 +93,7 @@
|
|||
centerY = true;
|
||||
}
|
||||
c->application = [NSApplication sharedApplication];
|
||||
|
||||
c->rect = NSMakeRect(x, y, width, height);
|
||||
c->rect = rectFlip(NSMakeRect(x, y, width, height));
|
||||
|
||||
if (parent == NULL) {
|
||||
c->window = [[NSWindow alloc]
|
||||
|
|
@ -81,12 +103,12 @@
|
|||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
} else {
|
||||
double offset = 0;
|
||||
NSWindow *parentWindow = parent->cocoa.real->window;
|
||||
|
||||
c->rect = [parentWindow frameRectForContentRect:c->rect];
|
||||
c->rect.origin.y =
|
||||
y -
|
||||
offset =
|
||||
[parentWindow frameRectForContentRect:parentWindow.frame].size.height -
|
||||
[parentWindow contentRectForFrameRect:parentWindow.frame].size.height;
|
||||
c->rect.origin.y -= offset;
|
||||
|
||||
c->window = [[NSWindow alloc] initWithContentRect:c->rect
|
||||
styleMask:NSBorderlessWindowMask
|
||||
|
|
@ -160,10 +182,10 @@
|
|||
- (void)lineWithPoints:(MwPoint *)points color:(MwLLColor)color {
|
||||
};
|
||||
- (void)getX:(int *)x Y:(int *)y W:(unsigned int *)w H:(unsigned int *)h {
|
||||
NSRect frame = [self->window frame];
|
||||
NSRect frame = rectFlip([self->window frame]);
|
||||
|
||||
*x = frame.origin.x;
|
||||
*y = frame.origin.y - frame.size.height;
|
||||
*y = frame.origin.y;
|
||||
|
||||
*w = frame.size.width;
|
||||
*h = frame.size.height;
|
||||
|
|
@ -174,12 +196,17 @@
|
|||
frame.origin.x = x;
|
||||
frame.origin.y = y;
|
||||
|
||||
if (self->parent) {
|
||||
NSWindow *parentWindow = [self parentWindow];
|
||||
NSRect correctedFrame =
|
||||
[parentWindow contentRectForFrameRect:parentWindow.frame];
|
||||
frame.origin.y = (correctedFrame.size.height - y);
|
||||
frame = rectFlip(frame);
|
||||
|
||||
if (parent) {
|
||||
double offset = 0;
|
||||
NSWindow *parentWindow = parent->cocoa.real->window;
|
||||
offset =
|
||||
[parentWindow frameRectForContentRect:parentWindow.frame].size.height -
|
||||
[parentWindow contentRectForFrameRect:parentWindow.frame].size.height;
|
||||
frame.origin.y -= offset;
|
||||
}
|
||||
[self->view setFrameSize:frame.size];
|
||||
|
||||
[self->window setFrame:frame display:YES animate:false];
|
||||
};
|
||||
|
|
@ -187,8 +214,10 @@
|
|||
NSRect frame = [self->window frame];
|
||||
frame.size.width = w;
|
||||
frame.size.height = h;
|
||||
|
||||
self->rect = frame;
|
||||
|
||||
[self->view setFrameSize:frame.size];
|
||||
[self->window setFrame:frame display:YES animate:false];
|
||||
};
|
||||
- (int)pending {
|
||||
|
|
@ -207,10 +236,6 @@
|
|||
if (self->lastEvent != nil) {
|
||||
NSWindow *win = [self->lastEvent window];
|
||||
NSWindow *parentWindow = [self parentWindow];
|
||||
NSRect realFrame = parentWindow.frame;
|
||||
NSRect correctedFrame =
|
||||
[parentWindow frameRectForContentRect:parentWindow.frame];
|
||||
CGFloat offset = realFrame.size.height - correctedFrame.size.height;
|
||||
MwLL h;
|
||||
|
||||
if ([win contentView].subviews.count == 0) {
|
||||
|
|
@ -228,6 +253,7 @@
|
|||
case NSEventTypeOtherMouseUp: {
|
||||
MwLLMouse mouse = {};
|
||||
MwBool isDown = MwTRUE;
|
||||
CGPoint mousePoint = pointFlip([lastEvent locationInWindow]);
|
||||
switch (self->lastEvent.type) {
|
||||
case NSEventTypeLeftMouseUp:
|
||||
isDown = MwFALSE;
|
||||
|
|
@ -247,9 +273,8 @@
|
|||
default:
|
||||
break;
|
||||
}
|
||||
mouse.point.x = [lastEvent locationInWindow].x;
|
||||
mouse.point.y = [win contentRectForFrameRect:win.frame].size.height -
|
||||
[lastEvent locationInWindow].y;
|
||||
mouse.point.x = mousePoint.x;
|
||||
mouse.point.y = mousePoint.y;
|
||||
|
||||
if (isDown) {
|
||||
MwLLDispatch(h, down, &mouse);
|
||||
|
|
@ -428,6 +453,10 @@
|
|||
topmostWindow = topmostWindow.parentWindow;
|
||||
return topmostWindow;
|
||||
}
|
||||
|
||||
- (NSView *)getView {
|
||||
return view;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MilskoCocoaView
|
||||
|
|
@ -471,13 +500,13 @@
|
|||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect {
|
||||
NSSize sz = [self->rep size];
|
||||
NSSize sz = self->rep.size;
|
||||
[super drawRect:dirtyRect];
|
||||
if (!self->rep) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self->rep drawInRect:NSMakeRect(0, 0, width, height)];
|
||||
[self->rep drawInRect:NSMakeRect(0, 0, sz.width, sz.height)];
|
||||
|
||||
[self->rep bitmapData];
|
||||
}
|
||||
|
|
@ -488,12 +517,7 @@
|
|||
|
||||
- (void)setFrameSize:(NSSize)newSize {
|
||||
[super setFrameSize:newSize];
|
||||
if (newSize.width != 0 && newSize.height != 0) {
|
||||
// [self->rep setSize:newSize];
|
||||
// width = newSize.width;
|
||||
// height = newSize.height;
|
||||
// [self->context setImageInterpolation:NSImageInterpolationHigh];
|
||||
}
|
||||
[self->rep setSize:newSize];
|
||||
}
|
||||
|
||||
- (void)displayRect:(NSRect)rect {
|
||||
|
|
|
|||
|
|
@ -1,44 +1,49 @@
|
|||
#ifndef __APPLE__
|
||||
|
||||
#include <Mw/Milsko.h>
|
||||
#include <Mw/Widget/OpenGL.h>
|
||||
|
||||
#ifdef USE_GDI
|
||||
typedef HGLRC(WINAPI* MWwglCreateContext)(HDC);
|
||||
typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC);
|
||||
typedef PROC(WINAPI* MWwglGetProcAddress)(LPCSTR);
|
||||
typedef BOOL(WINAPI* MWwglDeleteContext)(HGLRC);
|
||||
typedef HGLRC(WINAPI *MWwglCreateContext)(HDC);
|
||||
typedef BOOL(WINAPI *MWwglMakeCurrent)(HDC, HGLRC);
|
||||
typedef PROC(WINAPI *MWwglGetProcAddress)(LPCSTR);
|
||||
typedef BOOL(WINAPI *MWwglDeleteContext)(HGLRC);
|
||||
|
||||
typedef struct gdiopengl {
|
||||
HDC dc;
|
||||
HGLRC gl;
|
||||
HDC dc;
|
||||
HGLRC gl;
|
||||
|
||||
void* lib;
|
||||
void *lib;
|
||||
|
||||
MWwglCreateContext wglCreateContext;
|
||||
MWwglMakeCurrent wglMakeCurrent;
|
||||
MWwglDeleteContext wglDeleteContext;
|
||||
MWwglGetProcAddress wglGetProcAddress;
|
||||
MWwglCreateContext wglCreateContext;
|
||||
MWwglMakeCurrent wglMakeCurrent;
|
||||
MWwglDeleteContext wglDeleteContext;
|
||||
MWwglGetProcAddress wglGetProcAddress;
|
||||
} gdiopengl_t;
|
||||
#endif
|
||||
#ifdef USE_X11
|
||||
typedef XVisualInfo* (*MWglXChooseVisual)(Display* dpy, int screen, int* attribList);
|
||||
typedef GLXContext (*MWglXCreateContext)(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct);
|
||||
typedef void (*MWglXDestroyContext)(Display* dpy, GLXContext ctx);
|
||||
typedef Bool (*MWglXMakeCurrent)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
|
||||
typedef void (*MWglXSwapBuffers)(Display* dpy, GLXDrawable drawable);
|
||||
typedef void* (*MWglXGetProcAddress)(const GLubyte* procname);
|
||||
typedef XVisualInfo *(*MWglXChooseVisual)(Display *dpy, int screen,
|
||||
int *attribList);
|
||||
typedef GLXContext (*MWglXCreateContext)(Display *dpy, XVisualInfo *vis,
|
||||
GLXContext shareList, Bool direct);
|
||||
typedef void (*MWglXDestroyContext)(Display *dpy, GLXContext ctx);
|
||||
typedef Bool (*MWglXMakeCurrent)(Display *dpy, GLXDrawable drawable,
|
||||
GLXContext ctx);
|
||||
typedef void (*MWglXSwapBuffers)(Display *dpy, GLXDrawable drawable);
|
||||
typedef void *(*MWglXGetProcAddress)(const GLubyte *procname);
|
||||
|
||||
typedef struct x11opengl {
|
||||
XVisualInfo* visual;
|
||||
GLXContext gl;
|
||||
XVisualInfo *visual;
|
||||
GLXContext gl;
|
||||
|
||||
void* lib;
|
||||
void *lib;
|
||||
|
||||
MWglXChooseVisual glXChooseVisual;
|
||||
MWglXCreateContext glXCreateContext;
|
||||
MWglXDestroyContext glXDestroyContext;
|
||||
MWglXMakeCurrent glXMakeCurrent;
|
||||
MWglXSwapBuffers glXSwapBuffers;
|
||||
MWglXGetProcAddress glXGetProcAddress;
|
||||
MWglXChooseVisual glXChooseVisual;
|
||||
MWglXCreateContext glXCreateContext;
|
||||
MWglXDestroyContext glXDestroyContext;
|
||||
MWglXMakeCurrent glXMakeCurrent;
|
||||
MWglXSwapBuffers glXSwapBuffers;
|
||||
MWglXGetProcAddress glXGetProcAddress;
|
||||
} x11opengl_t;
|
||||
#endif
|
||||
|
||||
|
|
@ -47,348 +52,385 @@ typedef struct x11opengl {
|
|||
#include <wayland-egl-core.h>
|
||||
|
||||
typedef struct waylandopengl {
|
||||
EGLNativeWindowType egl_window_native;
|
||||
EGLDisplay egl_display;
|
||||
EGLContext egl_context;
|
||||
EGLSurface egl_surface;
|
||||
EGLConfig egl_config;
|
||||
EGLNativeWindowType egl_window_native;
|
||||
EGLDisplay egl_display;
|
||||
EGLContext egl_context;
|
||||
EGLSurface egl_surface;
|
||||
EGLConfig egl_config;
|
||||
} waylandopengl_t;
|
||||
#endif
|
||||
|
||||
static int create(MwWidget handle) {
|
||||
void* r = NULL;
|
||||
MwWidget w = handle;
|
||||
void *r = NULL;
|
||||
MwWidget w = handle;
|
||||
|
||||
#ifdef USE_GDI
|
||||
if(handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int pf;
|
||||
gdiopengl_t* o = r = malloc(sizeof(*o));
|
||||
if (handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int pf;
|
||||
gdiopengl_t *o = r = malloc(sizeof(*o));
|
||||
|
||||
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;
|
||||
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->gdi.hWnd);
|
||||
o->dc = GetDC(handle->lowlevel->gdi.hWnd);
|
||||
|
||||
pf = ChoosePixelFormat(o->dc, &pfd);
|
||||
SetPixelFormat(o->dc, pf, &pfd);
|
||||
pf = ChoosePixelFormat(o->dc, &pfd);
|
||||
SetPixelFormat(o->dc, pf, &pfd);
|
||||
|
||||
o->lib = MwDynamicOpen("opengl32.dll");
|
||||
o->lib = MwDynamicOpen("opengl32.dll");
|
||||
|
||||
o->wglCreateContext = (MWwglCreateContext)(void*)MwDynamicSymbol(o->lib, "wglCreateContext");
|
||||
o->wglMakeCurrent = (MWwglMakeCurrent)(void*)MwDynamicSymbol(o->lib, "wglMakeCurrent");
|
||||
o->wglDeleteContext = (MWwglDeleteContext)(void*)MwDynamicSymbol(o->lib, "wglDeleteContext");
|
||||
o->wglGetProcAddress = (MWwglGetProcAddress)(void*)MwDynamicSymbol(o->lib, "wglGetProcAddress");
|
||||
o->wglCreateContext =
|
||||
(MWwglCreateContext)(void *)MwDynamicSymbol(o->lib, "wglCreateContext");
|
||||
o->wglMakeCurrent =
|
||||
(MWwglMakeCurrent)(void *)MwDynamicSymbol(o->lib, "wglMakeCurrent");
|
||||
o->wglDeleteContext =
|
||||
(MWwglDeleteContext)(void *)MwDynamicSymbol(o->lib, "wglDeleteContext");
|
||||
o->wglGetProcAddress = (MWwglGetProcAddress)(void *)MwDynamicSymbol(
|
||||
o->lib, "wglGetProcAddress");
|
||||
|
||||
o->gl = o->wglCreateContext(o->dc);
|
||||
}
|
||||
o->gl = o->wglCreateContext(o->dc);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_X11
|
||||
if(handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
int attribs[5];
|
||||
const char* glpath[] = {
|
||||
"libGL.so",
|
||||
"/usr/local/lib/libGL.so",
|
||||
"/usr/X11R7/lib/libGL.so",
|
||||
"/usr/pkg/lib/libGL.so"};
|
||||
int glincr = 0;
|
||||
x11opengl_t* o = r = malloc(sizeof(*o));
|
||||
if (handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
int attribs[5];
|
||||
const char *glpath[] = {"libGL.so", "/usr/local/lib/libGL.so",
|
||||
"/usr/X11R7/lib/libGL.so", "/usr/pkg/lib/libGL.so"};
|
||||
int glincr = 0;
|
||||
x11opengl_t *o = r = malloc(sizeof(*o));
|
||||
|
||||
attribs[0] = GLX_RGBA;
|
||||
attribs[1] = GLX_DOUBLEBUFFER;
|
||||
attribs[2] = GLX_DEPTH_SIZE;
|
||||
attribs[3] = 24;
|
||||
attribs[4] = None;
|
||||
attribs[0] = GLX_RGBA;
|
||||
attribs[1] = GLX_DOUBLEBUFFER;
|
||||
attribs[2] = GLX_DEPTH_SIZE;
|
||||
attribs[3] = 24;
|
||||
attribs[4] = None;
|
||||
|
||||
while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL);
|
||||
while (glpath[glincr] != NULL &&
|
||||
(o->lib = MwDynamicOpen(glpath[glincr++])) == NULL)
|
||||
;
|
||||
|
||||
o->glXChooseVisual = (MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual");
|
||||
o->glXCreateContext = (MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext");
|
||||
o->glXDestroyContext = (MWglXDestroyContext)MwDynamicSymbol(o->lib, "glXDestroyContext");
|
||||
o->glXMakeCurrent = (MWglXMakeCurrent)MwDynamicSymbol(o->lib, "glXMakeCurrent");
|
||||
o->glXSwapBuffers = (MWglXSwapBuffers)MwDynamicSymbol(o->lib, "glXSwapBuffers");
|
||||
o->glXGetProcAddress = (MWglXGetProcAddress)MwDynamicSymbol(o->lib, "glXGetProcAddress");
|
||||
o->glXChooseVisual =
|
||||
(MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual");
|
||||
o->glXCreateContext =
|
||||
(MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext");
|
||||
o->glXDestroyContext =
|
||||
(MWglXDestroyContext)MwDynamicSymbol(o->lib, "glXDestroyContext");
|
||||
o->glXMakeCurrent =
|
||||
(MWglXMakeCurrent)MwDynamicSymbol(o->lib, "glXMakeCurrent");
|
||||
o->glXSwapBuffers =
|
||||
(MWglXSwapBuffers)MwDynamicSymbol(o->lib, "glXSwapBuffers");
|
||||
o->glXGetProcAddress =
|
||||
(MWglXGetProcAddress)MwDynamicSymbol(o->lib, "glXGetProcAddress");
|
||||
|
||||
/* XXX: fix this */
|
||||
o->visual = o->glXChooseVisual(handle->lowlevel->x11.display, DefaultScreen(handle->lowlevel->x11.display), attribs);
|
||||
o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL, GL_TRUE);
|
||||
}
|
||||
/* XXX: fix this */
|
||||
o->visual = o->glXChooseVisual(handle->lowlevel->x11.display,
|
||||
DefaultScreen(handle->lowlevel->x11.display),
|
||||
attribs);
|
||||
o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL,
|
||||
GL_TRUE);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WAYLAND
|
||||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
int err;
|
||||
EGLint numConfigs;
|
||||
EGLint majorVersion;
|
||||
EGLint minorVersion;
|
||||
EGLContext context;
|
||||
EGLSurface surface;
|
||||
EGLint fbAttribs[] =
|
||||
{
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE};
|
||||
EGLint contextAttribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||
EGL_CONTEXT_MAJOR_VERSION, 1,
|
||||
EGL_CONTEXT_MINOR_VERSION, 1,
|
||||
EGL_NONE};
|
||||
EGLDisplay display;
|
||||
waylandopengl_t* o = r = malloc(sizeof(*o));
|
||||
MwLL topmost_parent = handle->lowlevel->wayland.parent;
|
||||
topmost_parent->wayland.always_render = MwTRUE;
|
||||
if (handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
int err;
|
||||
EGLint numConfigs;
|
||||
EGLint majorVersion;
|
||||
EGLint minorVersion;
|
||||
EGLContext context;
|
||||
EGLSurface surface;
|
||||
EGLint fbAttribs[] = {EGL_SURFACE_TYPE,
|
||||
EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_DEPTH_SIZE,
|
||||
24,
|
||||
EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_BIT,
|
||||
EGL_NONE};
|
||||
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION,
|
||||
1,
|
||||
EGL_CONTEXT_MAJOR_VERSION,
|
||||
1,
|
||||
EGL_CONTEXT_MINOR_VERSION,
|
||||
1,
|
||||
EGL_NONE};
|
||||
EGLDisplay display;
|
||||
waylandopengl_t *o = r = malloc(sizeof(*o));
|
||||
MwLL topmost_parent = handle->lowlevel->wayland.parent;
|
||||
topmost_parent->wayland.always_render = MwTRUE;
|
||||
|
||||
while(topmost_parent->wayland.parent != NULL) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
topmost_parent->wayland.always_render = MwTRUE;
|
||||
}
|
||||
while (topmost_parent->wayland.parent != NULL) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
topmost_parent->wayland.always_render = MwTRUE;
|
||||
}
|
||||
|
||||
display = eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display);
|
||||
if(display == EGL_NO_DISPLAY) {
|
||||
printf("ERROR: eglGetDisplay, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
/* Initialize EGL */
|
||||
if(!eglInitialize(display, &majorVersion, &minorVersion)) {
|
||||
printf("ERROR: eglInitialize, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
display =
|
||||
eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display);
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
printf("ERROR: eglGetDisplay, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
/* Initialize EGL */
|
||||
if (!eglInitialize(display, &majorVersion, &minorVersion)) {
|
||||
printf("ERROR: eglInitialize, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
/* Get configs */
|
||||
if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) || (numConfigs == 0)) {
|
||||
printf("ERROR: eglGetConfigs, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
/* Get configs */
|
||||
if ((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) ||
|
||||
(numConfigs == 0)) {
|
||||
printf("ERROR: eglGetConfigs, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
/* Choose config */
|
||||
if((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
|
||||
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
/* Choose config */
|
||||
if ((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) !=
|
||||
EGL_TRUE) ||
|
||||
(numConfigs != 1)) {
|
||||
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
o->egl_window_native =
|
||||
(EGLNativeWindowType)wl_egl_window_create(handle->lowlevel->wayland.framebuffer.surface, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh);
|
||||
if(!o->egl_window_native) {
|
||||
printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n");
|
||||
return MwFALSE;
|
||||
}
|
||||
o->egl_window_native = (EGLNativeWindowType)wl_egl_window_create(
|
||||
handle->lowlevel->wayland.framebuffer.surface,
|
||||
handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh);
|
||||
if (!o->egl_window_native) {
|
||||
printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n");
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
/* Create a surface */
|
||||
surface = eglCreateWindowSurface(display, o->egl_config, o->egl_window_native, NULL);
|
||||
if(surface == EGL_NO_SURFACE) {
|
||||
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
/* Create a surface */
|
||||
surface = eglCreateWindowSurface(display, o->egl_config,
|
||||
o->egl_window_native, NULL);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
/* Create a GL context */
|
||||
context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if(context == EGL_NO_CONTEXT) {
|
||||
printf("ERROR: eglCreateContext, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
/* Create a GL context */
|
||||
context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT,
|
||||
contextAttribs);
|
||||
if (context == EGL_NO_CONTEXT) {
|
||||
printf("ERROR: eglCreateContext, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
if(!eglMakeCurrent(display, surface, surface, context)) {
|
||||
printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError());
|
||||
}
|
||||
if (!eglMakeCurrent(display, surface, surface, context)) {
|
||||
printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError());
|
||||
}
|
||||
|
||||
o->egl_display = display;
|
||||
o->egl_surface = surface;
|
||||
o->egl_context = context;
|
||||
}
|
||||
o->egl_display = display;
|
||||
o->egl_surface = surface;
|
||||
o->egl_context = context;
|
||||
}
|
||||
#endif
|
||||
|
||||
handle->internal = r;
|
||||
handle->lowlevel->common.copy_buffer = 0;
|
||||
handle->internal = r;
|
||||
handle->lowlevel->common.copy_buffer = 0;
|
||||
|
||||
MwSetDefault(handle);
|
||||
MwSetDefault(handle);
|
||||
|
||||
while(w->parent != NULL) w = w->parent;
|
||||
while (w->parent != NULL)
|
||||
w = w->parent;
|
||||
|
||||
w->berserk++;
|
||||
w->berserk++;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
MwWidget w = handle;
|
||||
MwWidget w = handle;
|
||||
|
||||
#ifdef USE_GDI
|
||||
if(handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t *o = handle->internal;
|
||||
|
||||
o->wglMakeCurrent(NULL, NULL);
|
||||
DeleteDC(o->dc);
|
||||
o->wglDeleteContext(o->gl);
|
||||
o->wglMakeCurrent(NULL, NULL);
|
||||
DeleteDC(o->dc);
|
||||
o->wglDeleteContext(o->gl);
|
||||
|
||||
MwDynamicClose(o->lib);
|
||||
}
|
||||
MwDynamicClose(o->lib);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_X11
|
||||
if(handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t *o = handle->internal;
|
||||
|
||||
o->glXMakeCurrent(handle->lowlevel->x11.display, None, NULL);
|
||||
o->glXDestroyContext(handle->lowlevel->x11.display, o->gl);
|
||||
o->glXMakeCurrent(handle->lowlevel->x11.display, None, NULL);
|
||||
o->glXDestroyContext(handle->lowlevel->x11.display, o->gl);
|
||||
|
||||
MwDynamicClose(o->lib);
|
||||
}
|
||||
MwDynamicClose(o->lib);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WAYLAND
|
||||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
/* todo */
|
||||
}
|
||||
if (handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
/* todo */
|
||||
}
|
||||
#endif
|
||||
|
||||
while(w->parent != NULL) w = w->parent;
|
||||
while (w->parent != NULL)
|
||||
w = w->parent;
|
||||
|
||||
w->berserk--;
|
||||
w->berserk--;
|
||||
|
||||
free(handle->internal);
|
||||
free(handle->internal);
|
||||
}
|
||||
|
||||
static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
|
||||
/* these swap interval functions belonging here actually stink! */
|
||||
/* these swap interval functions belonging here actually stink! */
|
||||
|
||||
#ifdef USE_GDI
|
||||
if(handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t* o = handle->internal;
|
||||
void (*swap_interval_ext)(int) = NULL;
|
||||
if (handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t *o = handle->internal;
|
||||
void (*swap_interval_ext)(int) = NULL;
|
||||
|
||||
o->wglMakeCurrent(o->dc, o->gl);
|
||||
o->wglMakeCurrent(o->dc, o->gl);
|
||||
|
||||
if((swap_interval_ext = MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) {
|
||||
swap_interval_ext(1);
|
||||
}
|
||||
}
|
||||
if ((swap_interval_ext =
|
||||
MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) {
|
||||
swap_interval_ext(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_X11
|
||||
if(handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t* o = handle->internal;
|
||||
void (*swap_interval_ext)(Display*, GLXDrawable, int) = NULL;
|
||||
void (*swap_interval_mesa)(unsigned int) = NULL;
|
||||
void (*swap_interval_sgi)(int) = NULL;
|
||||
if (handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t *o = handle->internal;
|
||||
void (*swap_interval_ext)(Display *, GLXDrawable, int) = NULL;
|
||||
void (*swap_interval_mesa)(unsigned int) = NULL;
|
||||
void (*swap_interval_sgi)(int) = NULL;
|
||||
|
||||
o->glXMakeCurrent(handle->lowlevel->x11.display, handle->lowlevel->x11.window, o->gl);
|
||||
o->glXMakeCurrent(handle->lowlevel->x11.display,
|
||||
handle->lowlevel->x11.window, o->gl);
|
||||
|
||||
if((swap_interval_ext = MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) {
|
||||
swap_interval_ext(handle->lowlevel->x11.display, handle->lowlevel->x11.window, 1);
|
||||
}
|
||||
if ((swap_interval_ext =
|
||||
MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) {
|
||||
swap_interval_ext(handle->lowlevel->x11.display,
|
||||
handle->lowlevel->x11.window, 1);
|
||||
}
|
||||
|
||||
if((swap_interval_mesa = MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) {
|
||||
swap_interval_mesa(1);
|
||||
}
|
||||
if ((swap_interval_mesa =
|
||||
MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) {
|
||||
swap_interval_mesa(1);
|
||||
}
|
||||
|
||||
if((swap_interval_sgi = MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) {
|
||||
swap_interval_sgi(1);
|
||||
}
|
||||
}
|
||||
if ((swap_interval_sgi =
|
||||
MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) {
|
||||
swap_interval_sgi(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WAYLAND
|
||||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
waylandopengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
waylandopengl_t *o = handle->internal;
|
||||
|
||||
if(!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface, o->egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
}
|
||||
if (!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface,
|
||||
o->egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
}
|
||||
|
||||
eglSwapInterval(o->egl_display, 1);
|
||||
}
|
||||
eglSwapInterval(o->egl_display, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void mwOpenGLSwapBufferImpl(MwWidget handle) {
|
||||
#ifdef USE_GDI
|
||||
if(handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t *o = handle->internal;
|
||||
|
||||
SwapBuffers(o->dc);
|
||||
}
|
||||
SwapBuffers(o->dc);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_X11
|
||||
if(handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t *o = handle->internal;
|
||||
|
||||
o->glXSwapBuffers(handle->lowlevel->x11.display, handle->lowlevel->x11.window);
|
||||
}
|
||||
o->glXSwapBuffers(handle->lowlevel->x11.display,
|
||||
handle->lowlevel->x11.window);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WAYLAND
|
||||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
waylandopengl_t* o = handle->internal;
|
||||
eglSwapInterval(o->egl_display, 0);
|
||||
if(!eglSwapBuffers(o->egl_display, o->egl_surface)) {
|
||||
printf("ERROR: eglSwapBuffers, %0X\n", eglGetError());
|
||||
};
|
||||
wl_egl_window_resize((struct wl_egl_window*)o->egl_window_native, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh, 0, 0);
|
||||
MwLLForceRender(handle->lowlevel);
|
||||
}
|
||||
if (handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
waylandopengl_t *o = handle->internal;
|
||||
eglSwapInterval(o->egl_display, 0);
|
||||
if (!eglSwapBuffers(o->egl_display, o->egl_surface)) {
|
||||
printf("ERROR: eglSwapBuffers, %0X\n", eglGetError());
|
||||
};
|
||||
wl_egl_window_resize((struct wl_egl_window *)o->egl_window_native,
|
||||
handle->lowlevel->wayland.ww,
|
||||
handle->lowlevel->wayland.wh, 0, 0);
|
||||
MwLLForceRender(handle->lowlevel);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) {
|
||||
static void *mwOpenGLGetProcAddressImpl(MwWidget handle, const char *name) {
|
||||
#ifdef USE_GDI
|
||||
if(handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendGDI) {
|
||||
gdiopengl_t *o = handle->internal;
|
||||
|
||||
return o->wglGetProcAddress(name);
|
||||
}
|
||||
return o->wglGetProcAddress(name);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_X11
|
||||
if(handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t* o = handle->internal;
|
||||
if (handle->lowlevel->common.type == MwLLBackendX11) {
|
||||
x11opengl_t *o = handle->internal;
|
||||
|
||||
return o->glXGetProcAddress((const GLubyte*)name);
|
||||
}
|
||||
return o->glXGetProcAddress((const GLubyte *)name);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WAYLAND
|
||||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
return eglGetProcAddress(name);
|
||||
}
|
||||
if (handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
return eglGetProcAddress(name);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
|
||||
if(strcmp(name, "mwOpenGLMakeCurrent") == 0) {
|
||||
mwOpenGLMakeCurrentImpl(handle);
|
||||
}
|
||||
if(strcmp(name, "mwOpenGLSwapBuffer") == 0) {
|
||||
mwOpenGLSwapBufferImpl(handle);
|
||||
}
|
||||
if(strcmp(name, "mwOpenGLGetProcAddress") == 0) {
|
||||
const char* _name = va_arg(va, const char*);
|
||||
*(void**)out = mwOpenGLGetProcAddressImpl(handle, _name);
|
||||
}
|
||||
static void func_handler(MwWidget handle, const char *name, void *out,
|
||||
va_list va) {
|
||||
if (strcmp(name, "mwOpenGLMakeCurrent") == 0) {
|
||||
mwOpenGLMakeCurrentImpl(handle);
|
||||
}
|
||||
if (strcmp(name, "mwOpenGLSwapBuffer") == 0) {
|
||||
mwOpenGLSwapBufferImpl(handle);
|
||||
}
|
||||
if (strcmp(name, "mwOpenGLGetProcAddress") == 0) {
|
||||
const char *_name = va_arg(va, const char *);
|
||||
*(void **)out = mwOpenGLGetProcAddressImpl(handle, _name);
|
||||
}
|
||||
}
|
||||
|
||||
MwClassRec MwOpenGLClassRec = {
|
||||
create, /* create */
|
||||
destroy, /* destroy */
|
||||
NULL, /* draw */
|
||||
NULL, /* click */
|
||||
NULL, /* parent_resize */
|
||||
NULL, /* prop_change */
|
||||
NULL, /* mouse_move */
|
||||
NULL, /* mouse_up */
|
||||
NULL, /* mouse_down */
|
||||
NULL, /* key */
|
||||
func_handler, /* execute */
|
||||
NULL, /* tick */
|
||||
NULL, /* resize */
|
||||
NULL, /* children_update */
|
||||
NULL, /* children_prop_change */
|
||||
NULL, /* clipboard */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
MwClassRec MwOpenGLClassRec = {create, /* create */
|
||||
destroy, /* destroy */
|
||||
NULL, /* draw */
|
||||
NULL, /* click */
|
||||
NULL, /* parent_resize */
|
||||
NULL, /* prop_change */
|
||||
NULL, /* mouse_move */
|
||||
NULL, /* mouse_up */
|
||||
NULL, /* mouse_down */
|
||||
NULL, /* key */
|
||||
func_handler, /* execute */
|
||||
NULL, /* tick */
|
||||
NULL, /* resize */
|
||||
NULL, /* children_update */
|
||||
NULL, /* children_prop_change */
|
||||
NULL, /* clipboard */
|
||||
NULL, NULL, NULL, NULL};
|
||||
MwClass MwOpenGLClass = &MwOpenGLClassRec;
|
||||
|
||||
#endif
|
||||
128
src/widget/opengl_cocoa.m
Normal file
128
src/widget/opengl_cocoa.m
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include "Mw/Core.h"
|
||||
#include "Mw/StringDefs.h"
|
||||
#include <Mw/Milsko.h>
|
||||
#include <Mw/Widget/OpenGL.h>
|
||||
#import <mach-o/dyld.h>
|
||||
|
||||
@interface MacOpenGLWidget : NSObject {
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
NSOpenGLContext *glc;
|
||||
}
|
||||
|
||||
- (MacOpenGLWidget *)initWithView:(NSView *)view;
|
||||
- (void)destroy;
|
||||
- (void)makeCurrent;
|
||||
- (void)swapBuffer;
|
||||
- (void *)getProcAddressWithName:(const char *)name;
|
||||
|
||||
@end
|
||||
|
||||
static int create(MwWidget handle) {
|
||||
void *r = NULL;
|
||||
MwWidget w = handle;
|
||||
|
||||
int x = MwGetInteger(w, MwNx);
|
||||
int y = MwGetInteger(w, MwNy);
|
||||
int width = MwGetInteger(w, MwNwidth);
|
||||
int height = MwGetInteger(w, MwNheight);
|
||||
|
||||
printf("%d %d\n", width, height);
|
||||
|
||||
MacOpenGLWidget *o = r = [[MacOpenGLWidget alloc]
|
||||
initWithView:[handle->lowlevel->cocoa.real getView]];
|
||||
|
||||
handle->internal = r;
|
||||
handle->lowlevel->common.copy_buffer = 0;
|
||||
|
||||
MwSetDefault(handle);
|
||||
|
||||
while (w->parent != NULL)
|
||||
w = w->parent;
|
||||
|
||||
w->berserk++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
[(MacOpenGLWidget *)handle->internal destroy];
|
||||
}
|
||||
|
||||
static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
|
||||
[(MacOpenGLWidget *)handle->internal makeCurrent];
|
||||
}
|
||||
|
||||
static void mwOpenGLSwapBufferImpl(MwWidget handle) {
|
||||
[(MacOpenGLWidget *)handle->internal swapBuffer];
|
||||
}
|
||||
|
||||
static void *mwOpenGLGetProcAddressImpl(MwWidget handle, const char *name) {
|
||||
return [(MacOpenGLWidget *)handle->internal getProcAddressWithName:name];
|
||||
}
|
||||
|
||||
static void func_handler(MwWidget handle, const char *name, void *out,
|
||||
va_list va) {
|
||||
if (strcmp(name, "mwOpenGLMakeCurrent") == 0) {
|
||||
mwOpenGLMakeCurrentImpl(handle);
|
||||
}
|
||||
if (strcmp(name, "mwOpenGLSwapBuffer") == 0) {
|
||||
mwOpenGLSwapBufferImpl(handle);
|
||||
}
|
||||
if (strcmp(name, "mwOpenGLGetProcAddress") == 0) {
|
||||
const char *_name = va_arg(va, const char *);
|
||||
*(void **)out = mwOpenGLGetProcAddressImpl(handle, _name);
|
||||
}
|
||||
}
|
||||
|
||||
@implementation MacOpenGLWidget
|
||||
|
||||
- (MacOpenGLWidget *)initWithView:(NSView *)view {
|
||||
NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = {
|
||||
NSOpenGLPFAColorSize, 24,
|
||||
NSOpenGLPFAStencilSize, 8,
|
||||
NSOpenGLPFAAlphaSize, 8,
|
||||
NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFANoRecovery, 0};
|
||||
self->pixelFormat =
|
||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes];
|
||||
self->glc =
|
||||
[[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
|
||||
[self->glc setView:view];
|
||||
return self;
|
||||
};
|
||||
- (void)destroy {
|
||||
};
|
||||
- (void)makeCurrent {
|
||||
[self->glc makeCurrentContext];
|
||||
};
|
||||
- (void)swapBuffer {
|
||||
[self->glc flushBuffer];
|
||||
};
|
||||
- (void *)getProcAddressWithName:(const char *)name {
|
||||
if (NSIsSymbolNameDefined(name)) {
|
||||
return NSAddressOfSymbol(NSLookupAndBindSymbol(name));
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
@end
|
||||
|
||||
MwClassRec MwOpenGLClassRec = {create, /* create */
|
||||
destroy, /* destroy */
|
||||
NULL, /* draw */
|
||||
NULL, /* click */
|
||||
NULL, /* parent_resize */
|
||||
NULL, /* prop_change */
|
||||
NULL, /* mouse_move */
|
||||
NULL, /* mouse_up */
|
||||
NULL, /* mouse_down */
|
||||
NULL, /* key */
|
||||
func_handler, /* execute */
|
||||
NULL, /* tick */
|
||||
NULL, /* resize */
|
||||
NULL, /* children_update */
|
||||
NULL, /* children_prop_change */
|
||||
NULL, /* clipboard */
|
||||
NULL, NULL, NULL, NULL};
|
||||
MwClass MwOpenGLClass = &MwOpenGLClassRec;
|
||||
Loading…
Add table
Add a link
Reference in a new issue