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)/
|
||||
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)
|
||||
|
||||
GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
|
||||
|
|
|
@ -28,4 +28,3 @@ CONFIG_I8259=y
|
|||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_TPM_TIS=y
|
||||
CONFIG_TPM_PASSTHROUGH=y
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#endif
|
||||
|
||||
#include "nv2a.h"
|
||||
#include "gloffscreen.h"
|
||||
#include "gl/gloffscreen.h"
|
||||
|
||||
#define DEBUG_NV2A
|
||||
#ifdef DEBUG_NV2A
|
||||
|
@ -1058,7 +1058,7 @@ static void load_graphics_object(NV2AState *d, hwaddr instance_address,
|
|||
kelvin = &obj->data.kelvin;
|
||||
|
||||
/* generate vertex programs */
|
||||
for (i=0; i<NV2A_VERTEXSHADER_SLOTS; i++) {
|
||||
for (i = 0; i < NV2A_VERTEXSHADER_SLOTS; i++) {
|
||||
VertexShader *shader = &kelvin->vertexshaders[i];
|
||||
glGenProgramsARB(1, &shader->gl_program);
|
||||
}
|
||||
|
@ -1069,7 +1069,7 @@ static void load_graphics_object(NV2AState *d, hwaddr instance_address,
|
|||
kelvin->fragment_program_dirty = true;
|
||||
|
||||
/* generate textures */
|
||||
for (i=0; i<NV2A_MAX_TEXTURES; i++) {
|
||||
for (i = 0; i < NV2A_MAX_TEXTURES; i++) {
|
||||
Texture *texture = &kelvin->textures[i];
|
||||
glGenTextures(1, &texture->gl_texture);
|
||||
glGenTextures(1, &texture->gl_texture_rect);
|
||||
|
|
|
@ -6,8 +6,3 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o
|
|||
obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
||||
obj-$(CONFIG_LINUX_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