mirror of https://github.com/xemu-project/xemu.git
Moved files
This commit is contained in:
parent
e1115b2a7c
commit
7eedd2c223
|
@ -132,6 +132,12 @@ else
|
||||||
obj-y += hw/$(TARGET_BASE_ARCH)/
|
obj-y += hw/$(TARGET_BASE_ARCH)/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# OpenGl Support
|
||||||
|
obj-gl-y += gl/gloffscreen_common.o
|
||||||
|
obj-gl-$(CONFIG_WIN32) += gl/gloffscreen_wgl.o
|
||||||
|
obj-gl-$(CONFIG_DARWIN) += gl/gloffscreen_cgl.o
|
||||||
|
obj-$(CONFIG_OPENGL) += $(obj-gl-y)
|
||||||
|
|
||||||
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
||||||
|
|
||||||
GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
|
GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
|
||||||
|
|
|
@ -28,4 +28,3 @@ CONFIG_I8259=y
|
||||||
CONFIG_PFLASH_CFI01=y
|
CONFIG_PFLASH_CFI01=y
|
||||||
CONFIG_TPM_TIS=y
|
CONFIG_TPM_TIS=y
|
||||||
CONFIG_TPM_PASSTHROUGH=y
|
CONFIG_TPM_PASSTHROUGH=y
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nv2a.h"
|
#include "nv2a.h"
|
||||||
#include "gloffscreen.h"
|
#include "gl/gloffscreen.h"
|
||||||
|
|
||||||
#define DEBUG_NV2A
|
#define DEBUG_NV2A
|
||||||
#ifdef DEBUG_NV2A
|
#ifdef DEBUG_NV2A
|
||||||
|
|
|
@ -6,8 +6,3 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o
|
||||||
obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
||||||
obj-$(CONFIG_LINUX_USER) += ioport-user.o
|
obj-$(CONFIG_LINUX_USER) += ioport-user.o
|
||||||
obj-$(CONFIG_BSD_USER) += ioport-user.o
|
obj-$(CONFIG_BSD_USER) += ioport-user.o
|
||||||
obj-gl-y += gloffscreen_common.o
|
|
||||||
obj-gl-$(CONFIG_WIN32) += gloffscreen_wgl.o
|
|
||||||
obj-gl-$(CONFIG_LINUX) += gloffscreen_glx.o
|
|
||||||
obj-gl-$(CONFIG_DARWIN) += gloffscreen_cgl.o
|
|
||||||
obj-$(CONFIG_OPENGL) += $(obj-gl-y)
|
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* Offscreen OpenGL abstraction layer
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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_ */
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,360 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void glo_surface_getcontents_readpixels(int formatFlags, int stride, int bpp,
|
|
||||||
int width, int height, void *data) {
|
|
||||||
int glFormat, glType, rl, pa;
|
|
||||||
static int once;
|
|
||||||
|
|
||||||
glo_flags_get_readpixel_type(formatFlags, &glFormat, &glType);
|
|
||||||
switch(bpp) {
|
|
||||||
case 24:
|
|
||||||
if(glFormat != GL_BGR) {
|
|
||||||
if(!once) {
|
|
||||||
fprintf(stderr, "Warning: compressing alpha\n");
|
|
||||||
once = 1;
|
|
||||||
}
|
|
||||||
glFormat = GL_BGR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
if(glFormat != GL_BGRA) {
|
|
||||||
fprintf(stderr, "Warning: expanding alpha!\n");
|
|
||||||
glFormat = GL_BGRA;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Warning: unsupported colourdepth\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save guest processes GL state before we ReadPixels()
|
|
||||||
glGetIntegerv(GL_PACK_ROW_LENGTH, &rl);
|
|
||||||
glGetIntegerv(GL_PACK_ALIGNMENT, &pa);
|
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
|
||||||
|
|
||||||
#ifdef GETCONTENTS_INDIVIDUAL
|
|
||||||
GLubyte *b = (GLubyte *)data;
|
|
||||||
int irow;
|
|
||||||
for(irow = height-1 ; irow >= 0 ; irow--) {
|
|
||||||
glReadPixels(0, irow, width, 1, glFormat, glType, b);
|
|
||||||
b += stride;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Faster buffer flip
|
|
||||||
GLubyte *b = (GLubyte *)data;
|
|
||||||
GLubyte *c = &((GLubyte *)data)[stride*(height-1)];
|
|
||||||
GLubyte *tmp = (GLubyte*)malloc(stride);
|
|
||||||
int irow;
|
|
||||||
|
|
||||||
glReadPixels(0, 0, width, height, glFormat, glType, data);
|
|
||||||
|
|
||||||
for(irow = 0; irow < height/2; irow++) {
|
|
||||||
memcpy(tmp, b, stride);
|
|
||||||
memcpy(b, c, stride);
|
|
||||||
memcpy(c, tmp, stride);
|
|
||||||
b += stride;
|
|
||||||
c -= stride;
|
|
||||||
}
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Restore GL state
|
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, rl);
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, pa);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,192 +0,0 @@
|
||||||
/*
|
|
||||||
* Offscreen OpenGL abstraction layer - GLX specific
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
#include <GL/gl.h>
|
|
||||||
#include <GL/glx.h>
|
|
||||||
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <X11/extensions/XShm.h>
|
|
||||||
|
|
||||||
struct GloMain {
|
|
||||||
Display *dpy;
|
|
||||||
int use_ximage;
|
|
||||||
GloSurface *curr_surface;
|
|
||||||
};
|
|
||||||
struct GloMain glo;
|
|
||||||
int glo_inited = 0;
|
|
||||||
|
|
||||||
struct _GloContext {
|
|
||||||
GLuint formatFlags;
|
|
||||||
GLXFBConfig fbConfig;
|
|
||||||
GLXContext context;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_CTX 128
|
|
||||||
#define MAX_SURF 128
|
|
||||||
static GloContext *ctx_arr[MAX_CTX];
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
int glo_initialised(void)
|
|
||||||
{
|
|
||||||
return glo_inited;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialise gloffscreen */
|
|
||||||
void glo_init(void)
|
|
||||||
{
|
|
||||||
if (glo_inited) {
|
|
||||||
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_inited = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Uninitialise gloffscreen */
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (!glo_inited) {
|
|
||||||
glo_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
GLX_GREEN_SIZE, 8,
|
|
||||||
GLX_BLUE_SIZE, 8,
|
|
||||||
GLX_ALPHA_SIZE, 8,
|
|
||||||
GLX_DEPTH_SIZE, 0,
|
|
||||||
GLX_STENCIL_SIZE, 0,
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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,
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,309 +0,0 @@
|
||||||
/*
|
|
||||||
* 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>
|
|
||||||
*
|
|
||||||
* 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