Formatting is fun!

This commit is contained in:
wayo 2013-04-01 20:44:50 -06:00 committed by espes
parent 320cbc8b56
commit 6456a4fadb
3 changed files with 191 additions and 257 deletions

View File

@ -36,16 +36,16 @@
#include "gloffscreen.h"
/* In Windows, you must create a window *before* you can create a pbuffer or
* get a context. So we create a hidden Window on startup (see glo_init/GloMain).
* get a context. So we create a hidden Window on startup(see glo_init/GloMain).
*
* Also, you can't share contexts that have different pixel formats, so we can't just
* create a new context from the window. We must create a whole new PBuffer just for
* a context :(
* Also, you can't share contexts that have different pixel formats, so we can't
* just create a new context from the window. We must create a whole new PBuffer
* just for a context :(
*/
struct GloMain {
int init;
// Not needed for CGL?
int init;
/* Not needed for CGL? */
};
struct GloMain glo;
@ -61,8 +61,8 @@ int glo_initialised(void) {
/* Initialise gloffscreen */
void glo_init(void) {
// TODO: CGL Implementation.
// Initialization needed for CGL?
/* TODO: CGL Implementation.
* Initialization needed for CGL? */
if (glo_inited) {
printf( "gloffscreen already inited\n" );
@ -77,7 +77,8 @@ void glo_kill(void) {
glo_inited = 0;
}
/* Create an OpenGL context for a certain pixel format. formatflags are from the GLO_ constants */
/* Create an OpenGL context for a certain pixel format. formatflags are from
* the GLO_ constants */
GloContext *glo_context_create(int formatFlags)
{
GloContext *context;
@ -115,10 +116,12 @@ GLboolean glo_check_extension(const GLubyte *extName,
/* Set current context */
void glo_set_current(GloContext *context)
{
if (context == NULL)
if (context == NULL) {
CGLSetCurrentContext(NULL);
else
}
else {
CGLSetCurrentContext(context->cglContext);
}
}
/* Destroy a previously created OpenGL context */
@ -127,6 +130,6 @@ void glo_context_destroy(GloContext *context)
if (!context) return;
glo_set_current(NULL);
CGLDestroyContext(context->cglContext);
}

View File

@ -48,7 +48,6 @@ int glo_inited = 0;
struct _GloContext {
GLuint formatFlags;
GLXFBConfig fbConfig;
GLXContext context;
};
@ -57,46 +56,48 @@ struct _GloContext {
#define MAX_SURF 128
static GloContext *ctx_arr[MAX_CTX];
static void glo_test_readback_methods(void);
/* ------------------------------------------------------------------------ */
int glo_initialised(void) {
return glo_inited;
int glo_initialised(void)
{
return glo_inited;
}
/* Initialise gloffscreen */
void glo_init(void) {
void glo_init(void)
{
if (glo_inited) {
printf( "gloffscreen already inited\n" );
exit( EXIT_FAILURE );
printf("gloffscreen already inited\n");
exit(EXIT_FAILURE);
}
/* Open a connection to the X server */
glo.dpy = XOpenDisplay( NULL );
if ( glo.dpy == NULL ) {
printf( "Unable to open a connection to the X server\n" );
exit( EXIT_FAILURE );
glo.dpy = XOpenDisplay(NULL);
if (glo.dpy == NULL) {
printf("Unable to open a connection to the X server\n");
exit(EXIT_FAILURE);
}
glo_inited = 1;
glo_test_readback_methods();
}
/* Uninitialise gloffscreen */
void glo_kill(void) {
void glo_kill(void)
{
XCloseDisplay(glo.dpy);
glo.dpy = NULL;
}
/* Create an OpenGL context for a certain pixel format. formatflags are from the GLO_ constants */
GloContext *glo_context_create(int formatFlags, GloContext *shareLists) {
if (!glo_inited)
glo_init();
/* Create an OpenGL context for a certain pixel format. formatflags
* are from the GLO_ constants */
GloContext *glo_context_create(int formatFlags)
{
if (!glo_inited)
glo_init();
GLXFBConfig *fbConfigs;
int numReturned;
GloContext *context;
int rgbaBits[4];
int bufferAttributes[] = {
GLXFBConfig *fbConfigs;
int numReturned;
GloContext *context;
int rgbaBits[4];
int bufferAttributes[] = {
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 8,
@ -106,160 +107,82 @@ GloContext *glo_context_create(int formatFlags, GloContext *shareLists) {
GLX_DEPTH_SIZE, 0,
GLX_STENCIL_SIZE, 0,
None
};
};
if (!glo_inited)
glo_init();
if (!glo_inited)
glo_init();
// set up the surface format from the flags we were given
glo_flags_get_rgba_bits(formatFlags, rgbaBits);
bufferAttributes[5] = rgbaBits[0];
bufferAttributes[7] = rgbaBits[1];
bufferAttributes[9] = rgbaBits[2];
bufferAttributes[11] = rgbaBits[3];
bufferAttributes[13] = glo_flags_get_depth_bits(formatFlags);
bufferAttributes[15] = glo_flags_get_stencil_bits(formatFlags);
// set up the surface format from the flags we were given
glo_flags_get_rgba_bits(formatFlags, rgbaBits);
bufferAttributes[5] = rgbaBits[0];
bufferAttributes[7] = rgbaBits[1];
bufferAttributes[9] = rgbaBits[2];
bufferAttributes[11] = rgbaBits[3];
bufferAttributes[13] = glo_flags_get_depth_bits(formatFlags);
bufferAttributes[15] = glo_flags_get_stencil_bits(formatFlags);
//printf("Got R%d, G%d, B%d, A%d\n", rgbaBits[0], rgbaBits[1], rgbaBits[2], rgbaBits[3]);
fbConfigs = glXChooseFBConfig( glo.dpy, DefaultScreen(glo.dpy),
fbConfigs = glXChooseFBConfig( glo.dpy, DefaultScreen(glo.dpy),
bufferAttributes, &numReturned );
if (numReturned==0) {
printf( "No matching configs found.\n" );
exit( EXIT_FAILURE );
}
context = (GloContext*)malloc(sizeof(GloContext));
memset(context, 0, sizeof(GloContext));
context->formatFlags = formatFlags;
context->fbConfig = fbConfigs[0];
/* Create a GLX context for OpenGL rendering */
context->context = glXCreateNewContext(glo.dpy, context->fbConfig,
GLX_RGBA_TYPE,
shareLists ? shareLists->context: NULL,
True );
if (!context->context) {
printf( "glXCreateNewContext failed\n" );
exit( EXIT_FAILURE );
}
{
int i;
for(i = 0 ; i < MAX_CTX ; i++)
if(ctx_arr[i] == NULL) {
ctx_arr[i] = context;
break;
if (numReturned==0) {
printf("No matching configs found.\n");
exit(EXIT_FAILURE);
}
}
fprintf(stderr, "Nct: %p\n", context->context);
context = (GloContext *)malloc(sizeof(GloContext));
memset(context, 0, sizeof(GloContext));
context->formatFlags = formatFlags;
context->fbConfig = fbConfigs[0];
return context;
/* Create a GLX context for OpenGL rendering */
context->context = glXCreateNewContext(glo.dpy, context->fbConfig,
GLX_RGBA_TYPE,
NULL,
True);
if (!context->context) {
printf("glXCreateNewContext failed\n");
exit(EXIT_FAILURE);
}
{
int i;
for(i = 0; i < MAX_CTX; i++)
if (ctx_arr[i] == NULL) {
ctx_arr[i] = context;
break;
}
}
fprintf(stderr, "Nct: %p\n", context->context);
return context;
}
/* Destroy a previously created OpenGL context */
void glo_context_destroy(GloContext *context) {
void glo_context_destroy(GloContext *context)
{
int i;
if (!context) fprintf(stderr, "CTX NOT FOUND NULL\n");;
for(i = 0 ; i < MAX_CTX ; i++)
if(ctx_arr[i] == context) {
ctx_arr[i] = NULL;
break;
}
if(i == MAX_CTX)
fprintf(stderr, "CTX NOT FOUND %p\n", context);
for(i = 0 ; i < MAX_SURF ; i++)
if(sur_arr[i])
if(sur_arr[i]->context == context)
fprintf(stderr, "In USE! %p\n", sur_arr[i]);
}
{
int i;
if (!context) fprintf(stderr, "CTX NOT FOUND NULL\n");;
for(i = 0 ; i < MAX_CTX ; i++)
if (ctx_arr[i] == context) {
ctx_arr[i] = NULL;
break;
}
if (i == MAX_CTX) {
fprintf(stderr, "CTX NOT FOUND %p\n", context);
}
for (i = 0 ; i < MAX_SURF ; i++) {
if (sur_arr[i]) {
if (sur_arr[i]->context == context) {
fprintf(stderr, "In USE! %p\n", sur_arr[i]);
}
}
}
}
if (!context) return;
// TODO: check for GloSurfaces using this?
fprintf(stderr, "Dst: %p\n", context->context);
glXDestroyContext( glo.dpy, context->context);
free(context);
}
#define TX (17)
#define TY (16)
static int glo_can_readback(void) {
GloContext *context;
GloSurface *surface;
unsigned char *datain = (unsigned char *)malloc(4*TX*TY);
unsigned char *datain_flip = (unsigned char *)malloc(4*TX*TY); // flipped input data (for GL)
unsigned char *dataout = (unsigned char *)malloc(4*TX*TY);
unsigned char *p;
int x,y;
const int bufferAttributes[] = {
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 0,
GLX_STENCIL_SIZE, 0,
0,
};
int bufferFlags = glo_flags_get_from_glx(bufferAttributes, 0);
int bpp = glo_flags_get_bytes_per_pixel(bufferFlags);
int glFormat, glType;
memset(datain_flip, 0, TX*TY*4);
memset(datain, 0, TX*TY*4);
p = datain;
for (y=0;y<TY;y++) {
for (x=0;x<TX;x++) {
p[0] = x;
p[1] = y;
//if (y&1) { p[0]=0; p[1]=0; }
if (bpp>2) p[2] = 0;
if (bpp>3) p[3] = 0xFF;
p+=bpp;
}
memcpy(&datain_flip[((TY-1)-y)*bpp*TX], &datain[y*bpp*TX], bpp*TX);
}
context = glo_context_create(bufferFlags, 0);
surface = glo_surface_create(TX, TY, context);
glo_surface_makecurrent(surface);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,TX, 0,TY, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRasterPos2f(0,0);
glo_flags_get_readpixel_type(bufferFlags, &glFormat, &glType);
glDrawPixels(TX,TY,glFormat, glType, datain_flip);
glFlush();
memset(dataout, 0, bpp*TX*TY);
glo_surface_getcontents(surface, TX*4, bpp*8, dataout);
glo_surface_destroy(surface);
glo_context_destroy(context);
if (memcmp(datain, dataout, bpp*TX*TY)==0)
return 1;
return 0;
}
static void glo_test_readback_methods(void) {
glo.use_ximage = 1;
if(!glo_can_readback())
glo.use_ximage = 0;
fprintf(stderr, "VM GL: Using %s readback\n", glo.use_ximage?"XImage":"glReadPixels");
if (!context) return;
/* TODO: check for GloSurfaces using this? */
fprintf(stderr, "Dst: %p\n", context->context);
glXDestroyContext( glo.dpy, context->context);
free(context);
}

View File

@ -40,11 +40,11 @@
#include "gloffscreen.h"
/* In Windows, you must create a window *before* you can create a pbuffer or
* get a context. So we create a hidden Window on startup (see glo_init/GloMain).
* get a context. So we create a hidden Window on startup(see glo_init/GloMain).
*
* Also, you can't share contexts that have different pixel formats, so we can't just
* create a new context from the window. We must create a whole new PBuffer just for
* a context :(
* Also, you can't share contexts that have different pixel formats, so we can't
* just create a new context from the window. We must create a whole new PBuffer
* just for a context :(
*/
struct GloMain {
@ -58,13 +58,13 @@ struct GloMain glo;
int glo_inited = 0;
struct _GloContext {
int formatFlags;
/* Pixel format returned by wglChoosePixelFormat */
int wglPixelFormat;
/* We need a pbuffer to make a context of the right pixelformat :( */
HPBUFFERARB hPBuffer;
HDC hDC;
HGLRC hContext;
int formatFlags;
/* Pixel format returned by wglChoosePixelFormat */
int wglPixelFormat;
/* We need a pbuffer to make a context of the right pixelformat :( */
HPBUFFERARB hPBuffer;
HDC hDC;
HGLRC hContext;
};
@ -77,9 +77,8 @@ PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
/* */
int glo_initialised(void) {
return glo_inited;
return glo_inited;
}
/* Initialise gloffscreen */
@ -88,11 +87,12 @@ void glo_init(void) {
PIXELFORMATDESCRIPTOR pfd;
if (glo_inited) {
printf( "gloffscreen already inited\n" );
exit( EXIT_FAILURE );
printf("gloffscreen already inited\n");
exit(EXIT_FAILURE);
}
glo.hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
/* Grab An Instance For Our Window */
glo.hInstance = GetModuleHandle(NULL);
wcx.cbSize = sizeof(wcx);
wcx.style = 0;
@ -116,8 +116,8 @@ void glo_init(void) {
(LPVOID) NULL);
if (!glo.hWnd) {
printf( "Unable to create window\n" );
exit( EXIT_FAILURE );
printf("Unable to create window\n");
exit(EXIT_FAILURE );
}
glo.hDC = GetDC(glo.hWnd);
@ -129,75 +129,82 @@ void glo_init(void) {
pfd.cColorBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
unsigned int pixelFormat = ChoosePixelFormat(glo.hDC, &pfd);
DescribePixelFormat(glo.hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
DescribePixelFormat(glo.hDC,
pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
if (!SetPixelFormat(glo.hDC, pixelFormat, &pfd))
return;
glo.hContext = wglCreateContext(glo.hDC);
if (glo.hContext == NULL) {
printf( "Unable to create GL context\n" );
exit( EXIT_FAILURE );
printf("Unable to create GL context\n");
exit(EXIT_FAILURE);
}
wglMakeCurrent(glo.hDC, glo.hContext);
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB");
wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB");
wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB");
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)
wglGetProcAddress("wglChoosePixelFormatARB");
wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)
wglGetProcAddress("wglGetPbufferDCARB");
wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)
wglGetProcAddress("wglReleasePbufferDCARB");
wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)
wglGetProcAddress("wglCreatePbufferARB");
wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)
wglGetProcAddress("wglDestroyPbufferARB");
if (!wglChoosePixelFormatARB ||
!wglGetPbufferDCARB ||
!wglReleasePbufferDCARB ||
!wglCreatePbufferARB ||
!wglDestroyPbufferARB) {
printf( "Unable to load the required WGL extensions\n" );
exit( EXIT_FAILURE );
printf( "Unable to load the required WGL extensions\n" );
exit( EXIT_FAILURE );
}
// Initialize glew
if (GLEW_OK != glewInit())
{
// GLEW failed!
printf("Glew init failed.");
exit(1);
}
/* Initialize glew */
if (GLEW_OK != glewInit())
{
/* GLEW failed! */
printf("Glew init failed.");
exit(1);
}
glo_inited = 1;
}
/* Uninitialise gloffscreen */
void glo_kill(void) {
if (glo.hContext) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(glo.hContext);
glo.hContext = NULL;
wglMakeCurrent(NULL, NULL);
wglDeleteContext(glo.hContext);
glo.hContext = NULL;
}
if (glo.hDC) {
ReleaseDC(glo.hWnd, glo.hDC);
glo.hDC = NULL;
ReleaseDC(glo.hWnd, glo.hDC);
glo.hDC = NULL;
}
if (glo.hWnd) {
DestroyWindow(glo.hWnd);
glo.hWnd = NULL;
DestroyWindow(glo.hWnd);
glo.hWnd = NULL;
}
UnregisterClass(GLO_WINDOW_CLASS, glo.hInstance);
}
/* Create an OpenGL context for a certain pixel format. formatflags are from the GLO_ constants */
/* Create an OpenGL context for a certain pixel format. formatflags are from
* the GLO_ constants */
GloContext *glo_context_create(int formatFlags) {
GloContext *context;
// pixel format attributes
int pf_attri[] = {
WGL_SUPPORT_OPENGL_ARB, TRUE,
WGL_DRAW_TO_PBUFFER_ARB, TRUE,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
/* pixel format attributes */
int pf_attri[] = {
WGL_SUPPORT_OPENGL_ARB, TRUE,
WGL_DRAW_TO_PBUFFER_ARB, TRUE,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 0,
WGL_STENCIL_BITS_ARB, 0,
WGL_DOUBLE_BUFFER_ARB, FALSE,
WGL_DOUBLE_BUFFER_ARB, FALSE,
0
};
float pf_attrf[] = {0, 0};
@ -205,15 +212,14 @@ GloContext *glo_context_create(int formatFlags) {
int pb_attr[] = { 0 };
int rgbaBits[4];
if (!glo_inited)
glo_init();
context = (GloContext*)malloc(sizeof(GloContext));
context = (GloContext *)malloc(sizeof(GloContext));
memset(context, 0, sizeof(GloContext));
context->formatFlags = formatFlags;
// set up the surface format from the flags we were given
/* set up the surface format from the flags we were given */
glo_flags_get_rgba_bits(context->formatFlags, rgbaBits);
pf_attri[5] = rgbaBits[0];
pf_attri[7] = rgbaBits[1];
@ -222,43 +228,45 @@ GloContext *glo_context_create(int formatFlags) {
pf_attri[13] = glo_flags_get_depth_bits(context->formatFlags);
pf_attri[15] = glo_flags_get_stencil_bits(context->formatFlags);
// find out what pixel format to use
wglChoosePixelFormatARB( glo.hDC, pf_attri, pf_attrf, 1, &context->wglPixelFormat, &numReturned);
if( numReturned == 0 ) {
/* find out what pixel format to use */
wglChoosePixelFormatARB(glo.hDC, pf_attri, pf_attrf, 1,
&context->wglPixelFormat, &numReturned);
if (numReturned == 0) {
printf( "No matching configs found.\n" );
exit( EXIT_FAILURE );
exit(EXIT_FAILURE);
}
// We create a tiny pbuffer - just so we can make a context of the right pixel format
context->hPBuffer = wglCreatePbufferARB( glo.hDC, context->wglPixelFormat,
/* We create a tiny pbuffer - just so we can make a context of
* the right pixel format */
context->hPBuffer = wglCreatePbufferARB( glo.hDC, context->wglPixelFormat,
16, 16, pb_attr );
if( !context->hPBuffer ) {
printf( "Couldn't create the PBuffer\n" );
exit( EXIT_FAILURE );
if (!context->hPBuffer) {
printf( "Couldn't create the PBuffer\n" );
exit(EXIT_FAILURE);
}
context->hDC = wglGetPbufferDCARB( context->hPBuffer );
if( !context->hDC ) {
printf( "Couldn't create the DC\n" );
exit( EXIT_FAILURE );
context->hDC = wglGetPbufferDCARB( context->hPBuffer );
if (!context->hDC) {
printf( "Couldn't create the DC\n" );
exit(EXIT_FAILURE);
}
context->hContext = wglCreateContext(context->hDC);
if (context->hContext == NULL) {
printf( "Unable to create GL context\n" );
exit( EXIT_FAILURE );
printf( "Unable to create GL context\n" );
exit(EXIT_FAILURE);
}
glo_set_current(context);
glo_set_current(context);
return context;
}
/* Set current context */
void glo_set_current(GloContext *context) {
if(context == NULL)
wglMakeCurrent(NULL, NULL);
else
wglMakeCurrent(context->hDC, context->hContext);
if(context == NULL)
wglMakeCurrent(NULL, NULL);
else
wglMakeCurrent(context->hDC, context->hContext);
}
/* Destroy a previously created OpenGL context */
@ -266,12 +274,12 @@ void glo_context_destroy(GloContext *context)
{
if (!context) return;
wglMakeCurrent( NULL, NULL );
if( context->hPBuffer != NULL ) {
wglMakeCurrent(NULL, NULL);
if (context->hPBuffer != NULL) {
wglReleasePbufferDCARB( context->hPBuffer, context->hDC );
wglDestroyPbufferARB( context->hPBuffer );
}
if( context->hDC != NULL ) {
if (context->hDC != NULL) {
ReleaseDC( glo.hWnd, context->hDC );
}
if (context->hContext) {