mirror of https://github.com/xemu-project/xemu.git
Moved gloffscreen files to gl dir, and the gloffscreen_glx.c. Trimmed gloffscreen_common.c a little. Modified Makefile.target and nv2a.c according to the new gloffscreen files location.
This commit is contained in:
parent
663ce2b88e
commit
e1115b2a7c
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Offscreen OpenGL abstraction layer
|
||||
*
|
||||
* Copyright (c) 2010 Intel
|
||||
* Written by:
|
||||
* Gordon Williams <gordon.williams@collabora.co.uk>
|
||||
* Ian Molton <ian.molton@collabora.co.uk>
|
||||
* Wayo
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef GLOFFSCREEN_H_
|
||||
#define GLOFFSCREEN_H_
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
/* Used to hold data for the OpenGL context */
|
||||
struct _GloContext;
|
||||
typedef struct _GloContext GloContext;
|
||||
|
||||
/* Format flags for glo_surface_create */
|
||||
#define GLO_FF_ALPHA_MASK (0x0001)
|
||||
#define GLO_FF_NOALPHA (0x0000)
|
||||
#define GLO_FF_ALPHA (0x0001)
|
||||
|
||||
#define GLO_FF_BITS_MASK (0x00F0)
|
||||
#define GLO_FF_BITS_16 (0x0020)
|
||||
#define GLO_FF_BITS_24 (0x0030)
|
||||
#define GLO_FF_BITS_32 (0x0040)
|
||||
|
||||
#define GLO_FF_DEPTH_MASK (0x0F00)
|
||||
#define GLO_FF_DEPTH_16 (0x0100)
|
||||
#define GLO_FF_DEPTH_24 (0x0200)
|
||||
#define GLO_FF_DEPTH_32 (0x0300)
|
||||
|
||||
#define GLO_FF_STENCIL_MASK (0xF000)
|
||||
#define GLO_FF_STENCIL_8 (0x1000)
|
||||
|
||||
/* The only currently supported format */
|
||||
#define GLO_FF_DEFAULT (GLO_FF_BITS_24|GLO_FF_DEPTH_24)
|
||||
|
||||
/* Has gloffscreen been previously initialised? */
|
||||
extern int glo_initialised(void);
|
||||
|
||||
/* Initialise gloffscreen */
|
||||
extern void glo_init(void);
|
||||
|
||||
/* Change current context */
|
||||
extern void glo_set_current(GloContext *context);
|
||||
|
||||
/* Uninitialise gloffscreen */
|
||||
extern void glo_kill(void);
|
||||
|
||||
/* Check GL Extensions */
|
||||
extern GLboolean glo_check_extension(
|
||||
const GLubyte *extName, const GLubyte *extString);
|
||||
|
||||
/* Create an OpenGL context for a certain
|
||||
* pixel format. formatflags are from the
|
||||
* GLO_ constants */
|
||||
extern GloContext *glo_context_create(int formatFlags);
|
||||
|
||||
/* Destroy a previouslu created OpenGL context */
|
||||
extern void glo_context_destroy(GloContext *context);
|
||||
|
||||
/* Functions to decode the format flags */
|
||||
extern int glo_flags_get_depth_bits(int formatFlags);
|
||||
extern int glo_flags_get_stencil_bits(int formatFlags);
|
||||
extern void glo_flags_get_rgba_bits(int formatFlags, int *rgba);
|
||||
extern int glo_flags_get_bytes_per_pixel(int formatFlags);
|
||||
extern void glo_flags_get_readpixel_type(int formatFlags, int *glFormat, int *glType);
|
||||
/* Score how close the given format flags match. 0=great, >0 not so great */
|
||||
extern int glo_flags_score(int formatFlagsExpected, int formatFlagsReal);
|
||||
|
||||
/* Create a set of format flags from a null-terminated list
|
||||
* of GLX fbConfig flags. If assumeBooleans is set, items such
|
||||
* as GLX_RGBA/GLX_DOUBLEBUFFER are treated as booleans, not key-value pairs
|
||||
* (glXChooseVisual treats them as booleans, glXChooseFBConfig as key-value pairs)
|
||||
*/
|
||||
extern int glo_flags_get_from_glx(const int *fbConfig, int assumeBooleans);
|
||||
/* Use in place of glxGetConfig - returns information from flags based on a GLX enum */
|
||||
extern int glo_get_glx_from_flags(int formatFlags, int glxEnum);
|
||||
|
||||
|
||||
/* In terms of speed, glReadPixels actually seems the best we can do.
|
||||
* * On Windows PFB_DRAW_TO_BITMAP is software-only.
|
||||
* * http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt would be
|
||||
* useful if we didn't want the data right away (as we could avoid flushing the
|
||||
* pipeline).
|
||||
* * The internal data format seems to be GL_BGRA - and this is indeed faster.
|
||||
* * Apple suggests using GL_UNSIGNED_INT_8_8_8_8_REV instead of
|
||||
* GL_UNSIGNED_BYTE, but there don't appear to be any speed increase from
|
||||
* doing this on Windows at least.
|
||||
*/
|
||||
|
||||
#endif /* GLOFFSCREEN_H_ */
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Offscreen OpenGL abstraction layer - CGL (Apple) specific
|
||||
*
|
||||
* Copyright (c) 2010 Intel
|
||||
* Written by:
|
||||
* Wayo
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/CGLTypes.h>
|
||||
#include <OpenGL/CGLCurrent.h>
|
||||
#include <GLUT/glut.h>
|
||||
|
||||
#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).
|
||||
*
|
||||
* 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? */
|
||||
};
|
||||
|
||||
struct GloMain glo;
|
||||
int glo_inited = 0;
|
||||
|
||||
struct _GloContext {
|
||||
CGLContextObj cglContext;
|
||||
};
|
||||
|
||||
int glo_initialised(void) {
|
||||
return glo_inited;
|
||||
}
|
||||
|
||||
/* Initialise gloffscreen */
|
||||
void glo_init(void) {
|
||||
/* TODO: CGL Implementation.
|
||||
* Initialization needed for CGL? */
|
||||
|
||||
if (glo_inited) {
|
||||
printf( "gloffscreen already inited\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glo_inited = 1;
|
||||
}
|
||||
|
||||
/* Uninitialise gloffscreen */
|
||||
void glo_kill(void) {
|
||||
glo_inited = 0;
|
||||
}
|
||||
|
||||
/* Create an OpenGL context for a certain pixel format. formatflags are from
|
||||
* the GLO_ constants */
|
||||
GloContext *glo_context_create(int formatFlags)
|
||||
{
|
||||
GloContext *context;
|
||||
|
||||
context = (GloContext *)malloc(sizeof(GloContext));
|
||||
memset(context, 0, sizeof(GloContext));
|
||||
|
||||
/* pixel format attributes */
|
||||
CGLPixelFormatAttribute attributes[] = {
|
||||
kCGLPFAAccelerated,
|
||||
(CGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
CGLPixelFormatObj pix;
|
||||
GLint num;
|
||||
CGLChoosePixelFormat(attributes, &pix, &num);
|
||||
CGLCreateContext(pix, NULL, &context->cglContext);
|
||||
CGLDestroyPixelFormat(pix);
|
||||
|
||||
if (!glo_inited)
|
||||
glo_init();
|
||||
|
||||
glo_set_current(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/* Check if an extension is available. */
|
||||
GLboolean glo_check_extension(const GLubyte *extName,
|
||||
const GLubyte *extString)
|
||||
{
|
||||
return gluCheckExtension(extName, extString);
|
||||
}
|
||||
|
||||
/* Set current context */
|
||||
void glo_set_current(GloContext *context)
|
||||
{
|
||||
if (context == NULL) {
|
||||
CGLSetCurrentContext(NULL);
|
||||
} else {
|
||||
CGLSetCurrentContext(context->cglContext);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy a previously created OpenGL context */
|
||||
void glo_context_destroy(GloContext *context)
|
||||
{
|
||||
if (!context) return;
|
||||
glo_set_current(NULL);
|
||||
CGLDestroyContext(context->cglContext);
|
||||
}
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Offscreen OpenGL abstraction layer - Common utilities
|
||||
*
|
||||
* Copyright (c) 2010 Intel
|
||||
* Written by:
|
||||
* Gordon Williams <gordon.williams@collabora.co.uk>
|
||||
* Ian Molton <ian.molton@collabora.co.uk>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "gloffscreen.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Copied from glx.h as we need them in windows too
|
||||
/*
|
||||
* Tokens for glXChooseVisual and glXGetConfig:
|
||||
*/
|
||||
#define GLX_USE_GL 1
|
||||
#define GLX_BUFFER_SIZE 2
|
||||
#define GLX_LEVEL 3
|
||||
#define GLX_RGBA 4
|
||||
#define GLX_DOUBLEBUFFER 5
|
||||
#define GLX_STEREO 6
|
||||
#define GLX_AUX_BUFFERS 7
|
||||
#define GLX_RED_SIZE 8
|
||||
#define GLX_GREEN_SIZE 9
|
||||
#define GLX_BLUE_SIZE 10
|
||||
#define GLX_ALPHA_SIZE 11
|
||||
#define GLX_DEPTH_SIZE 12
|
||||
#define GLX_STENCIL_SIZE 13
|
||||
#define GLX_ACCUM_RED_SIZE 14
|
||||
#define GLX_ACCUM_GREEN_SIZE 15
|
||||
#define GLX_ACCUM_BLUE_SIZE 16
|
||||
#define GLX_ACCUM_ALPHA_SIZE 17
|
||||
// ---------------------------------------------------
|
||||
|
||||
extern void glo_surface_getcontents_readpixels(int formatFlags, int stride,
|
||||
int bpp, int width, int height, void *data);
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
int glo_flags_get_depth_bits(int formatFlags) {
|
||||
switch ( formatFlags & GLO_FF_DEPTH_MASK ) {
|
||||
case GLO_FF_DEPTH_16: return 16;
|
||||
case GLO_FF_DEPTH_24: return 24;
|
||||
case GLO_FF_DEPTH_32: return 32;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int glo_flags_get_stencil_bits(int formatFlags) {
|
||||
switch ( formatFlags & GLO_FF_STENCIL_MASK ) {
|
||||
case GLO_FF_STENCIL_8: return 8;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void glo_flags_get_rgba_bits(int formatFlags, int *rgba) {
|
||||
int alpha = (formatFlags & GLO_FF_ALPHA) != 0;
|
||||
switch ( formatFlags & GLO_FF_BITS_MASK ) {
|
||||
case GLO_FF_BITS_16:
|
||||
rgba[0] = alpha ? 4 : 5;
|
||||
rgba[1] = alpha ? 4 : 6;
|
||||
rgba[2] = alpha ? 4 : 5;
|
||||
rgba[3] = alpha ? 4 : 0;
|
||||
break;
|
||||
case GLO_FF_BITS_24:
|
||||
// ignore alpha
|
||||
rgba[0] = 8;
|
||||
rgba[1] = 8;
|
||||
rgba[2] = 8;
|
||||
rgba[3] = 0;
|
||||
break;
|
||||
case GLO_FF_BITS_32:
|
||||
rgba[0] = 8;
|
||||
rgba[1] = 8;
|
||||
rgba[2] = 8;
|
||||
rgba[3] = 8;
|
||||
break;
|
||||
default:
|
||||
rgba[0] = 8;
|
||||
rgba[1] = 8;
|
||||
rgba[2] = 8;
|
||||
rgba[3] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int glo_flags_get_bytes_per_pixel(int formatFlags) {
|
||||
switch ( formatFlags & GLO_FF_BITS_MASK ) {
|
||||
case GLO_FF_BITS_16: return 2;
|
||||
case GLO_FF_BITS_24: return 3;
|
||||
case GLO_FF_BITS_32: return 4;
|
||||
default: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
void glo_flags_get_readpixel_type(int formatFlags, int *glFormat, int *glType) {
|
||||
GLenum gFormat, gType;
|
||||
|
||||
if (formatFlags & GLO_FF_ALPHA) {
|
||||
switch ( formatFlags & GLO_FF_BITS_MASK ) {
|
||||
case GLO_FF_BITS_16:
|
||||
gFormat = GL_RGBA;
|
||||
gType = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
break;
|
||||
case GLO_FF_BITS_24:
|
||||
case GLO_FF_BITS_32:
|
||||
default:
|
||||
gFormat = GL_BGRA;
|
||||
gType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ( formatFlags & GLO_FF_BITS_MASK ) {
|
||||
case GLO_FF_BITS_16:
|
||||
gFormat = GL_RGB;
|
||||
gType = GL_UNSIGNED_SHORT_5_6_5;
|
||||
break;
|
||||
case GLO_FF_BITS_24:
|
||||
case GLO_FF_BITS_32:
|
||||
default:
|
||||
gFormat = GL_BGR;
|
||||
gType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (glFormat) *glFormat = gFormat;
|
||||
if (glType) *glType = gType;
|
||||
}
|
||||
|
||||
int glo_flags_score(int formatFlagsExpected, int formatFlagsReal) {
|
||||
if (formatFlagsExpected == formatFlagsReal) return 0;
|
||||
int score = 1;
|
||||
// we wanted alpha, but we didn't get it
|
||||
if ((formatFlagsExpected&GLO_FF_ALPHA_MASK) <
|
||||
(formatFlagsReal&GLO_FF_ALPHA_MASK))
|
||||
score++;
|
||||
// less bits than we expected
|
||||
if ((formatFlagsExpected&GLO_FF_BITS_MASK) <
|
||||
!(formatFlagsReal&GLO_FF_BITS_MASK))
|
||||
score++;
|
||||
// less depth bits than we expected
|
||||
if ((formatFlagsExpected&GLO_FF_DEPTH_MASK) <
|
||||
!(formatFlagsReal&GLO_FF_DEPTH_MASK))
|
||||
score++;
|
||||
// less stencil bits than we expected
|
||||
if ((formatFlagsExpected&GLO_FF_STENCIL_MASK) <
|
||||
!(formatFlagsReal&GLO_FF_STENCIL_MASK))
|
||||
score++;
|
||||
return score;
|
||||
}
|
||||
|
||||
int glo_flags_get_from_glx(const int *fbConfig, int assumeBooleans) {
|
||||
int bufferSize = 0;
|
||||
int depthSize = 0;
|
||||
int stencilSize = 0;
|
||||
int rgbaSize[] = {0,0,0,0};
|
||||
int flags = 0;
|
||||
|
||||
while (*fbConfig) {
|
||||
int isSingle = 0;
|
||||
switch (*fbConfig) {
|
||||
case GLX_USE_GL:
|
||||
isSingle = 1;
|
||||
break;
|
||||
case GLX_BUFFER_SIZE:
|
||||
bufferSize = fbConfig[1];
|
||||
break;
|
||||
case GLX_LEVEL:
|
||||
break;
|
||||
case GLX_RGBA:
|
||||
flags |= GLO_FF_ALPHA;
|
||||
break;
|
||||
case GLX_DOUBLEBUFFER:
|
||||
isSingle = 1;
|
||||
break;
|
||||
case GLX_STEREO:
|
||||
isSingle = 1;
|
||||
break;
|
||||
case GLX_AUX_BUFFERS:
|
||||
break;
|
||||
case GLX_RED_SIZE:
|
||||
rgbaSize[0] = fbConfig[1];
|
||||
break;
|
||||
case GLX_GREEN_SIZE:
|
||||
rgbaSize[1] = fbConfig[1];
|
||||
break;
|
||||
case GLX_BLUE_SIZE:
|
||||
rgbaSize[2] = fbConfig[1];
|
||||
break;
|
||||
case GLX_ALPHA_SIZE:
|
||||
rgbaSize[3] = fbConfig[1];
|
||||
break;
|
||||
case GLX_DEPTH_SIZE:
|
||||
depthSize = fbConfig[1];
|
||||
break;
|
||||
case GLX_STENCIL_SIZE:
|
||||
stencilSize = fbConfig[1];
|
||||
break;
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
break;
|
||||
}
|
||||
// go to next
|
||||
if (isSingle && assumeBooleans)
|
||||
fbConfig++;
|
||||
else
|
||||
fbConfig+=2;
|
||||
}
|
||||
if (rgbaSize[3])
|
||||
flags |= GLO_FF_ALPHA;
|
||||
// ensure we have room for *some* alpha
|
||||
if ((flags & GLO_FF_ALPHA) && (rgbaSize[3]==0))
|
||||
rgbaSize[3] = 1;
|
||||
// Buffer size flag
|
||||
if (bufferSize==0)
|
||||
bufferSize = rgbaSize[0]+rgbaSize[1]+rgbaSize[2]+rgbaSize[3];
|
||||
if (bufferSize==0)
|
||||
bufferSize = (flags & GLO_FF_ALPHA) ? 32 : 24;
|
||||
if (bufferSize<=16)
|
||||
flags |= GLO_FF_BITS_16;
|
||||
else if (bufferSize<=24)
|
||||
flags |= GLO_FF_BITS_24;
|
||||
else flags |= GLO_FF_BITS_32;
|
||||
// Depth
|
||||
if (depthSize<=16)
|
||||
flags |= GLO_FF_DEPTH_16;
|
||||
else if (depthSize<=24)
|
||||
flags |= GLO_FF_DEPTH_24;
|
||||
else flags |= GLO_FF_DEPTH_32;
|
||||
// Stencil
|
||||
if (stencilSize>0)
|
||||
flags |= GLO_FF_STENCIL_8;
|
||||
return flags;
|
||||
}
|
||||
|
||||
int glo_get_glx_from_flags(int formatFlags, int glxEnum) {
|
||||
int rgba[4];
|
||||
glo_flags_get_rgba_bits(formatFlags, rgba);
|
||||
|
||||
switch (glxEnum) {
|
||||
case GLX_USE_GL: return 1;
|
||||
case GLX_BUFFER_SIZE: return glo_flags_get_bytes_per_pixel(formatFlags)*8;
|
||||
case GLX_LEVEL: return 0;
|
||||
case GLX_RGBA: return formatFlags & GLO_FF_ALPHA;
|
||||
case GLX_DOUBLEBUFFER: return 1;
|
||||
case GLX_STEREO: return 0;
|
||||
case GLX_AUX_BUFFERS: return 0;
|
||||
case GLX_RED_SIZE: return rgba[0];
|
||||
case GLX_GREEN_SIZE: return rgba[1];
|
||||
case GLX_BLUE_SIZE: return rgba[2];
|
||||
case GLX_ALPHA_SIZE: return rgba[3];
|
||||
case GLX_DEPTH_SIZE: return glo_flags_get_depth_bits(formatFlags);
|
||||
case GLX_STENCIL_SIZE: return glo_flags_get_stencil_bits(formatFlags);
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* Offscreen OpenGL abstraction layer - WGL (windows) specific
|
||||
*
|
||||
* Copyright (c) 2010 Intel
|
||||
* Written by:
|
||||
* Gordon Williams <gordon.williams@collabora.co.uk>
|
||||
* Ian Molton <ian.molton@collabora.co.uk>
|
||||
* Wayo
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wingdi.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/wglext.h>
|
||||
#include <GL/glut.h>
|
||||
|
||||
#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).
|
||||
*
|
||||
* 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 {
|
||||
HINSTANCE hInstance;
|
||||
HDC hDC;
|
||||
HWND hWnd; /* Our hidden window */
|
||||
HGLRC hContext;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
#define GLO_WINDOW_CLASS "QEmuGLClass"
|
||||
#define DEFAULT_DEPTH_BUFFER (16)
|
||||
|
||||
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
|
||||
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
|
||||
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
|
||||
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
|
||||
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
|
||||
|
||||
int glo_initialised(void) {
|
||||
return glo_inited;
|
||||
}
|
||||
|
||||
/* Initialise gloffscreen */
|
||||
void glo_init(void) {
|
||||
WNDCLASSEX wcx;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
if (glo_inited) {
|
||||
printf("gloffscreen already inited\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Grab An Instance For Our Window */
|
||||
glo.hInstance = GetModuleHandle(NULL);
|
||||
|
||||
wcx.cbSize = sizeof(wcx);
|
||||
wcx.style = 0;
|
||||
wcx.lpfnWndProc = DefWindowProc;
|
||||
wcx.cbClsExtra = 0;
|
||||
wcx.cbWndExtra = 0;
|
||||
wcx.hInstance = glo.hInstance;
|
||||
wcx.hIcon = NULL;
|
||||
wcx.hCursor = NULL;
|
||||
wcx.hbrBackground = NULL;
|
||||
wcx.lpszMenuName = NULL;
|
||||
wcx.lpszClassName = GLO_WINDOW_CLASS;
|
||||
wcx.hIconSm = NULL;
|
||||
RegisterClassEx(&wcx);
|
||||
glo.hWnd = CreateWindow(
|
||||
GLO_WINDOW_CLASS,
|
||||
"QEmuGL",
|
||||
0,0,0,0,0,
|
||||
(HWND)NULL, (HMENU)NULL,
|
||||
glo.hInstance,
|
||||
(LPVOID) NULL);
|
||||
|
||||
if (!glo.hWnd) {
|
||||
printf("Unable to create window\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
glo.hDC = GetDC(glo.hWnd);
|
||||
|
||||
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
unsigned int pixelFormat = ChoosePixelFormat(glo.hDC, &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);
|
||||
}
|
||||
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");
|
||||
|
||||
if (!wglChoosePixelFormatARB ||
|
||||
!wglGetPbufferDCARB ||
|
||||
!wglReleasePbufferDCARB ||
|
||||
!wglCreatePbufferARB ||
|
||||
!wglDestroyPbufferARB) {
|
||||
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);
|
||||
}
|
||||
glo_inited = 1;
|
||||
}
|
||||
|
||||
/* Uninitialise gloffscreen */
|
||||
void glo_kill(void) {
|
||||
if (glo.hContext) {
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(glo.hContext);
|
||||
glo.hContext = NULL;
|
||||
}
|
||||
if (glo.hDC) {
|
||||
ReleaseDC(glo.hWnd, glo.hDC);
|
||||
glo.hDC = NULL;
|
||||
}
|
||||
if (glo.hWnd) {
|
||||
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 */
|
||||
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,
|
||||
WGL_ALPHA_BITS_ARB, 8,
|
||||
WGL_DEPTH_BITS_ARB, 0,
|
||||
WGL_STENCIL_BITS_ARB, 0,
|
||||
WGL_DOUBLE_BUFFER_ARB, FALSE,
|
||||
0
|
||||
};
|
||||
float pf_attrf[] = {0, 0};
|
||||
unsigned int numReturned = 0;
|
||||
int pb_attr[] = { 0 };
|
||||
int rgbaBits[4];
|
||||
|
||||
if (!glo_inited)
|
||||
glo_init();
|
||||
|
||||
context = (GloContext *)malloc(sizeof(GloContext));
|
||||
memset(context, 0, sizeof(GloContext));
|
||||
context->formatFlags = formatFlags;
|
||||
|
||||
/* 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];
|
||||
pf_attri[9] = rgbaBits[2];
|
||||
pf_attri[11] = rgbaBits[3];
|
||||
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) {
|
||||
printf( "No matching configs found.\n" );
|
||||
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,
|
||||
16, 16, pb_attr);
|
||||
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->hContext = wglCreateContext(context->hDC);
|
||||
if (context->hContext == NULL) {
|
||||
printf("Unable to create GL context\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy a previously created OpenGL context */
|
||||
void glo_context_destroy(GloContext *context)
|
||||
{
|
||||
if (!context) return;
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
if (context->hPBuffer != NULL) {
|
||||
wglReleasePbufferDCARB(context->hPBuffer, context->hDC);
|
||||
wglDestroyPbufferARB(context->hPBuffer);
|
||||
}
|
||||
if (context->hDC != NULL) {
|
||||
ReleaseDC(glo.hWnd, context->hDC);
|
||||
}
|
||||
if (context->hContext) {
|
||||
wglDeleteContext(context->hContext);
|
||||
}
|
||||
free(context);
|
||||
}
|
||||
|
||||
|
||||
/* Check extension implementation for Windows.
|
||||
* The Glu 1.2 framework in Windows doesn't include them... */
|
||||
GLboolean glo_check_extension(const GLubyte *extName,
|
||||
const GLubyte *extString)
|
||||
{
|
||||
char *p = (char *) glGetString(GL_EXTENSIONS);
|
||||
char *end;
|
||||
if (p == NULL) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
end = p + strlen(p);
|
||||
|
||||
while (p < end) {
|
||||
int n = strcspn(p, " ");
|
||||
if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0)) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
p += (n + 1);
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
Loading…
Reference in New Issue