mirror of https://github.com/fltk/fltk
Rewrite OpenGL-related code under the driver model.
Class Fl_Gl_Window_Driver, with its platform-specific derived classes, is created to hold platform-specific, OpenGL code. File gl_draw.cxx still needs to be converted to the driver model. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11716 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
048bb2b0f6
commit
300747225c
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// OpenGL header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2015 by Bill Spitzak and others.
|
||||
// Copyright 1998-2016 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
|
@ -33,7 +33,7 @@ typedef void* GLContext; // actually a GLXContext or HGLDC
|
|||
#endif
|
||||
|
||||
class Fl_Gl_Choice; // structure to hold result of glXChooseVisual
|
||||
|
||||
class Fl_Gl_Window_Driver;
|
||||
/**
|
||||
The Fl_Gl_Window widget sets things up so OpenGL works.
|
||||
|
||||
|
@ -55,6 +55,8 @@ class Fl_Gl_Choice; // structure to hold result of glXChooseVisual
|
|||
unless those widgets are modified to draw using OpenGL calls.
|
||||
*/
|
||||
class FL_EXPORT Fl_Gl_Window : public Fl_Window {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
Fl_Gl_Window_Driver *pGlWindowDriver;
|
||||
|
||||
int mode_;
|
||||
const int *alist;
|
||||
|
@ -66,21 +68,23 @@ class FL_EXPORT Fl_Gl_Window : public Fl_Window {
|
|||
void init();
|
||||
|
||||
void *overlay;
|
||||
void make_overlay();
|
||||
friend class _Fl_Gl_Overlay;
|
||||
|
||||
static int can_do(int, const int *);
|
||||
int mode(int, const int *);
|
||||
static int gl_plugin_linkage();
|
||||
protected:
|
||||
virtual void draw();
|
||||
|
||||
public:
|
||||
|
||||
void show();
|
||||
/** Same as Fl_Window::show(int a, char **b) */
|
||||
void show(int a, char **b) {Fl_Window::show(a,b);}
|
||||
void flush();
|
||||
void hide();
|
||||
void resize(int,int,int,int);
|
||||
int handle(int);
|
||||
/** Returns a pointer to the window's Fl_Gl_Window_Driver object */
|
||||
Fl_Gl_Window_Driver *gl_driver() {return pGlWindowDriver;}
|
||||
|
||||
/**
|
||||
Is turned off when FLTK creates a new context for this window or
|
||||
|
@ -204,50 +208,15 @@ public:
|
|||
void swap_buffers();
|
||||
void ortho();
|
||||
|
||||
/**
|
||||
Returns true if the hardware overlay is possible. If this is false,
|
||||
FLTK will try to simulate the overlay, with significant loss of update
|
||||
speed. Calling this will cause FLTK to open the display.
|
||||
*/
|
||||
int can_do_overlay();
|
||||
/**
|
||||
This method causes draw_overlay() to be called at a later time.
|
||||
Initially the overlay is clear. If you want the window to display
|
||||
something in the overlay when it first appears, you must call this
|
||||
immediately after you show() your window.
|
||||
*/
|
||||
void redraw_overlay();
|
||||
void hide_overlay();
|
||||
/**
|
||||
The make_overlay_current() method selects the OpenGL context
|
||||
for the widget's overlay. It is called automatically prior to the
|
||||
draw_overlay() method being called and can also be used to
|
||||
implement feedback and/or selection within the handle()
|
||||
method.
|
||||
*/
|
||||
void make_overlay_current();
|
||||
|
||||
// Note: Doxygen docs in Fl_Widget.H to avoid redundancy.
|
||||
virtual Fl_Gl_Window* as_gl_window() {return this;}
|
||||
|
||||
/** The number of pixels per FLTK unit of length for the window.
|
||||
Returns 1, except for a window mapped to
|
||||
an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true,
|
||||
when it returns 2. This method dynamically adjusts its value when the window
|
||||
is moved to/from a retina display. This method is useful, e.g., to convert,
|
||||
in a window's handle() method, the FLTK units returned by Fl::event_x() and
|
||||
Fl::event_y() to the pixel units used by the OpenGL source code.
|
||||
\version 1.3.4
|
||||
*/
|
||||
#ifdef __APPLE__ // PORTME: Fl_Surface_Driver - additional functionality
|
||||
int pixels_per_unit();
|
||||
#elif defined(WIN32)
|
||||
int pixels_per_unit() { return 1; }
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: define multiple resolution OpenGL rendering if your platform supports it"
|
||||
#else
|
||||
int pixels_per_unit() { return 1; }
|
||||
#endif
|
||||
/** Gives the window width in OpenGL pixels.
|
||||
Generally identical with the result of the w() function, but for a window mapped to
|
||||
an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true,
|
||||
|
@ -279,17 +248,9 @@ public:
|
|||
|
||||
Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0)
|
||||
: Fl_Window(X,Y,W,H,l) {init();}
|
||||
|
||||
protected:
|
||||
/**
|
||||
Draws the Fl_Gl_Window.
|
||||
|
||||
You \e \b must override the draw() method.
|
||||
*/
|
||||
virtual void draw();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // Fl_Gl_Window_H
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
//
|
||||
// "$Id: Fl_Gl_Window_Driver.H 11696 2016-04-25 06:29:36Z manolo $"
|
||||
//
|
||||
// Definition of classes Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device
|
||||
// for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2016 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems on the following page:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#ifndef Fl_Gl_Window_Driver_H
|
||||
#define Fl_Gl_Window_Driver_H
|
||||
|
||||
#if defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: please, derive and implement the Fl_Gl_Window_Driver class for your platform"
|
||||
#endif
|
||||
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
|
||||
class Fl_Gl_Choice;
|
||||
|
||||
/* The constructor of each Fl_Gl_Window object creates also an object from a
|
||||
platform-specific derived class from this class.
|
||||
*/
|
||||
class Fl_Gl_Window_Driver {
|
||||
protected:
|
||||
Fl_Gl_Window *pWindow;
|
||||
public:
|
||||
Fl_Gl_Choice* g() {return pWindow->g;}
|
||||
void g(Fl_Gl_Choice *c) {pWindow->g = c;}
|
||||
int mode() {return pWindow->mode_;}
|
||||
void mode(int m) { pWindow->mode_ = m;}
|
||||
const int *alist() {return pWindow->alist;}
|
||||
void alist(const int *l) { pWindow->alist = l;}
|
||||
void* overlay() {return pWindow->overlay;}
|
||||
void draw_overlay() {pWindow->draw_overlay();}
|
||||
|
||||
Fl_Gl_Window_Driver(Fl_Gl_Window *win) : pWindow(win) {}
|
||||
virtual ~Fl_Gl_Window_Driver() {}
|
||||
static Fl_Gl_Window_Driver *newGlWindowDriver(Fl_Gl_Window *w);
|
||||
static Fl_Gl_Window_Driver *global();
|
||||
virtual int pixels_per_unit() {return 1;}
|
||||
virtual void before_show(int& need_redraw) {}
|
||||
virtual void after_show(int need_redraw) {}
|
||||
virtual void invalidate();
|
||||
virtual int mode_(int m, const int *a) {return 0;}
|
||||
virtual void make_current_before() {}
|
||||
virtual void make_current_after() {}
|
||||
virtual void swap_buffers() {}
|
||||
virtual void resize(int is_a_resize, int w, int h) {}
|
||||
virtual char swap_type();
|
||||
virtual void flush_context() {}
|
||||
virtual int flush_begin(char& valid_f) {return 0;}
|
||||
virtual void hide_overlay(void *& overlay) {}
|
||||
static Fl_Gl_Choice *find_begin(int m, const int *alistp);
|
||||
// Return one of these structures for a given gl mode.
|
||||
// The second argument is a glX attribute list, and is used if mode is zero.
|
||||
// This is not supported on Win32:
|
||||
virtual Fl_Gl_Choice *find(int mode, const int *alistp) {return NULL;}
|
||||
virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0) {return 0;}
|
||||
virtual void set_gl_context(Fl_Window* w, GLContext context) {}
|
||||
virtual void delete_gl_context(GLContext) {}
|
||||
virtual void make_overlay(void* &o);
|
||||
virtual void hide_overlay() {}
|
||||
virtual void make_overlay_current() {}
|
||||
virtual void redraw_overlay() {}
|
||||
virtual int can_do_overlay() {return 0;}
|
||||
virtual void waitGL() {} // support for gl_finish() function
|
||||
virtual void gl_visual(Fl_Gl_Choice*); // support for Fl::gl_visual() function
|
||||
virtual void gl_start() {} // support for gl_start() function
|
||||
virtual void* GetProcAddress(const char *procName); // support for glutGetProcAddress()
|
||||
};
|
||||
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
|
||||
virtual int pixels_per_unit();
|
||||
virtual void before_show(int& need_redraw);
|
||||
virtual void after_show(int need_redraw);
|
||||
virtual int mode_(int m, const int *a);
|
||||
virtual void make_current_before();
|
||||
virtual void swap_buffers();
|
||||
virtual void resize(int is_a_resize, int w, int h);
|
||||
virtual char swap_type();
|
||||
virtual void flush_context();
|
||||
virtual Fl_Gl_Choice *find(int m, const int *alistp);
|
||||
virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
|
||||
virtual void set_gl_context(Fl_Window* w, GLContext context);
|
||||
virtual void delete_gl_context(GLContext);
|
||||
virtual void make_overlay_current();
|
||||
virtual void redraw_overlay();
|
||||
virtual void gl_start();
|
||||
};
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_GDI
|
||||
|
||||
class Fl_WinAPI_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
Fl_WinAPI_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
|
||||
virtual int mode_(int m, const int *a);
|
||||
virtual void make_current_after();
|
||||
virtual void swap_buffers();
|
||||
virtual void invalidate() {}
|
||||
virtual int flush_begin(char& valid_f);
|
||||
virtual void hide_overlay(void *& overlay);
|
||||
virtual Fl_Gl_Choice *find(int m, const int *alistp);
|
||||
virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
|
||||
virtual void set_gl_context(Fl_Window* w, GLContext context);
|
||||
virtual void delete_gl_context(GLContext);
|
||||
virtual void make_overlay_current();
|
||||
virtual void redraw_overlay();
|
||||
virtual void* GetProcAddress(const char *procName);
|
||||
#if HAVE_GL_OVERLAY
|
||||
virtual int can_do_overlay();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_XLIB
|
||||
#include <X11/Xutil.h>
|
||||
class Fl_X11_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
Fl_X11_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {}
|
||||
virtual void before_show(int& need_redraw);
|
||||
virtual int mode_(int m, const int *a);
|
||||
virtual void swap_buffers();
|
||||
virtual void resize(int is_a_resize, int w, int h);
|
||||
virtual char swap_type();
|
||||
virtual Fl_Gl_Choice *find(int m, const int *alistp);
|
||||
virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
|
||||
virtual void set_gl_context(Fl_Window* w, GLContext context);
|
||||
virtual void delete_gl_context(GLContext);
|
||||
#if HAVE_GL_OVERLAY
|
||||
virtual void make_overlay(void *&o);
|
||||
virtual int can_do_overlay();
|
||||
virtual void hide_overlay();
|
||||
#endif
|
||||
virtual void make_overlay_current();
|
||||
virtual void redraw_overlay();
|
||||
virtual void waitGL();
|
||||
virtual void gl_visual(Fl_Gl_Choice*); // support for Fl::gl_visual()
|
||||
virtual void gl_start();
|
||||
public:
|
||||
static GLContext create_gl_context(XVisualInfo* vis);
|
||||
};
|
||||
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
#endif /* Fl_Gl_Window_Driver_H */
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Gl_Window_Driver.H 11662 2016-04-19 16:58:17Z manolo $".
|
||||
//
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// OpenGL definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2016 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
|
@ -22,41 +22,29 @@
|
|||
// necessary to create a window (on X) and to create an OpenGL "context"
|
||||
// (on both X and Win32).
|
||||
//
|
||||
// fl_create_gl_context takes a window (necessary only on Win32) and an
|
||||
// create_gl_context takes a window (necessary only on Win32) and an
|
||||
// Fl_Gl_Choice and returns a new OpenGL context. All contexts share
|
||||
// display lists with each other.
|
||||
//
|
||||
// On X another fl_create_gl_context is provided to create it for any
|
||||
// On X another create_gl_context is provided to create it for any
|
||||
// X visual.
|
||||
//
|
||||
// fl_set_gl_context makes the given OpenGL context current and makes
|
||||
// set_gl_context makes the given OpenGL context current and makes
|
||||
// it draw into the passed window. It tracks the current one context
|
||||
// to avoid calling the context switching code when the same context
|
||||
// is used, though it is a mystery to me why the GLX/WGL libraries
|
||||
// don't do this themselves...
|
||||
//
|
||||
// fl_no_gl_context clears that cache so the next fl_set_gl_context is
|
||||
// guaranteed to work.
|
||||
//
|
||||
// fl_delete_gl_context destroys the context.
|
||||
// delete_gl_context destroys the context.
|
||||
//
|
||||
// This code is used by Fl_Gl_Window, gl_start(), and gl_visual()
|
||||
|
||||
#ifndef Fl_Gl_Choice_H
|
||||
#define Fl_Gl_Choice_H
|
||||
|
||||
#if defined(WIN32) || defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: add code to list and select OpenGL drawing contexts"
|
||||
#else
|
||||
#endif
|
||||
|
||||
// Warning: whatever GLContext is defined to must take exactly the same
|
||||
// space in a structure as a void*!!!
|
||||
#ifdef WIN32
|
||||
# include <FL/gl.h>
|
||||
# define GLContext HGLRC
|
||||
#elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
|
||||
# include <OpenGL/gl.h>
|
||||
#ifdef __OBJC__
|
||||
@class NSOpenGLPixelFormat;
|
||||
|
@ -67,64 +55,60 @@ class NSOpenGLContext;
|
|||
#endif // __OBJC__
|
||||
typedef NSOpenGLContext* FLOpenGLContextPtr;
|
||||
# define GLContext FLOpenGLContextPtr
|
||||
#else
|
||||
# include <GL/glx.h>
|
||||
# define GLContext GLXContext
|
||||
#endif
|
||||
|
||||
// Describes crap needed to create a GLContext.
|
||||
// Describes crap needed to create a GLContext under Mac OS X.
|
||||
class Fl_Gl_Choice {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
int mode;
|
||||
const int *alist;
|
||||
Fl_Gl_Choice *next;
|
||||
public:
|
||||
#ifdef WIN32
|
||||
int pixelformat; // the visual to use
|
||||
PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
|
||||
#elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management
|
||||
Fl_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : mode(m), alist(alistp), next(n) {}
|
||||
NSOpenGLPixelFormat* pixelformat;
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: define OpenGL pixel format containers"
|
||||
#else
|
||||
XVisualInfo *vis; // the visual to use
|
||||
Colormap colormap; // a colormap for that visual
|
||||
#endif
|
||||
// Return one of these structures for a given gl mode.
|
||||
// The second argument is a glX attribute list, and is used if mode is
|
||||
// zero. This is not supported on Win32:
|
||||
static Fl_Gl_Choice *find(int mode, const int *);
|
||||
};
|
||||
|
||||
class Fl_Window;
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef FL_CFG_GFX_GDI
|
||||
|
||||
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
|
||||
# include <FL/gl.h>
|
||||
# define GLContext HGLRC
|
||||
|
||||
#elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management
|
||||
// Describes crap needed to create a GLContext under MSWindows.
|
||||
class Fl_Gl_Choice {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
int mode;
|
||||
const int *alist;
|
||||
Fl_Gl_Choice *next;
|
||||
public:
|
||||
Fl_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : mode(m), alist(alistp), next(n) {}
|
||||
int pixelformat; // the visual to use
|
||||
PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
|
||||
};
|
||||
|
||||
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
#elif defined(FL_PORTING)
|
||||
#ifdef FL_CFG_GFX_XLIB
|
||||
|
||||
# pragma message "FL_PORTING: define fl_create_gl_context function"
|
||||
# include <GL/glx.h>
|
||||
# define GLContext GLXContext
|
||||
|
||||
#else
|
||||
// Describes crap needed to create a GLContext under X11.
|
||||
class Fl_Gl_Choice {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
int mode;
|
||||
const int *alist;
|
||||
Fl_Gl_Choice *next;
|
||||
public:
|
||||
Fl_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : mode(m), alist(alistp), next(n) {}
|
||||
XVisualInfo *vis; // the visual to use
|
||||
Colormap colormap; // a colormap for that visual
|
||||
};
|
||||
|
||||
GLContext fl_create_gl_context(XVisualInfo* vis);
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
static inline
|
||||
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) {
|
||||
return fl_create_gl_context(g->vis);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void fl_set_gl_context(Fl_Window*, GLContext);
|
||||
void fl_no_gl_context();
|
||||
void fl_delete_gl_context(GLContext);
|
||||
|
||||
#endif
|
||||
#endif // Fl_Gl_Choice_H
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
|
|
@ -16,110 +16,123 @@
|
|||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <config.h>
|
||||
#include "config_lib.h"
|
||||
#if HAVE_GL
|
||||
|
||||
# include <FL/Fl.H>
|
||||
# include <FL/x.H>
|
||||
# include <FL/Fl_Graphics_Driver.H>
|
||||
# include <stdlib.h>
|
||||
# include "Fl_Gl_Choice.H"
|
||||
# include <FL/Fl_Gl_Window.H>
|
||||
# include <FL/Fl_Gl_Window_Driver.H>
|
||||
# include <FL/gl_draw.H>
|
||||
# include "flstring.h"
|
||||
# include <FL/fl_utf8.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
|
||||
#elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: add code to list and select OpenGL drawing contexts"
|
||||
#else
|
||||
#endif
|
||||
|
||||
# ifdef WIN32
|
||||
void fl_save_dc(HWND, HDC);
|
||||
#elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
extern void gl_texture_reset();
|
||||
#endif
|
||||
static GLContext *context_list = 0;
|
||||
static int nContext = 0, NContext = 0;
|
||||
|
||||
static void add_context(GLContext ctx) {
|
||||
if (!ctx) return;
|
||||
if (nContext==NContext) {
|
||||
if (!NContext) NContext = 8;
|
||||
NContext *= 2;
|
||||
context_list = (GLContext*)realloc(
|
||||
context_list, NContext*sizeof(GLContext));
|
||||
}
|
||||
context_list[nContext++] = ctx;
|
||||
}
|
||||
|
||||
static void del_context(GLContext ctx) {
|
||||
int i;
|
||||
for (i=0; i<nContext; i++) {
|
||||
if (context_list[i]==ctx) {
|
||||
memmove(context_list+i, context_list+i+1,
|
||||
(nContext-i-1) * sizeof(GLContext));
|
||||
context_list[--nContext] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nContext) gl_remove_displaylist_fonts();
|
||||
}
|
||||
|
||||
static Fl_Gl_Choice *first;
|
||||
|
||||
// this assumes one of the two arguments is zero:
|
||||
// We keep the list system in Win32 to stay compatible and interpret
|
||||
// the list later...
|
||||
Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
|
||||
Fl_Gl_Choice *Fl_Gl_Window_Driver::find_begin(int m, const int *alistp) {
|
||||
Fl_Gl_Choice *g;
|
||||
|
||||
for (g = first; g; g = g->next)
|
||||
if (g->mode == m && g->alist == alistp)
|
||||
if (g->mode == m && g->alist == alistp)
|
||||
return g;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
const int *blist;
|
||||
int list[32];
|
||||
|
||||
if (alistp)
|
||||
blist = alistp;
|
||||
else {
|
||||
int n = 0;
|
||||
if (m & FL_INDEX) {
|
||||
list[n++] = GLX_BUFFER_SIZE;
|
||||
list[n++] = 8; // glut tries many sizes, but this should work...
|
||||
} else {
|
||||
list[n++] = GLX_RGBA;
|
||||
list[n++] = GLX_GREEN_SIZE;
|
||||
list[n++] = (m & FL_RGB8) ? 8 : 1;
|
||||
if (m & FL_ALPHA) {
|
||||
list[n++] = GLX_ALPHA_SIZE;
|
||||
list[n++] = (m & FL_RGB8) ? 8 : 1;
|
||||
}
|
||||
if (m & FL_ACCUM) {
|
||||
list[n++] = GLX_ACCUM_GREEN_SIZE;
|
||||
list[n++] = 1;
|
||||
if (m & FL_ALPHA) {
|
||||
list[n++] = GLX_ACCUM_ALPHA_SIZE;
|
||||
list[n++] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m & FL_DOUBLE) {
|
||||
list[n++] = GLX_DOUBLEBUFFER;
|
||||
}
|
||||
if (m & FL_DEPTH) {
|
||||
list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
|
||||
}
|
||||
if (m & FL_STENCIL) {
|
||||
list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
|
||||
}
|
||||
if (m & FL_STEREO) {
|
||||
list[n++] = GLX_STEREO;
|
||||
}
|
||||
# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
if (m & FL_MULTISAMPLE) {
|
||||
list[n++] = GLX_SAMPLES_SGIS;
|
||||
list[n++] = 4; // value Glut uses
|
||||
}
|
||||
# endif
|
||||
list[n] = 0;
|
||||
blist = list;
|
||||
}
|
||||
|
||||
fl_open_display();
|
||||
XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
|
||||
if (!visp) {
|
||||
# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE,0);
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
static GLContext cached_context;
|
||||
static Fl_Window* cached_window;
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
extern void gl_texture_reset();
|
||||
|
||||
Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp)
|
||||
{
|
||||
Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
|
||||
if (g) return g;
|
||||
NSOpenGLPixelFormat* fmt = Fl_Cocoa_Screen_Driver::mode_to_NSOpenGLPixelFormat(m, alistp);
|
||||
if (!fmt) return 0;
|
||||
|
||||
#elif defined(WIN32)
|
||||
g = new Fl_Gl_Choice(m, alistp, first);
|
||||
first = g;
|
||||
g->pixelformat = fmt;
|
||||
return g;
|
||||
}
|
||||
|
||||
GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
|
||||
GLContext context, shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
// resets the pile of string textures used to draw strings
|
||||
// necessary before the first context is created
|
||||
if (!shared_ctx) gl_texture_reset();
|
||||
context = Fl_Cocoa_Screen_Driver::create_GLcontext_for_window(g->pixelformat, shared_ctx, window);
|
||||
if (!context) return 0;
|
||||
add_context((GLContext)context);
|
||||
return (context);
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
|
||||
if (context != cached_context || w != cached_window) {
|
||||
cached_context = context;
|
||||
cached_window = w;
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_makecurrent(context);
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
|
||||
if (cached_context == context) {
|
||||
cached_context = 0;
|
||||
cached_window = 0;
|
||||
Fl_Cocoa_Screen_Driver::GL_cleardrawable();
|
||||
}
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_release(context);
|
||||
del_context(context);
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
#ifdef FL_CFG_GFX_GDI
|
||||
# include <FL/x.H>
|
||||
#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
|
||||
extern void fl_save_dc(HWND, HDC);
|
||||
|
||||
Fl_Gl_Choice *Fl_WinAPI_Gl_Window_Driver::find(int m, const int *alistp)
|
||||
{
|
||||
Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
|
||||
if (g) return g;
|
||||
|
||||
// Replacement for ChoosePixelFormat() that finds one with an overlay
|
||||
// if possible:
|
||||
HDC gc = (HDC)fl_graphics_driver->gc();
|
||||
|
@ -154,79 +167,19 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
|
|||
}
|
||||
//printf("Chosen pixel format is %d\n", pixelformat);
|
||||
if (!pixelformat) return 0;
|
||||
#else
|
||||
# error platform unsupported
|
||||
#endif
|
||||
|
||||
g = new Fl_Gl_Choice;
|
||||
g->mode = m;
|
||||
g->alist = alistp;
|
||||
g->next = first;
|
||||
|
||||
g = new Fl_Gl_Choice(m, alistp, first);
|
||||
first = g;
|
||||
|
||||
#if defined(USE_X11)
|
||||
g->vis = visp;
|
||||
|
||||
if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
|
||||
visp->visualid == fl_visual->visualid &&
|
||||
!fl_getenv("MESA_PRIVATE_CMAP"))
|
||||
g->colormap = fl_colormap;
|
||||
else
|
||||
g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
|
||||
visp->visual, AllocNone);
|
||||
# elif defined(WIN32)
|
||||
|
||||
g->pixelformat = pixelformat;
|
||||
g->pfd = chosen_pfd;
|
||||
# elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management
|
||||
g->pixelformat = fmt;
|
||||
# else
|
||||
# error unsupported platform
|
||||
# endif
|
||||
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
static GLContext *context_list = 0;
|
||||
static int nContext = 0, NContext = 0;
|
||||
|
||||
static void add_context(GLContext ctx) {
|
||||
if (!ctx) return;
|
||||
if (nContext==NContext) {
|
||||
if (!NContext) NContext = 8;
|
||||
NContext *= 2;
|
||||
context_list = (GLContext*)realloc(
|
||||
context_list, NContext*sizeof(GLContext));
|
||||
}
|
||||
context_list[nContext++] = ctx;
|
||||
}
|
||||
|
||||
static void del_context(GLContext ctx) {
|
||||
int i;
|
||||
for (i=0; i<nContext; i++) {
|
||||
if (context_list[i]==ctx) {
|
||||
memmove(context_list+i, context_list+i+1,
|
||||
(nContext-i-1) * sizeof(GLContext));
|
||||
context_list[--nContext] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nContext) gl_remove_displaylist_fonts();
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
||||
GLContext fl_create_gl_context(XVisualInfo* vis) {
|
||||
GLContext shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1);
|
||||
if (context)
|
||||
add_context(context);
|
||||
return context;
|
||||
}
|
||||
|
||||
#elif defined(WIN32)
|
||||
|
||||
GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
|
||||
GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer)
|
||||
{
|
||||
Fl_X* i = Fl_X::i(window);
|
||||
HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc;
|
||||
if (!hdc) {
|
||||
|
@ -237,82 +190,153 @@ GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int lay
|
|||
if (fl_palette) SelectPalette(hdc, fl_palette, FALSE);
|
||||
# endif
|
||||
}
|
||||
GLContext context =
|
||||
layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
|
||||
GLContext context = layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
|
||||
if (context) {
|
||||
if (context_list && nContext)
|
||||
if (context_list && nContext)
|
||||
wglShareLists(context_list[0], context);
|
||||
add_context(context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
# elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
|
||||
GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
|
||||
GLContext context, shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
// resets the pile of string textures used to draw strings
|
||||
// necessary before the first context is created
|
||||
if (!shared_ctx) gl_texture_reset();
|
||||
context = Fl_Cocoa_Screen_Driver::create_GLcontext_for_window(g->pixelformat, shared_ctx, window);
|
||||
if (!context) return 0;
|
||||
add_context((GLContext)context);
|
||||
return (context);
|
||||
}
|
||||
# else
|
||||
# error unsupported platform
|
||||
# endif
|
||||
|
||||
static GLContext cached_context;
|
||||
static Fl_Window* cached_window;
|
||||
|
||||
void fl_set_gl_context(Fl_Window* w, GLContext context) {
|
||||
void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
|
||||
if (context != cached_context || w != cached_window) {
|
||||
cached_context = context;
|
||||
cached_window = w;
|
||||
# if defined(USE_X11)
|
||||
glXMakeCurrent(fl_display, fl_xid(w), context);
|
||||
# elif defined(WIN32)
|
||||
wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context);
|
||||
# elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_makecurrent(context);
|
||||
# else
|
||||
# error unsupported platform
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
void fl_no_gl_context() {
|
||||
cached_context = 0;
|
||||
cached_window = 0;
|
||||
# if defined(USE_X11)
|
||||
glXMakeCurrent(fl_display, 0, 0);
|
||||
# elif defined(WIN32)
|
||||
wglMakeCurrent(0, 0);
|
||||
# elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
Fl_Cocoa_Screen_Driver::GL_cleardrawable();
|
||||
# else
|
||||
# error unsupported platform
|
||||
# endif
|
||||
}
|
||||
|
||||
void fl_delete_gl_context(GLContext context) {
|
||||
if (cached_context == context) fl_no_gl_context();
|
||||
# if defined(USE_X11)
|
||||
glXDestroyContext(fl_display, context);
|
||||
# elif defined(WIN32)
|
||||
void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) {
|
||||
if (cached_context == context) {
|
||||
cached_context = 0;
|
||||
cached_window = 0;
|
||||
wglMakeCurrent(0, 0);
|
||||
}
|
||||
wglDeleteContext(context);
|
||||
# elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_release(context);
|
||||
# else
|
||||
# error unsupported platform
|
||||
# endif
|
||||
del_context(context);
|
||||
}
|
||||
|
||||
#endif // HAVE_GL
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
#ifdef FL_CFG_GFX_XLIB
|
||||
# include <FL/x.H>
|
||||
|
||||
Fl_Gl_Choice *Fl_X11_Gl_Window_Driver::find(int m, const int *alistp)
|
||||
{
|
||||
Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
|
||||
if (g) return g;
|
||||
|
||||
const int *blist;
|
||||
int list[32];
|
||||
|
||||
if (alistp)
|
||||
blist = alistp;
|
||||
else {
|
||||
int n = 0;
|
||||
if (m & FL_INDEX) {
|
||||
list[n++] = GLX_BUFFER_SIZE;
|
||||
list[n++] = 8; // glut tries many sizes, but this should work...
|
||||
} else {
|
||||
list[n++] = GLX_RGBA;
|
||||
list[n++] = GLX_GREEN_SIZE;
|
||||
list[n++] = (m & FL_RGB8) ? 8 : 1;
|
||||
if (m & FL_ALPHA) {
|
||||
list[n++] = GLX_ALPHA_SIZE;
|
||||
list[n++] = (m & FL_RGB8) ? 8 : 1;
|
||||
}
|
||||
if (m & FL_ACCUM) {
|
||||
list[n++] = GLX_ACCUM_GREEN_SIZE;
|
||||
list[n++] = 1;
|
||||
if (m & FL_ALPHA) {
|
||||
list[n++] = GLX_ACCUM_ALPHA_SIZE;
|
||||
list[n++] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m & FL_DOUBLE) {
|
||||
list[n++] = GLX_DOUBLEBUFFER;
|
||||
}
|
||||
if (m & FL_DEPTH) {
|
||||
list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
|
||||
}
|
||||
if (m & FL_STENCIL) {
|
||||
list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
|
||||
}
|
||||
if (m & FL_STEREO) {
|
||||
list[n++] = GLX_STEREO;
|
||||
}
|
||||
# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
if (m & FL_MULTISAMPLE) {
|
||||
list[n++] = GLX_SAMPLES_SGIS;
|
||||
list[n++] = 4; // value Glut uses
|
||||
}
|
||||
# endif
|
||||
list[n] = 0;
|
||||
blist = list;
|
||||
}
|
||||
|
||||
fl_open_display();
|
||||
XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
|
||||
if (!visp) {
|
||||
# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE,0);
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
g = new Fl_Gl_Choice(m, alistp, first);
|
||||
first = g;
|
||||
|
||||
g->vis = visp;
|
||||
|
||||
if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
|
||||
visp->visualid == fl_visual->visualid &&
|
||||
!fl_getenv("MESA_PRIVATE_CMAP"))
|
||||
g->colormap = fl_colormap;
|
||||
else
|
||||
g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
|
||||
visp->visual, AllocNone);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
GLContext Fl_X11_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
|
||||
return create_gl_context(g->vis);
|
||||
}
|
||||
|
||||
GLContext Fl_X11_Gl_Window_Driver::create_gl_context(XVisualInfo *vis) {
|
||||
GLContext shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1);
|
||||
if (context)
|
||||
add_context(context);
|
||||
return context;
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
|
||||
if (context != cached_context || w != cached_window) {
|
||||
cached_context = context;
|
||||
cached_window = w;
|
||||
glXMakeCurrent(fl_display, fl_xid(w), context);
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::delete_gl_context(GLContext context) {
|
||||
if (cached_context == context) {
|
||||
cached_context = 0;
|
||||
cached_window = 0;
|
||||
glXMakeCurrent(fl_display, 0, 0);
|
||||
}
|
||||
glXDestroyContext(fl_display, context);
|
||||
del_context(context);
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
#endif // HAVE_GL
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// OpenGL overlay code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2016 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
|
@ -16,30 +16,58 @@
|
|||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <config.h>
|
||||
#include "config_lib.h"
|
||||
#if HAVE_GL
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/x.H>
|
||||
#include <FL/gl.h>
|
||||
#include "Fl_Gl_Choice.H"
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
#include <FL/Fl_Gl_Window_Driver.H>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(WIN32) // PORTME: platform OpenGL management
|
||||
#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: implement OpenGL hardware overlays if they are availbale in a compatible way. This is rarely needed."
|
||||
#else
|
||||
#endif
|
||||
/**
|
||||
Returns true if the hardware overlay is possible. If this is false,
|
||||
FLTK will try to simulate the overlay, with significant loss of update
|
||||
speed. Calling this will cause FLTK to open the display.
|
||||
*/
|
||||
int Fl_Gl_Window::can_do_overlay() {
|
||||
return pGlWindowDriver->can_do_overlay();
|
||||
}
|
||||
|
||||
#if !HAVE_GL_OVERLAY
|
||||
void Fl_Gl_Window_Driver::make_overlay(void *&o) {
|
||||
o = pWindow;
|
||||
}
|
||||
|
||||
int Fl_Gl_Window::can_do_overlay() {return 0;}
|
||||
/**
|
||||
Causes draw_overlay() to be called at a later time.
|
||||
Initially the overlay is clear. If you want the window to display
|
||||
something in the overlay when it first appears, you must call this
|
||||
immediately after you show() your window.
|
||||
*/
|
||||
void Fl_Gl_Window::redraw_overlay() {
|
||||
if (!shown()) return;
|
||||
pGlWindowDriver->make_overlay(overlay);
|
||||
pGlWindowDriver->redraw_overlay();
|
||||
}
|
||||
|
||||
void Fl_Gl_Window::make_overlay() {overlay = this;}
|
||||
/**
|
||||
Selects the OpenGL context for the widget's overlay.
|
||||
This method is called automatically prior to the
|
||||
draw_overlay() method being called and can also be used to
|
||||
implement feedback and/or selection within the handle()
|
||||
method.
|
||||
*/
|
||||
void Fl_Gl_Window::make_overlay_current() {
|
||||
pGlWindowDriver->make_overlay(overlay);
|
||||
pGlWindowDriver->make_overlay_current();
|
||||
}
|
||||
|
||||
/** Hides the window if it is not this window, does nothing in WIN32. */
|
||||
void Fl_Gl_Window::hide_overlay() {
|
||||
pGlWindowDriver->hide_overlay();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Methods on Fl_Gl_Window that create an overlay window. Because
|
||||
// many programs don't need the overlay, this is separated into this
|
||||
|
@ -56,10 +84,44 @@ void Fl_Gl_Window::make_overlay() {overlay = this;}
|
|||
// "faked" by drawing into the main layers. This is indicated by
|
||||
// setting overlay == this.
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::make_overlay_current() {
|
||||
// this is not very useful, but unfortunately, Apple decided
|
||||
// that front buffer drawing can no longer (OS X 10.4) be supported on their platforms.
|
||||
pWindow->make_current();
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::redraw_overlay() {
|
||||
pWindow->redraw();
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_XLIB
|
||||
#include <FL/x.H>
|
||||
////////////////////////////////////////////////////////////////
|
||||
// X version
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::make_overlay_current() {
|
||||
#if HAVE_GL_OVERLAY
|
||||
if (overlay() != pWindow) {
|
||||
((Fl_Gl_Window*)overlay())->make_current();
|
||||
} else
|
||||
#endif
|
||||
glDrawBuffer(GL_FRONT);
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::redraw_overlay() {
|
||||
if (overlay() != pWindow)
|
||||
((Fl_Gl_Window*)overlay())->redraw();
|
||||
else
|
||||
pWindow->damage(FL_DAMAGE_OVERLAY);
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
|
||||
extern XVisualInfo *fl_find_overlay_visual();
|
||||
extern XVisualInfo *fl_overlay_visual;
|
||||
extern Colormap fl_overlay_colormap;
|
||||
|
@ -100,7 +162,7 @@ void _Fl_Gl_Overlay::draw() {
|
|||
uchar save_valid = w->valid();
|
||||
w->valid(valid());
|
||||
fl_overlay = 1;
|
||||
w->draw_overlay();
|
||||
w->gl_driver()->draw_overlay();
|
||||
fl_overlay = 0;
|
||||
valid(w->valid());
|
||||
w->valid(save_valid);
|
||||
|
@ -115,42 +177,79 @@ void _Fl_Gl_Overlay::show() {
|
|||
Fl_Window *w = window();
|
||||
for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
|
||||
XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
|
||||
context(fl_create_gl_context(fl_overlay_visual), 1);
|
||||
context(Fl_X11_Gl_Window_Driver::create_gl_context(fl_overlay_visual), 1);
|
||||
valid(0);
|
||||
}
|
||||
Fl_Gl_Window::show();
|
||||
}
|
||||
|
||||
int Fl_Gl_Window::can_do_overlay() {
|
||||
void Fl_X11_Gl_Window_Driver::hide_overlay() {
|
||||
if (overlay() && overlay() != pWindow) ((Fl_Gl_Window*)overlay())->hide();
|
||||
}
|
||||
|
||||
int Fl_X11_Gl_Window_Driver::can_do_overlay() {
|
||||
return fl_find_overlay_visual() != 0;
|
||||
}
|
||||
|
||||
void Fl_Gl_Window::make_overlay() {
|
||||
if (overlay) return;
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::make_overlay(void *¤t) {
|
||||
if (current) return;
|
||||
if (can_do_overlay()) {
|
||||
_Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
|
||||
overlay = o;
|
||||
add(*o);
|
||||
_Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0, 0, pWindow->w(), pWindow->h());
|
||||
current = o;
|
||||
pWindow->add(*o);
|
||||
o->show();
|
||||
} else {
|
||||
overlay = this; // fake the overlay
|
||||
current = pWindow; // fake the overlay
|
||||
}
|
||||
}
|
||||
#endif // HAVE_GL_OVERLAY
|
||||
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_GDI
|
||||
#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
|
||||
|
||||
#else
|
||||
////////////////////////////////////////////////////////////////
|
||||
// WIN32 version:
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::hide_overlay(void *& overlay) {
|
||||
#if HAVE_GL_OVERLAY
|
||||
if (overlay && overlay != pWindow) {
|
||||
delete_gl_context((GLContext)overlay);
|
||||
overlay = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::make_overlay_current() {
|
||||
#if HAVE_GL_OVERLAY
|
||||
if (overlay != this) {
|
||||
pGlWindowDriver->set_gl_context(this, (GLContext)overlay);
|
||||
// if (fl_overlay_depth)
|
||||
// wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
|
||||
} else
|
||||
#endif
|
||||
glDrawBuffer(GL_FRONT);
|
||||
}
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::redraw_overlay() {
|
||||
pWindow->damage(FL_DAMAGE_OVERLAY);
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
|
||||
//static COLORREF *palette;
|
||||
extern int fl_overlay_depth;
|
||||
|
||||
void Fl_Gl_Window::make_overlay() {
|
||||
void Fl_WinAPI_Gl_Window_Driver::make_overlay(void*&overlay) {
|
||||
if (overlay) return;
|
||||
|
||||
GLContext context = fl_create_gl_context(this, g, 1);
|
||||
if (!context) {overlay = this; return;} // fake the overlay
|
||||
GLContext context = create_gl_context(pWindow, g, 1);
|
||||
if (!context) {overlay = pWindow; return;} // fake the overlay
|
||||
|
||||
HDC hdc = Fl_WinAPI_Window_Driver::driver(this)->private_dc;
|
||||
HDC hdc = Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc;
|
||||
overlay = context;
|
||||
LAYERPLANEDESCRIPTOR pfd;
|
||||
wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd);
|
||||
|
@ -179,68 +278,18 @@ void Fl_Gl_Window::make_overlay() {
|
|||
return;
|
||||
}
|
||||
|
||||
int Fl_Gl_Window::can_do_overlay() {
|
||||
if (!g) {
|
||||
g = Fl_Gl_Choice::find(mode_,alist);
|
||||
if (!g) return 0;
|
||||
int Fl_WinAPI_Gl_Window_Driver::can_do_overlay() {
|
||||
if (!g()) {
|
||||
g( find(mode(), alist()) );
|
||||
if (!g()) return 0;
|
||||
}
|
||||
return (g->pfd.bReserved & 15) != 0;
|
||||
return (g()->pfd.bReserved & 15) != 0;
|
||||
}
|
||||
#endif // HAVE_GL_OVERLAY
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
#endif
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
#endif
|
||||
|
||||
void Fl_Gl_Window::redraw_overlay() {
|
||||
if (!shown()) return;
|
||||
make_overlay();
|
||||
#ifdef __APPLE__ // PORTME: platform OpenGL management
|
||||
redraw();
|
||||
#else
|
||||
#ifndef WIN32
|
||||
if (overlay != this)
|
||||
((Fl_Gl_Window*)overlay)->redraw();
|
||||
else
|
||||
#endif
|
||||
damage(FL_DAMAGE_OVERLAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl_Gl_Window::make_overlay_current() {
|
||||
make_overlay();
|
||||
#ifdef __APPLE__ // PORTME: platform OpenGL management
|
||||
// this is not very useful, but unfortunately, Apple decided
|
||||
// that front buffer drawing can no longer (OS X 10.4) be
|
||||
// supported on their platforms.
|
||||
make_current();
|
||||
#else
|
||||
#if HAVE_GL_OVERLAY
|
||||
if (overlay != this) {
|
||||
#ifdef WIN32
|
||||
fl_set_gl_context(this, (GLContext)overlay);
|
||||
// if (fl_overlay_depth)
|
||||
// wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
|
||||
#else
|
||||
((Fl_Gl_Window*)overlay)->make_current();
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
glDrawBuffer(GL_FRONT);
|
||||
#endif
|
||||
}
|
||||
/** Hides the window if it is not this window, does nothing in WIN32. */
|
||||
void Fl_Gl_Window::hide_overlay() {
|
||||
#if HAVE_GL_OVERLAY
|
||||
#ifdef WIN32
|
||||
// nothing needs to be done? Or should it be erased?
|
||||
#else
|
||||
if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // HAVE_GL
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
|
|
@ -16,39 +16,29 @@
|
|||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include "flstring.h"
|
||||
#include "config_lib.h"
|
||||
#if HAVE_GL
|
||||
|
||||
extern int fl_gl_load_plugin;
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
#include <FL/Fl_Window_Driver.H>
|
||||
#include <FL/x.H>
|
||||
#include "Fl_Gl_Choice.H"
|
||||
#ifdef __APPLE__ // PORTME: platform OpenGL management
|
||||
#include <FL/gl.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
#elif defined(WIN32)
|
||||
#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
|
||||
#endif
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
#include <FL/Fl_Device.H>
|
||||
#include <FL/Fl_Gl_Window_Driver.H>
|
||||
#include <stdlib.h>
|
||||
#include <FL/fl_utf8.h>
|
||||
# if HAVE_DLFCN_H
|
||||
# include <dlfcn.h>
|
||||
# endif // HAVE_DLFCN_H
|
||||
# ifdef HAVE_GLXGETPROCADDRESSARB
|
||||
# define GLX_GLXEXT_LEGACY
|
||||
# include <GL/glx.h>
|
||||
# endif // HAVE_GLXGETPROCADDRESSARB
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_OPENGL
|
||||
#include "drivers/OpenGL/Fl_OpenGL_Display_Device.H"
|
||||
|
||||
#if defined(WIN32) || defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: implement the creation and destruction of OpenGL surfaces"
|
||||
#else
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// The symbol SWAP_TYPE defines what is in the back buffer after doing
|
||||
|
@ -76,18 +66,16 @@ static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable
|
|||
|
||||
/** Returns non-zero if the hardware supports the given or current OpenGL mode. */
|
||||
int Fl_Gl_Window::can_do(int a, const int *b) {
|
||||
return Fl_Gl_Choice::find(a,b) != 0;
|
||||
return Fl_Gl_Window_Driver::global()->find(a,b) != 0;
|
||||
}
|
||||
|
||||
void Fl_Gl_Window::show() {
|
||||
#if defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
int need_redraw = 0;
|
||||
#endif
|
||||
if (!shown()) {
|
||||
if (!g) {
|
||||
g = Fl_Gl_Choice::find(mode_,alist);
|
||||
g = pGlWindowDriver->find(mode_,alist);
|
||||
if (!g && (mode_ & FL_DOUBLE) == FL_SINGLE) {
|
||||
g = Fl_Gl_Choice::find(mode_ | FL_DOUBLE,alist);
|
||||
g = pGlWindowDriver->find(mode_ | FL_DOUBLE,alist);
|
||||
if (g) mode_ |= FL_FAKE_SINGLE;
|
||||
}
|
||||
|
||||
|
@ -96,30 +84,12 @@ void Fl_Gl_Window::show() {
|
|||
return;
|
||||
}
|
||||
}
|
||||
#if !defined(WIN32) && !defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
Fl_X::make_xid(this, g->vis, g->colormap);
|
||||
if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
|
||||
#elif defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
if( ! parent() ) need_redraw=1;
|
||||
#endif
|
||||
pGlWindowDriver->before_show(need_redraw);
|
||||
}
|
||||
Fl_Window::show();
|
||||
|
||||
#ifdef __APPLE__ // PORTME: platform OpenGL management
|
||||
set_visible();
|
||||
if(need_redraw) redraw();//necessary only after creation of a top-level GL window
|
||||
#endif /* __APPLE__ */ // PORTME: platform OpenGL management
|
||||
pGlWindowDriver->after_show(need_redraw);
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
|
||||
int Fl_Gl_Window::pixels_per_unit()
|
||||
{
|
||||
return (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(this) &&
|
||||
Fl_Cocoa_Window_Driver::driver(this)->mapped_to_retina()) ? 2 : 1;
|
||||
}
|
||||
|
||||
#endif // __APPLE__ // PORTME: platform OpenGL management
|
||||
|
||||
/**
|
||||
The invalidate() method turns off valid() and is
|
||||
|
@ -128,62 +98,12 @@ int Fl_Gl_Window::pixels_per_unit()
|
|||
void Fl_Gl_Window::invalidate() {
|
||||
valid(0);
|
||||
context_valid(0);
|
||||
#ifndef WIN32
|
||||
if (overlay) {
|
||||
((Fl_Gl_Window*)overlay)->valid(0);
|
||||
((Fl_Gl_Window*)overlay)->context_valid(0);
|
||||
}
|
||||
#endif
|
||||
pGlWindowDriver->invalidate();
|
||||
}
|
||||
|
||||
int Fl_Gl_Window::mode(int m, const int *a) {
|
||||
if (m == mode_ && a == alist) return 0;
|
||||
#ifndef __APPLE__ // PORTME: platform OpenGL management
|
||||
int oldmode = mode_;
|
||||
#endif
|
||||
#if defined(__APPLE__) || defined(USE_X11) // PORTME: platform OpenGL management
|
||||
if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
|
||||
// the FL_DOUBLE flag must be set in the mode_ member variable
|
||||
const int *aa = a;
|
||||
while (*aa) {
|
||||
if (*(aa++) ==
|
||||
# if defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
kCGLPFADoubleBuffer
|
||||
# else
|
||||
GLX_DOUBLEBUFFER
|
||||
# endif
|
||||
) { m |= FL_DOUBLE; break; }
|
||||
}
|
||||
}
|
||||
#endif // !__APPLE__ // PORTME: platform OpenGL management
|
||||
#if !defined(WIN32) && !defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
Fl_Gl_Choice* oldg = g;
|
||||
#endif // !WIN32 && !__APPLE__ // PORTME: platform OpenGL management
|
||||
context(0);
|
||||
mode_ = m; alist = a;
|
||||
if (shown()) {
|
||||
g = Fl_Gl_Choice::find(m, a);
|
||||
|
||||
#if defined(USE_X11)
|
||||
// under X, if the visual changes we must make a new X window (yuck!):
|
||||
if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) {
|
||||
hide();
|
||||
show();
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
if (!g || (oldmode^m)&(FL_DOUBLE|FL_STEREO)) {
|
||||
hide();
|
||||
show();
|
||||
}
|
||||
#elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management
|
||||
redraw();
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
} else {
|
||||
g = 0;
|
||||
}
|
||||
return 1;
|
||||
return pGlWindowDriver->mode_(m, a);
|
||||
}
|
||||
|
||||
#define NON_LOCAL_CONTEXT 0x80000000
|
||||
|
@ -198,30 +118,15 @@ int Fl_Gl_Window::mode(int m, const int *a) {
|
|||
void Fl_Gl_Window::make_current() {
|
||||
// puts("Fl_Gl_Window::make_current()");
|
||||
// printf("make_current: context_=%p\n", context_);
|
||||
#if defined(__APPLE__) // PORTME: platform OpenGL management
|
||||
// detect if the window was moved between low and high resolution displays
|
||||
Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(this);
|
||||
if (d->changed_resolution()){
|
||||
d->changed_resolution(false);
|
||||
invalidate();
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_update(context_);
|
||||
}
|
||||
#endif
|
||||
pGlWindowDriver->make_current_before();
|
||||
if (!context_) {
|
||||
mode_ &= ~NON_LOCAL_CONTEXT;
|
||||
context_ = fl_create_gl_context(this, g);
|
||||
context_ = pGlWindowDriver->create_gl_context(this, g);
|
||||
valid(0);
|
||||
context_valid(0);
|
||||
}
|
||||
fl_set_gl_context(this, context_);
|
||||
|
||||
#if defined(WIN32) && USE_COLORMAP
|
||||
if (fl_palette) {
|
||||
fl_GetDC(fl_xid(this));
|
||||
SelectPalette((HDC)fl_graphics_driver->gc(), fl_palette, FALSE);
|
||||
RealizePalette((HDC)fl_graphics_driver->gc());
|
||||
}
|
||||
#endif // USE_COLORMAP
|
||||
pGlWindowDriver->set_gl_context(this, context_);
|
||||
pGlWindowDriver->make_current_after();
|
||||
if (mode_ & FL_FAKE_SINGLE) {
|
||||
glDrawBuffer(GL_FRONT);
|
||||
glReadBuffer(GL_FRONT);
|
||||
|
@ -254,91 +159,13 @@ void Fl_Gl_Window::ortho() {
|
|||
It is called automatically after the draw() method is called.
|
||||
*/
|
||||
void Fl_Gl_Window::swap_buffers() {
|
||||
#if defined(USE_X11)
|
||||
glXSwapBuffers(fl_display, fl_xid(this));
|
||||
#elif defined(WIN32)
|
||||
# if HAVE_GL_OVERLAY
|
||||
// Do not swap the overlay, to match GLX:
|
||||
BOOL ret = wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(this)->private_dc, WGL_SWAP_MAIN_PLANE);
|
||||
DWORD err = GetLastError();;
|
||||
# else
|
||||
SwapBuffers(Fl_WinAPI_Window_Driver::driver(this)->private_dc);
|
||||
# endif
|
||||
#elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management
|
||||
if(overlay != NULL) {
|
||||
// STR# 2944 [1]
|
||||
// Save matrixmode/proj/modelview/rasterpos before doing overlay.
|
||||
//
|
||||
int wo=pixel_w(), ho=pixel_h();
|
||||
GLint matrixmode;
|
||||
GLfloat pos[4];
|
||||
glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
|
||||
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); // save original glRasterPos
|
||||
glMatrixMode(GL_PROJECTION); // save proj/model matrices
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glScalef(2.0f/wo, 2.0f/ho, 1.0f);
|
||||
glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of Gl_Window
|
||||
glRasterPos2i(0,0); // set glRasterPos to bottom left corner
|
||||
{
|
||||
// Emulate overlay by doing copypixels
|
||||
glReadBuffer(GL_BACK);
|
||||
glDrawBuffer(GL_FRONT);
|
||||
glCopyPixels(0, 0, wo, ho, GL_COLOR); // copy GL_BACK to GL_FRONT
|
||||
}
|
||||
glPopMatrix(); // GL_MODELVIEW // restore model/proj matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(matrixmode);
|
||||
glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos
|
||||
}
|
||||
/* // nothing to do here under Cocoa because [NSOpenGLContext -flushBuffer] done later replaces it
|
||||
else
|
||||
aglSwapBuffers((AGLContext)context_);
|
||||
*/
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
pGlWindowDriver->swap_buffers();
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY && defined(WIN32)
|
||||
uchar fl_overlay; // changes how fl_color() works
|
||||
int fl_overlay_depth = 0;
|
||||
#endif
|
||||
|
||||
|
||||
void Fl_Gl_Window::flush() {
|
||||
if (!shown()) return;
|
||||
uchar save_valid = valid_f_ & 1;
|
||||
#if HAVE_GL_OVERLAY && defined(WIN32)
|
||||
uchar save_valid_f = valid_f_;
|
||||
#endif
|
||||
|
||||
#if HAVE_GL_OVERLAY && defined(WIN32)
|
||||
|
||||
// Draw into hardware overlay planes if they are damaged:
|
||||
if (overlay && overlay != this
|
||||
&& (damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid)) {
|
||||
fl_set_gl_context(this, (GLContext)overlay);
|
||||
if (fl_overlay_depth)
|
||||
wglRealizeLayerPalette(Fl_WinAPI_Window_Driver::driver(this)->private_dc, 1, TRUE);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
fl_overlay = 1;
|
||||
draw_overlay();
|
||||
fl_overlay = 0;
|
||||
valid_f_ = save_valid_f;
|
||||
wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(this)->private_dc, WGL_SWAP_OVERLAY1);
|
||||
// if only the overlay was damaged we are done, leave main layer alone:
|
||||
if (damage() == FL_DAMAGE_OVERLAY) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pGlWindowDriver->flush_begin(valid_f_) ) return;
|
||||
make_current();
|
||||
|
||||
if (mode_ & FL_DOUBLE) {
|
||||
|
@ -346,11 +173,7 @@ void Fl_Gl_Window::flush() {
|
|||
glDrawBuffer(GL_BACK);
|
||||
|
||||
if (!SWAP_TYPE) {
|
||||
#if defined (__APPLE_QUARTZ__) || defined (USE_X11) // PORTME: platform OpenGL management
|
||||
SWAP_TYPE = COPY;
|
||||
#else
|
||||
SWAP_TYPE = UNDEFINED;
|
||||
#endif
|
||||
SWAP_TYPE = pGlWindowDriver->swap_type();
|
||||
const char* c = fl_getenv("GL_SWAP_TYPE");
|
||||
if (c) {
|
||||
if (!strcmp(c,"COPY")) SWAP_TYPE = COPY;
|
||||
|
@ -390,8 +213,8 @@ void Fl_Gl_Window::flush() {
|
|||
static GLContext ortho_context = 0;
|
||||
static Fl_Gl_Window* ortho_window = 0;
|
||||
int orthoinit = !ortho_context;
|
||||
if (orthoinit) ortho_context = fl_create_gl_context(this, g);
|
||||
fl_set_gl_context(this, ortho_context);
|
||||
if (orthoinit) ortho_context = pGlWindowDriver->create_gl_context(this, g);
|
||||
pGlWindowDriver->set_gl_context(this, ortho_context);
|
||||
if (orthoinit || !save_valid || ortho_window != this) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
@ -413,10 +236,7 @@ void Fl_Gl_Window::flush() {
|
|||
}
|
||||
|
||||
}
|
||||
#ifdef __APPLE__ // PORTME: platform OpenGL management
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_flushbuffer(context_);
|
||||
#endif
|
||||
|
||||
pGlWindowDriver->flush_context();
|
||||
if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
|
||||
glDrawBuffer(GL_FRONT);
|
||||
draw_overlay();
|
||||
|
@ -442,19 +262,7 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
|
|||
|
||||
int is_a_resize = (W != Fl_Widget::w() || H != Fl_Widget::h());
|
||||
if (is_a_resize) valid(0);
|
||||
|
||||
#ifdef __APPLE__ // PORTME: platform OpenGL management
|
||||
Fl_X *flx = Fl_X::i(this);
|
||||
Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(this);
|
||||
if (flx && d->in_windowDidResize()) Fl_Cocoa_Screen_Driver::GLcontext_update(context_);
|
||||
#endif
|
||||
|
||||
#if ! ( defined(__APPLE__) || defined(WIN32) ) // PORTME: platform OpenGL management
|
||||
if (is_a_resize && !resizable() && overlay && overlay != this) {
|
||||
((Fl_Gl_Window*)overlay)->resize(0,0,W,H);
|
||||
}
|
||||
#endif
|
||||
|
||||
pGlWindowDriver->resize(is_a_resize, W, H);
|
||||
Fl_Window::resize(X,Y,W,H);
|
||||
}
|
||||
|
||||
|
@ -470,7 +278,7 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
|
|||
or the next time context(x) is called.
|
||||
*/
|
||||
void Fl_Gl_Window::context(void* v, int destroy_flag) {
|
||||
if (context_ && !(mode_&NON_LOCAL_CONTEXT)) fl_delete_gl_context(context_);
|
||||
if (context_ && !(mode_&NON_LOCAL_CONTEXT)) pGlWindowDriver->delete_gl_context(context_);
|
||||
context_ = (GLContext)v;
|
||||
if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT;
|
||||
else mode_ |= NON_LOCAL_CONTEXT;
|
||||
|
@ -481,12 +289,7 @@ void Fl_Gl_Window::context(void* v, int destroy_flag) {
|
|||
*/
|
||||
void Fl_Gl_Window::hide() {
|
||||
context(0);
|
||||
#if HAVE_GL_OVERLAY && defined(WIN32)
|
||||
if (overlay && overlay != this) {
|
||||
fl_delete_gl_context((GLContext)overlay);
|
||||
overlay = 0;
|
||||
}
|
||||
#endif
|
||||
pGlWindowDriver->hide_overlay(overlay);
|
||||
Fl_Window::hide();
|
||||
}
|
||||
|
||||
|
@ -497,9 +300,11 @@ void Fl_Gl_Window::hide() {
|
|||
Fl_Gl_Window::~Fl_Gl_Window() {
|
||||
hide();
|
||||
// delete overlay; this is done by ~Fl_Group
|
||||
delete pGlWindowDriver;
|
||||
}
|
||||
|
||||
void Fl_Gl_Window::init() {
|
||||
pGlWindowDriver = Fl_Gl_Window_Driver::newGlWindowDriver(this);
|
||||
end(); // we probably don't want any children
|
||||
box(FL_NO_BOX);
|
||||
|
||||
|
@ -535,9 +340,9 @@ void Fl_Gl_Window::init() {
|
|||
*/
|
||||
void Fl_Gl_Window::draw_overlay() {}
|
||||
|
||||
#endif
|
||||
#endif // HAVE_GL
|
||||
|
||||
/**
|
||||
/** Draws the Fl_Gl_Window.
|
||||
You \e \b must subclass Fl_Gl_Window and provide an implementation for
|
||||
draw(). You may also provide an implementation of draw_overlay()
|
||||
if you want to draw into the overlay planes. You can avoid
|
||||
|
@ -590,6 +395,314 @@ int Fl_Gl_Window::gl_plugin_linkage() {
|
|||
return fl_gl_load_plugin;
|
||||
}
|
||||
|
||||
/** The number of pixels per FLTK unit of length for the window.
|
||||
Returns 1, except for a window mapped to
|
||||
an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true,
|
||||
when it returns 2. This method dynamically adjusts its value when the window
|
||||
is moved to/from a retina display. This method is useful, e.g., to convert,
|
||||
in a window's handle() method, the FLTK units returned by Fl::event_x() and
|
||||
Fl::event_y() to the pixel units used by the OpenGL source code.
|
||||
\version 1.3.4
|
||||
*/
|
||||
int Fl_Gl_Window::pixels_per_unit() {
|
||||
return pGlWindowDriver->pixels_per_unit();
|
||||
}
|
||||
|
||||
// creates a unique, dummy Fl_Gl_Window_Driver object used when no Fl_Gl_Window is around
|
||||
Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::global() {
|
||||
static Fl_Gl_Window_Driver *gwd = newGlWindowDriver(NULL);
|
||||
return gwd;
|
||||
}
|
||||
|
||||
void Fl_Gl_Window_Driver::invalidate() {
|
||||
if (pWindow->overlay) {
|
||||
((Fl_Gl_Window*)pWindow->overlay)->valid(0);
|
||||
((Fl_Gl_Window*)pWindow->overlay)->context_valid(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char Fl_Gl_Window_Driver::swap_type() {return UNDEFINED;}
|
||||
|
||||
|
||||
void* Fl_Gl_Window_Driver::GetProcAddress(const char *procName) {
|
||||
#if (HAVE_DLSYM && HAVE_DLFCN_H)
|
||||
char symbol[1024];
|
||||
|
||||
snprintf(symbol, sizeof(symbol), "_%s", procName);
|
||||
|
||||
# ifdef RTLD_DEFAULT
|
||||
return dlsym(RTLD_DEFAULT, symbol);
|
||||
|
||||
# else // No RTLD_DEFAULT support, so open the current a.out symbols...
|
||||
static void *rtld_default = dlopen(0, RTLD_LAZY);
|
||||
|
||||
if (rtld_default) return dlsym(rtld_default, symbol);
|
||||
else return 0;
|
||||
|
||||
# endif // RTLD_DEFAULT
|
||||
|
||||
#elif defined(HAVE_GLXGETPROCADDRESSARB)
|
||||
return glXGetProcAddressARB((const GLubyte *)procName);
|
||||
|
||||
#else
|
||||
return 0;
|
||||
#endif // HAVE_DLSYM
|
||||
}
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
//#include <FL/gl.h>
|
||||
#include <FL/x.H>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
|
||||
Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
|
||||
{
|
||||
return new Fl_Cocoa_Gl_Window_Driver(w);
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::before_show(int& need_redraw) {
|
||||
if( ! pWindow->parent() ) need_redraw=1;
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::after_show(int need_redraw) {
|
||||
pWindow->set_visible();
|
||||
if(need_redraw) pWindow->redraw();//necessary only after creation of a top-level GL window
|
||||
}
|
||||
|
||||
int Fl_Cocoa_Gl_Window_Driver::pixels_per_unit()
|
||||
{
|
||||
return (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(pWindow) &&
|
||||
Fl_Cocoa_Window_Driver::driver(pWindow)->mapped_to_retina()) ? 2 : 1;
|
||||
}
|
||||
|
||||
int Fl_Cocoa_Gl_Window_Driver::mode_(int m, const int *a) {
|
||||
if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
|
||||
// the FL_DOUBLE flag must be set in the mode_ member variable
|
||||
const int *aa = a;
|
||||
while (*aa) {
|
||||
if (*(aa++) ==
|
||||
kCGLPFADoubleBuffer
|
||||
) { m |= FL_DOUBLE; break; }
|
||||
}
|
||||
}
|
||||
pWindow->context(0);
|
||||
mode( m); alist(a);
|
||||
if (pWindow->shown()) {
|
||||
g( find(m, a) );
|
||||
pWindow->redraw();
|
||||
} else {
|
||||
g(0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::make_current_before() {
|
||||
// detect if the window was moved between low and high resolution displays
|
||||
Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(pWindow);
|
||||
if (d->changed_resolution()){
|
||||
d->changed_resolution(false);
|
||||
invalidate();
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_update((GLContext)pWindow->context());
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::swap_buffers() {
|
||||
if (overlay() != NULL) {
|
||||
// STR# 2944 [1]
|
||||
// Save matrixmode/proj/modelview/rasterpos before doing overlay.
|
||||
//
|
||||
int wo = pWindow->pixel_w(), ho = pWindow->pixel_h();
|
||||
GLint matrixmode;
|
||||
GLfloat pos[4];
|
||||
glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
|
||||
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); // save original glRasterPos
|
||||
glMatrixMode(GL_PROJECTION); // save proj/model matrices
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glScalef(2.0f/wo, 2.0f/ho, 1.0f);
|
||||
glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of Gl_Window
|
||||
glRasterPos2i(0,0); // set glRasterPos to bottom left corner
|
||||
{
|
||||
// Emulate overlay by doing copypixels
|
||||
glReadBuffer(GL_BACK);
|
||||
glDrawBuffer(GL_FRONT);
|
||||
glCopyPixels(0, 0, wo, ho, GL_COLOR); // copy GL_BACK to GL_FRONT
|
||||
}
|
||||
glPopMatrix(); // GL_MODELVIEW // restore model/proj matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(matrixmode);
|
||||
glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos
|
||||
}
|
||||
/* // nothing to do here under Cocoa because [NSOpenGLContext -flushBuffer] done later replaces it
|
||||
else
|
||||
aglSwapBuffers((AGLContext)context_);
|
||||
*/
|
||||
}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int unused, int also) {
|
||||
Fl_X *flx = Fl_X::i(pWindow);
|
||||
Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(pWindow);
|
||||
if (flx && d->in_windowDidResize()) Fl_Cocoa_Screen_Driver::GLcontext_update((GLContext)pWindow->context());
|
||||
}
|
||||
|
||||
char Fl_Cocoa_Gl_Window_Driver::swap_type() {return COPY;}
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::flush_context() {
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_flushbuffer((GLContext)pWindow->context());
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_QUARTZ
|
||||
|
||||
#if defined(FL_CFG_GFX_GDI)
|
||||
#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
|
||||
#include <FL/x.H>
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
|
||||
Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
|
||||
{
|
||||
return new Fl_WinAPI_Gl_Window_Driver(w);
|
||||
}
|
||||
|
||||
int Fl_WinAPI_Gl_Window_Driver::mode_(int m, const int *a) {
|
||||
int oldmode = mode();
|
||||
pWindow->context(0);
|
||||
mode( m); alist(a);
|
||||
if (pWindow->shown()) {
|
||||
g( find(m, a) );
|
||||
if (!g() || (oldmode^m)&(FL_DOUBLE|FL_STEREO)) {
|
||||
pWindow->hide();
|
||||
pWindow->show();
|
||||
}
|
||||
} else {
|
||||
g(0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::make_current_after() {
|
||||
#if USE_COLORMAP
|
||||
if (fl_palette) {
|
||||
fl_GetDC(fl_xid(pWindow));
|
||||
SelectPalette((HDC)fl_graphics_driver->gc(), fl_palette, FALSE);
|
||||
RealizePalette((HDC)fl_graphics_driver->gc());
|
||||
}
|
||||
#endif // USE_COLORMAP
|
||||
}
|
||||
|
||||
//#define HAVE_GL_OVERLAY 1 //test only
|
||||
|
||||
void Fl_WinAPI_Gl_Window_Driver::swap_buffers() {
|
||||
# if HAVE_GL_OVERLAY
|
||||
// Do not swap the overlay, to match GLX:
|
||||
BOOL ret = wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, WGL_SWAP_MAIN_PLANE);
|
||||
DWORD err = GetLastError();
|
||||
# else
|
||||
SwapBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if HAVE_GL_OVERLAY
|
||||
uchar fl_overlay; // changes how fl_color() works
|
||||
int fl_overlay_depth = 0;
|
||||
#endif
|
||||
|
||||
int Fl_WinAPI_Gl_Window_Driver::flush_begin(char& valid_f_) {
|
||||
#if HAVE_GL_OVERLAY
|
||||
char save_valid_f = valid_f_;
|
||||
// Draw into hardware overlay planes if they are damaged:
|
||||
if (overlay() && overlay() != pWindow
|
||||
&& (pWindow->damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid_f & 1)) {
|
||||
set_gl_context(pWindow, (GLContext)overlay());
|
||||
if (fl_overlay_depth)
|
||||
wglRealizeLayerPalette(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, 1, TRUE);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
fl_overlay = 1;
|
||||
draw_overlay();
|
||||
fl_overlay = 0;
|
||||
valid_f_ = save_valid_f;
|
||||
wglSwapLayerBuffers(Fl_WinAPI_Window_Driver::driver(pWindow)->private_dc, WGL_SWAP_OVERLAY1);
|
||||
// if only the overlay was damaged we are done, leave main layer alone:
|
||||
if (pWindow->damage() == FL_DAMAGE_OVERLAY) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* Fl_WinAPI_Gl_Window_Driver::GetProcAddress(const char *procName) {
|
||||
return (void*)wglGetProcAddress((LPCSTR)procName);
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_GDI
|
||||
|
||||
|
||||
#if defined(FL_CFG_GFX_XLIB)
|
||||
#include <FL/x.H>
|
||||
|
||||
Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
|
||||
{
|
||||
return new Fl_X11_Gl_Window_Driver(w);
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::before_show(int& need_redraw) {
|
||||
Fl_X::make_xid(pWindow, g()->vis, g()->colormap);
|
||||
if (overlay() && overlay() != pWindow) ((Fl_Gl_Window*)overlay())->show();
|
||||
}
|
||||
|
||||
int Fl_X11_Gl_Window_Driver::mode_(int m, const int *a) {
|
||||
int oldmode = mode();
|
||||
if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
|
||||
// the FL_DOUBLE flag must be set in the mode_ member variable
|
||||
const int *aa = a;
|
||||
while (*aa) {
|
||||
if (*(aa++) ==
|
||||
GLX_DOUBLEBUFFER
|
||||
) { m |= FL_DOUBLE; break; }
|
||||
}
|
||||
}
|
||||
Fl_Gl_Choice* oldg = g();
|
||||
pWindow->context(0);
|
||||
mode(m); alist(a);
|
||||
if (pWindow->shown()) {
|
||||
g( find(m, a) );
|
||||
// under X, if the visual changes we must make a new X window (yuck!):
|
||||
if (!g() || g()->vis->visualid != oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) {
|
||||
pWindow->hide();
|
||||
pWindow->show();
|
||||
}
|
||||
} else {
|
||||
g(0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::swap_buffers() {
|
||||
glXSwapBuffers(fl_display, fl_xid(pWindow));
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
|
||||
if (is_a_resize && !pWindow->resizable() && overlay() && overlay() != pWindow) {
|
||||
((Fl_Gl_Window*)overlay())->resize(0,0,W,H);
|
||||
}
|
||||
}
|
||||
|
||||
char Fl_X11_Gl_Window_Driver::swap_type() {return COPY;}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::waitGL() {
|
||||
glXWaitGL();
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
# endif
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: please choose a core graphics library"
|
||||
#else /* X11 */
|
||||
#elif defined(USE_X11) /* X11 */
|
||||
# define FL_CFG_GFX_XLIB
|
||||
# ifdef HAVE_GL
|
||||
# define FL_CFG_GFX_OPENGL
|
||||
|
@ -46,7 +46,7 @@
|
|||
# define FL_CFG_PRN_WIN32
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: please choose a printer driver"
|
||||
#else /* X11 */
|
||||
#elif defined(USE_X11) /* X11 */
|
||||
# define FL_CFG_PRN_PS
|
||||
#endif
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
|||
# define FL_CFG_WIN_WIN32
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: please choose a window management library"
|
||||
#else /* X11 */
|
||||
#elif defined(USE_X11) /* X11 */
|
||||
# define FL_CFG_WIN_X11
|
||||
#endif
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
|||
# define FL_CFG_SYS_WIN32
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: please choose a system library"
|
||||
#else /* X11 */
|
||||
#elif defined(USE_X11) /* X11 */
|
||||
# define FL_CFG_SYS_POSIX
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
// Functions from <FL/gl.h>
|
||||
// See also Fl_Gl_Window and gl_start.cxx
|
||||
|
||||
#include "config_lib.h"
|
||||
#if defined(WIN32) || defined(__APPLE__) // PORTME: Fl_Graphics_Driver - platform opengl
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: implement OpenGL text rendering here"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// OpenGL context routines for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2016 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
|
@ -28,56 +28,31 @@
|
|||
// be erased when the buffers are swapped (when double buffer hardware
|
||||
// is being used)
|
||||
|
||||
#if defined(WIN32) // PORTME: platform opengl
|
||||
#elif defined(__APPLE__)
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: if possible, add OpenGL rendering in non-OpenGL contexts"
|
||||
#else
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
#include "config_lib.h"
|
||||
#if HAVE_GL
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/x.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/gl.h>
|
||||
#include "Fl_Gl_Choice.H"
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
#include <FL/Fl_Gl_Window_Driver.H>
|
||||
|
||||
static GLContext context;
|
||||
static int clip_state_number=-1;
|
||||
static int pw, ph;
|
||||
|
||||
#ifdef WIN32
|
||||
static Fl_Gl_Choice* gl_choice;
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
static Fl_Gl_Choice* gl_choice;
|
||||
#endif
|
||||
|
||||
/** Creates an OpenGL context */
|
||||
void gl_start() {
|
||||
if (!context) {
|
||||
#if defined(USE_X11)
|
||||
context = fl_create_gl_context(fl_visual);
|
||||
#elif defined(WIN32)
|
||||
if (!gl_choice) Fl::gl_visual(0);
|
||||
context = fl_create_gl_context(Fl_Window::current(), gl_choice);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
context = fl_create_gl_context(Fl_Window::current(), gl_choice);
|
||||
#else
|
||||
# error Unsupported platform
|
||||
#endif
|
||||
context = Fl_Gl_Window_Driver::global()->create_gl_context(Fl_Window::current(), gl_choice);
|
||||
}
|
||||
fl_set_gl_context(Fl_Window::current(), context);
|
||||
#ifdef __APPLE__
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_update(context); // supports window resizing
|
||||
#elif !defined(WIN32)
|
||||
glXWaitX();
|
||||
#endif
|
||||
Fl_Gl_Window_Driver::global()->set_gl_context(Fl_Window::current(), context);
|
||||
Fl_Gl_Window_Driver::global()->gl_start();
|
||||
if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
|
||||
pw = Fl_Window::current()->w();
|
||||
ph = Fl_Window::current()->h();
|
||||
|
@ -103,27 +78,46 @@ void gl_start() {
|
|||
/** Releases an OpenGL context */
|
||||
void gl_finish() {
|
||||
glFlush();
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
glXWaitGL();
|
||||
#endif
|
||||
Fl_Gl_Window_Driver::global()->waitGL();
|
||||
}
|
||||
|
||||
int Fl::gl_visual(int mode, int *alist) {
|
||||
Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist);
|
||||
if (!c) return 0;
|
||||
#if defined(USE_X11)
|
||||
void Fl_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) {
|
||||
gl_choice = c;
|
||||
}
|
||||
|
||||
#ifdef FL_CFG_GFX_QUARTZ
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
|
||||
void Fl_Cocoa_Gl_Window_Driver::gl_start() {
|
||||
Fl_Cocoa_Screen_Driver::GLcontext_update(context); // supports window resizing
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FL_CFG_GFX_XLIB
|
||||
#include <FL/x.H>
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) {
|
||||
Fl_Gl_Window_Driver::gl_visual(c);
|
||||
fl_visual = c->vis;
|
||||
fl_colormap = c->colormap;
|
||||
#elif defined(WIN32)
|
||||
gl_choice = c;
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
gl_choice = c;
|
||||
#else
|
||||
# error Unsupported platform
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl_X11_Gl_Window_Driver::gl_start() {
|
||||
glXWaitX();
|
||||
}
|
||||
|
||||
#endif // FL_CFG_GFX_XLIB
|
||||
|
||||
int Fl::gl_visual(int mode, int *alist) {
|
||||
Fl_Gl_Choice *c = Fl_Gl_Window_Driver::global()->find(mode,alist);
|
||||
if (!c) return 0;
|
||||
Fl_Gl_Window_Driver::global()->gl_visual(c);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HAVE_GL
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
|
|
@ -28,19 +28,10 @@
|
|||
|
||||
#include "flstring.h"
|
||||
#if HAVE_GL
|
||||
|
||||
# include <FL/Fl_Gl_Window_Driver.H>
|
||||
# include <FL/glut.H>
|
||||
# ifdef HAVE_GLXGETPROCADDRESSARB
|
||||
# define GLX_GLXEXT_LEGACY
|
||||
# include <GL/glx.h>
|
||||
# endif // HAVE_GLXGETPROCADDRESSARB
|
||||
# if HAVE_DLFCN_H
|
||||
# include <dlfcn.h>
|
||||
# endif // HAVE_DLFCN_H
|
||||
# define MAXWINDOWS 32
|
||||
# ifdef __APPLE__
|
||||
# include <FL/x.H>
|
||||
# endif
|
||||
|
||||
static Fl_Glut_Window *windows[MAXWINDOWS+1];
|
||||
|
||||
static void (*glut_idle_func)() = 0; // global glut idle function
|
||||
|
@ -440,33 +431,7 @@ int glutDeviceGet(GLenum type) {
|
|||
|
||||
// Get extension function address...
|
||||
GLUTproc glutGetProcAddress(const char *procName) {
|
||||
# ifdef WIN32
|
||||
return (GLUTproc)wglGetProcAddress((LPCSTR)procName);
|
||||
|
||||
# elif (HAVE_DLSYM && HAVE_DLFCN_H)
|
||||
char symbol[1024];
|
||||
|
||||
snprintf(symbol, sizeof(symbol), "_%s", procName);
|
||||
|
||||
# ifdef RTLD_DEFAULT
|
||||
return (GLUTproc)dlsym(RTLD_DEFAULT, symbol);
|
||||
|
||||
# else // No RTLD_DEFAULT support, so open the current a.out symbols...
|
||||
static void *rtld_default = 0;
|
||||
|
||||
if (!rtld_default) rtld_default = dlopen(0, RTLD_LAZY);
|
||||
|
||||
if (rtld_default) return (GLUTproc)dlsym(rtld_default, symbol);
|
||||
else return 0;
|
||||
|
||||
# endif // RTLD_DEFAULT
|
||||
|
||||
# elif defined(HAVE_GLXGETPROCADDRESSARB)
|
||||
return (GLUTproc)glXGetProcAddressARB((const GLubyte *)procName);
|
||||
|
||||
# else
|
||||
return (GLUTproc)0;
|
||||
# endif // WIN32
|
||||
return (GLUTproc)Fl_Gl_Window_Driver::global()->GetProcAddress(procName);
|
||||
}
|
||||
|
||||
// Parse the GL_EXTENSIONS string to see if the named extension is
|
||||
|
|
Loading…
Reference in New Issue