summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-01-21 16:37:42 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-01-21 16:37:42 +0000
commit5ff6efd52913ba1d3ec6f22bc61e416a26e70361 (patch)
tree1debe4f2511064f890ad00500953f55bc0f38ec9
parent84e9be966d40bd6d74b5165987049051127f3a04 (diff)
Removed OpenGL graphics driver from public view. For the parts that are implemented, it will 'just work' by allowing fl_* rendering into OpenGL contexts (such as widgets, etc.)
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11021 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--src/cfg_gfx/opengl.H784
-rw-r--r--src/cfg_gfx/opengl_rect.cxx879
-rw-r--r--src/cfg_gfx/quartz_rect.cxx6
3 files changed, 198 insertions, 1471 deletions
diff --git a/src/cfg_gfx/opengl.H b/src/cfg_gfx/opengl.H
index 82b38fd14..7737757b3 100644
--- a/src/cfg_gfx/opengl.H
+++ b/src/cfg_gfx/opengl.H
@@ -1,9 +1,10 @@
//
// "$Id$"
//
-// OpenGL window code for the Fast Light Tool Kit (FLTK).
+// Definition of OpenGL graphics driver
+// 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
@@ -16,767 +17,54 @@
// http://www.fltk.org/str.php
//
-#include "flstring.h"
-#include "config_lib.h"
-#if HAVE_GL
+/**
+ \file opengl.H
+ \brief Definition of OpenGL graphics driver.
+ */
-extern int fl_gl_load_plugin;
+#ifndef FL_CFG_GFX_OPENGL_H
+#define FL_CFG_GFX_OPENGL_H
-#include <FL/Fl.H>
-#include <FL/x.H>
-#include "Fl_Gl_Choice.H"
-#ifdef __APPLE__
-#include <FL/gl.h>
-#include <OpenGL/OpenGL.h>
-#endif
-#include <FL/Fl_Gl_Window.H>
#include <FL/Fl_Device.H>
-#include <stdlib.h>
-#include <FL/fl_utf8.h>
-
-#if defined(WIN32) || defined(__APPLE__)
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement the creation and destruction of OpenGL surfaces"
-#else
-#endif
-// ------ this should be in a separate file! -----------------------------------
-#ifdef FL_CFG_GFX_OPENGL
-
-#include <FL/Fl_Device.H>
-#include <FL/gl.h>
-
/**
- \brief OpenGL pecific graphics class.
- *
- This class is implemented only on the Mac OS X platform.
+ \brief OpenGL specific graphics class.
*/
class FL_EXPORT Fl_OpenGL_Graphics_Driver : public Fl_Graphics_Driver {
public:
static const char *class_id;
const char *class_name() {return class_id;};
- void draw(const char* str, int n, int x, int y) {
- gl_draw(str, n, x, y);
- }
- void color(Fl_Color c) {
- gl_color(c);
- }
- void color(uchar r, uchar g, uchar b) {
- unsigned int c = (r<<24)|(g<<16)|(b<<8);
- gl_color(c);
- }
- // --- implementation will eventually be in src/fl_rect.cxx which includes src/cfg_gfx/xlib_rect.cxx
- // --- line and polygon drawing with integer coordinates
- void point(int x, int y) {
- glBegin(GL_POINTS);
- glVertex2i(x, y);
- glEnd();
- }
- void rect(int x, int y, int w, int h) {
- glBegin(GL_LINE_LOOP);
- glVertex2i(x, y);
- glVertex2i(x+w, y);
- glVertex2i(x+w, y+h);
- glVertex2i(x, y+h);
- glEnd();
- }
- void rectf(int x, int y, int w, int h) {
- if (w<=0 || h<=0) return;
- // OpenGL has the natural origin at the bottom left. Drawing in FLTK
- // coordinates requires that we shift the rectangle one pixel up.
- glBegin(GL_POLYGON);
- glVertex2i(x, y-1);
- glVertex2i(x+w, y-1);
- glVertex2i(x+w, y+h-1);
- glVertex2i(x, y+h-1);
- glEnd();
- }
- void line(int x, int y, int x1, int y1) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y1);
- glEnd();
- point(x1, y1);
- }
- void line(int x, int y, int x1, int y1, int x2, int y2) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
- point(x2, y2);
- }
- void xyline(int x, int y, int x1) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y);
- glEnd();
- point(x1, y);
- }
- void xyline(int x, int y, int x1, int y2) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y);
- glVertex2i(x1, y2);
- glEnd();
- point(x1, y2);
- }
- void xyline(int x, int y, int x1, int y2, int x3) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y);
- glVertex2i(x1, y2);
- glVertex2i(x3, y2);
- glEnd();
- point(x3, y2);
- }
- void yxline(int x, int y, int y1) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x, y1);
- glEnd();
- point(x, y1);
- }
- void yxline(int x, int y, int y1, int x2) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x, y1);
- glVertex2i(x2, y1);
- glEnd();
- point(x2, y1);
- }
- void yxline(int x, int y, int y1, int x2, int y3) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x, y1);
- glVertex2i(x2, y1);
- glVertex2i(x2, y3);
- glEnd();
- point(x2, y3);
- }
- void loop(int x0, int y0, int x1, int y1, int x2, int y2) {
- glBegin(GL_LINE_LOOP);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
- }
- void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
- glBegin(GL_LINE_LOOP);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glVertex2i(x3, y3);
- glEnd();
- }
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
- glBegin(GL_POLYGON);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
- }
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
- glBegin(GL_POLYGON);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glVertex2i(x3, y3);
- glEnd();
- }
- void push_clip(int x, int y, int w, int h) {
- // TODO: implement OpenGL clipping
- if (rstackptr < region_stack_max) rstack[++rstackptr] = 0L;
- else Fl::warning("Fl_OpenGL_Graphics_Driver::push_clip: clip stack overflow!\n");
- }
- int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {
- // TODO: implement OpenGL clipping
- X = x; Y = y; W = w, H = h;
- return 0;
- }
- int not_clipped(int x, int y, int w, int h) {
- // TODO: implement OpenGL clipping
- return 1;
- }
- void push_no_clip() {
- // TODO: implement OpenGL clipping
- if (rstackptr < region_stack_max) rstack[++rstackptr] = 0;
- else Fl::warning("Fl_OpenGL_Graphics_Driver::push_no_clip: clip stack overflow!\n");
- restore_clip();
- }
- void pop_clip() {
- // TODO: implement OpenGL clipping
- if (rstackptr > 0) {
- rstackptr--;
- } else Fl::warning("Fl_OpenGL_Graphics_Driver::pop_clip: clip stack underflow!\n");
- restore_clip();
- }
- void restore_clip() {
- // TODO: implement OpenGL clipping
- fl_clip_state_number++;
- }
-};
-
-const char *Fl_OpenGL_Graphics_Driver::class_id = "Fl_OpenGL_Graphics_Driver";
+ void draw(const char* str, int n, int x, int y);
+ void color(Fl_Color c);
+ void color(uchar r, uchar g, uchar b);
-Fl_OpenGL_Display_Device *Fl_OpenGL_Display_Device::display_device() {
- static Fl_OpenGL_Display_Device *display = new Fl_OpenGL_Display_Device(new Fl_OpenGL_Graphics_Driver());
- return display;
+ // --- line and polygon drawing with integer coordinates
+ void point(int x, int y);
+ void rect(int x, int y, int w, int h);
+ void rectf(int x, int y, int w, int h);
+ void line(int x, int y, int x1, int y1);
+ void line(int x, int y, int x1, int y1, int x2, int y2);
+ void xyline(int x, int y, int x1);
+ void xyline(int x, int y, int x1, int y2);
+ void xyline(int x, int y, int x1, int y2, int x3);
+ void yxline(int x, int y, int y1);
+ void yxline(int x, int y, int y1, int x2);
+ void yxline(int x, int y, int y1, int x2, int y3);
+ void loop(int x0, int y0, int x1, int y1, int x2, int y2);
+ void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+ void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
+ void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+ void push_clip(int x, int y, int w, int h);
+ int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
+ int not_clipped(int x, int y, int w, int h);
+ void push_no_clip();
+ void pop_clip();
+ void restore_clip();
};
-Fl_OpenGL_Display_Device::Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *graphics_driver)
-: Fl_Surface_Device(graphics_driver)
-{
-}
-
-
-const char *Fl_OpenGL_Display_Device::class_id = "Fl_OpenGL_Display_Device";
-
-
-
-#endif
-// ------ end of separate file! ------------------------------------------------
-
-
-////////////////////////////////////////////////////////////////
-
-// The symbol SWAP_TYPE defines what is in the back buffer after doing
-// a glXSwapBuffers().
-
-// The OpenGl documentation says that the contents of the backbuffer
-// are "undefined" after glXSwapBuffers(). However, if we know what
-// is in the backbuffers then we can save a good deal of time. For
-// this reason you can define some symbols to describe what is left in
-// the back buffer.
-
-// Having not found any way to determine this from glx (or wgl) I have
-// resorted to letting the user specify it with an environment variable,
-// GL_SWAP_TYPE, it should be equal to one of these symbols:
-
-// contents of back buffer after glXSwapBuffers():
-#define UNDEFINED 1 // anything
-#define SWAP 2 // former front buffer (same as unknown)
-#define COPY 3 // unchanged
-#define NODAMAGE 4 // unchanged even by X expose() events
-
-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;
-}
-
-void Fl_Gl_Window::show() {
-#if defined(__APPLE__)
- int need_redraw = 0;
-#endif
- if (!shown()) {
- if (!g) {
- g = Fl_Gl_Choice::find(mode_,alist);
- if (!g && (mode_ & FL_DOUBLE) == FL_SINGLE) {
- g = Fl_Gl_Choice::find(mode_ | FL_DOUBLE,alist);
- if (g) mode_ |= FL_FAKE_SINGLE;
- }
-
- if (!g) {
- Fl::error("Insufficient GL support");
- return;
- }
- }
-#if !defined(WIN32) && !defined(__APPLE__)
- Fl_X::make_xid(this, g->vis, g->colormap);
- if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
-#elif defined(__APPLE__)
- if( ! parent() ) need_redraw=1;
-#endif
- }
- Fl_Window::show();
-
-#ifdef __APPLE__
- set_visible();
- if(need_redraw) redraw();//necessary only after creation of a top-level GL window
-#endif /* __APPLE__ */
-}
-
-#if defined(__APPLE__)
-
-int Fl_Gl_Window::pixels_per_unit()
-{
- return (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(this) && Fl_X::i(this)->mapped_to_retina()) ? 2 : 1;
-}
-
-#endif // __APPLE__
-
-/**
- The invalidate() method turns off valid() and is
- equivalent to calling value(0).
-*/
-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
-}
-
-int Fl_Gl_Window::mode(int m, const int *a) {
- if (m == mode_ && a == alist) return 0;
-#ifndef __APPLE__
- int oldmode = mode_;
-#endif
-#if defined(__APPLE__) || defined(USE_X11)
- 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__)
- kCGLPFADoubleBuffer
-# else
- GLX_DOUBLEBUFFER
-# endif
- ) { m |= FL_DOUBLE; break; }
- }
- }
-#endif // !__APPLE__
-#if !defined(WIN32) && !defined(__APPLE__)
- Fl_Gl_Choice* oldg = g;
-#endif // !WIN32 && !__APPLE__
- 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__)
- redraw();
-#else
-# error unsupported platform
-#endif
- } else {
- g = 0;
- }
- return 1;
-}
-
-#define NON_LOCAL_CONTEXT 0x80000000
-
-/**
- The make_current() method selects the OpenGL context for the
- widget. It is called automatically prior to the draw() method
- being called and can also be used to implement feedback and/or
- selection within the handle() method.
-*/
-
-void Fl_Gl_Window::make_current() {
-// puts("Fl_Gl_Window::make_current()");
-// printf("make_current: context_=%p\n", context_);
-#if defined(__APPLE__)
- // detect if the window was moved between low and high resolution displays
- if (Fl_X::i(this)->changed_resolution()){
- Fl_X::i(this)->changed_resolution(false);
- invalidate();
- Fl_X::GLcontext_update(context_);
- }
-#endif
- if (!context_) {
- mode_ &= ~NON_LOCAL_CONTEXT;
- context_ = fl_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(fl_gc, fl_palette, FALSE);
- RealizePalette(fl_gc);
- }
-#endif // USE_COLORMAP
- if (mode_ & FL_FAKE_SINGLE) {
- glDrawBuffer(GL_FRONT);
- glReadBuffer(GL_FRONT);
- }
- current_ = this;
-}
-
-/**
- Sets the projection so 0,0 is in the lower left of the window and each
- pixel is 1 unit wide/tall. If you are drawing 2D images, your
- draw() method may want to call this if valid() is false.
-*/
-void Fl_Gl_Window::ortho() {
-// Alpha NT seems to have a broken OpenGL that does not like negative coords:
-#ifdef _M_ALPHA
- glLoadIdentity();
- glViewport(0, 0, w(), h());
- glOrtho(0, w(), 0, h(), -1, 1);
-#else
- GLint v[2];
- glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
- glLoadIdentity();
- glViewport(pixel_w()-v[0], pixel_h()-v[1], v[0], v[1]);
- glOrtho(pixel_w()-v[0], pixel_w(), pixel_h()-v[1], pixel_h(), -1, 1);
-#endif
-}
-
-/**
- The swap_buffers() method swaps the back and front buffers.
- 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_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE);
- DWORD err = GetLastError();;
-# else
- SwapBuffers(Fl_X::i(this)->private_dc);
-# endif
-#elif defined(__APPLE_QUARTZ__)
- 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
-}
-
-#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_X::i(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_X::i(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
-
- make_current();
-
- if (mode_ & FL_DOUBLE) {
-
- glDrawBuffer(GL_BACK);
-
- if (!SWAP_TYPE) {
-#if defined (__APPLE_QUARTZ__) || defined (USE_X11)
- SWAP_TYPE = COPY;
-#else
- SWAP_TYPE = UNDEFINED;
-#endif
- const char* c = fl_getenv("GL_SWAP_TYPE");
- if (c) {
- if (!strcmp(c,"COPY")) SWAP_TYPE = COPY;
- else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE;
- else if (!strcmp(c, "SWAP")) SWAP_TYPE = SWAP;
- else SWAP_TYPE = UNDEFINED;
- }
- }
-
- if (SWAP_TYPE == NODAMAGE) {
-
- // don't draw if only overlay damage or expose events:
- if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !save_valid)
- draw();
- swap_buffers();
-
- } else if (SWAP_TYPE == COPY) {
-
- // don't draw if only the overlay is damaged:
- if (damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
- swap_buffers();
-
- } else if (SWAP_TYPE == SWAP){
- damage(FL_DAMAGE_ALL);
- draw();
- if (overlay == this) draw_overlay();
- swap_buffers();
- } else if (SWAP_TYPE == UNDEFINED){ // SWAP_TYPE == UNDEFINED
-
- // If we are faking the overlay, use CopyPixels to act like
- // SWAP_TYPE == COPY. Otherwise overlay redraw is way too slow.
- if (overlay == this) {
- // don't draw if only the overlay is damaged:
- if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
- // we use a separate context for the copy because rasterpos must be 0
- // and depth test needs to be off:
- 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 || !save_valid || ortho_window != this) {
- glDisable(GL_DEPTH_TEST);
- glReadBuffer(GL_BACK);
- glDrawBuffer(GL_FRONT);
- glLoadIdentity();
- glViewport(0, 0, pixel_w(), pixel_h());
- glOrtho(0, pixel_w(), 0, pixel_h(), -1, 1);
- glRasterPos2i(0,0);
- ortho_window = this;
- }
- glCopyPixels(0,0,pixel_w(),pixel_h(),GL_COLOR);
- make_current(); // set current context back to draw overlay
- damage1_ = 0;
-
- } else {
- damage1_ = damage();
- clear_damage(0xff); draw();
- swap_buffers();
- }
-
- }
-#ifdef __APPLE__
- Fl_X::GLcontext_flushbuffer(context_);
-#endif
-
- if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
- glDrawBuffer(GL_FRONT);
- draw_overlay();
- glDrawBuffer(GL_BACK);
- glFlush();
- }
-
- } else { // single-buffered context is simpler:
-
- draw();
- if (overlay == this) draw_overlay();
- glFlush();
-
- }
-
- valid(1);
- context_valid(1);
-}
-
-void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
-// printf("Fl_Gl_Window::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
-// printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h());
-
- int is_a_resize = (W != Fl_Widget::w() || H != Fl_Widget::h());
- if (is_a_resize) valid(0);
-
-#ifdef __APPLE__
- Fl_X *flx = Fl_X::i(this);
- if (flx && flx->in_windowDidResize()) Fl_X::GLcontext_update(context_);
-#endif
-
-#if ! ( defined(__APPLE__) || defined(WIN32) )
- if (is_a_resize && !resizable() && overlay && overlay != this) {
- ((Fl_Gl_Window*)overlay)->resize(0,0,W,H);
- }
-#endif
-
- Fl_Window::resize(X,Y,W,H);
-}
-
-/**
- Sets a pointer to the GLContext that this window is using.
- This is a system-dependent structure, but it is portable to copy
- the context from one window to another. You can also set it to NULL,
- which will force FLTK to recreate the context the next time make_current()
- is called, this is useful for getting around bugs in OpenGL implementations.
-
- If <i>destroy_flag</i> is true the context will be destroyed by
- fltk when the window is destroyed, or when the mode() is changed,
- 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_);
- context_ = (GLContext)v;
- if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT;
- else mode_ |= NON_LOCAL_CONTEXT;
-}
-
-/**
- Hides the window and destroys the OpenGL context.
-*/
-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
- Fl_Window::hide();
-}
-
-/**
- The destructor removes the widget and destroys the OpenGL context
- associated with it.
-*/
-Fl_Gl_Window::~Fl_Gl_Window() {
- hide();
-// delete overlay; this is done by ~Fl_Group
-}
-
-void Fl_Gl_Window::init() {
- end(); // we probably don't want any children
- box(FL_NO_BOX);
-
- mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE;
- alist = 0;
- context_ = 0;
- g = 0;
- overlay = 0;
- valid_f_ = 0;
- damage1_ = 0;
-
-#if 0 // This breaks resizing on Linux/X11
- int H = h();
- h(1); // Make sure we actually do something in resize()...
- resize(x(), y(), w(), H);
-#endif // 0
-}
-
-/**
- You must implement this virtual function if you want to draw into the
- overlay. The overlay is cleared before this is called. You should
- draw anything that is not clear using OpenGL. You must use
- gl_color(i) to choose colors (it allocates them from the colormap
- using system-specific calls), and remember that you are in an indexed
- OpenGL mode and drawing anything other than flat-shaded will probably
- not work.
-
- Both this function and Fl_Gl_Window::draw() should check
- Fl_Gl_Window::valid() and set the same transformation. If you
- don't your code may not work on other systems. Depending on the OS,
- and on whether overlays are real or simulated, the OpenGL context may
- be the same or different between the overlay and main window.
-*/
-void Fl_Gl_Window::draw_overlay() {}
-
-#endif
-
- /**
- 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
- reinitializing the viewport and lights and other things by checking
- valid() at the start of draw() and only doing the
- initialization if it is false.
-
- The draw() method can <I>only</I> use OpenGL calls. Do not
- attempt to call X, any of the functions in <FL/fl_draw.H>, or glX
- directly. Do not call gl_start() or gl_finish().
-
- If double-buffering is enabled in the window, the back and front
- buffers are swapped after this function is completed.
-*/
-void Fl_Gl_Window::draw() {
-#ifdef FL_CFG_GFX_OPENGL
- Fl_Surface_Device *prev_device = Fl_Surface_Device::surface();
- Fl_OpenGL_Display_Device::display_device()->set_current();
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_DEPTH_TEST);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-0.5, w()-0.5, h()-0.5, -0.5, -1, 1);
-// glOrtho(0, w(), h(), 0, -1, 1);
- glLineWidth(pixels_per_unit()); // should be 1 or 2 (2 if highres OpenGL)
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // FIXME: push on state stack
- glEnable(GL_BLEND); // FIXME: push on state stack
-
- Fl_Window::draw();
-
- glPopMatrix();
- glPushAttrib(GL_ENABLE_BIT);
- prev_device->set_current();
-#else
- Fl::fatal("Fl_Gl_Window::draw() *must* be overriden. Please refer to the documentation.");
-#endif
-}
-
-
-/**
- Handle some FLTK events as needed.
- */
-int Fl_Gl_Window::handle(int event)
-{
- return Fl_Window::handle(event);
-}
-
-// don't remove me! this serves only to force linking of Fl_Gl_Device_Plugin.o
-int Fl_Gl_Window::gl_plugin_linkage() {
- return fl_gl_load_plugin;
-}
+#endif // FL_CFG_GFX_OPENGL_H
//
// End of "$Id$".
diff --git a/src/cfg_gfx/opengl_rect.cxx b/src/cfg_gfx/opengl_rect.cxx
index 82b38fd14..63038a19c 100644
--- a/src/cfg_gfx/opengl_rect.cxx
+++ b/src/cfg_gfx/opengl_rect.cxx
@@ -1,9 +1,9 @@
//
// "$Id$"
//
-// OpenGL window code for the Fast Light Tool Kit (FLTK).
+// Rectangle drawing routines 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
@@ -16,767 +16,206 @@
// http://www.fltk.org/str.php
//
-#include "flstring.h"
-#include "config_lib.h"
-#if HAVE_GL
+#ifndef FL_CFG_GFX_OPENGL_RECT_CXX
+#define FL_CFG_GFX_OPENGL_RECT_CXX
-extern int fl_gl_load_plugin;
-
-#include <FL/Fl.H>
-#include <FL/x.H>
-#include "Fl_Gl_Choice.H"
-#ifdef __APPLE__
-#include <FL/gl.h>
-#include <OpenGL/OpenGL.h>
-#endif
-#include <FL/Fl_Gl_Window.H>
-#include <FL/Fl_Device.H>
-#include <stdlib.h>
-#include <FL/fl_utf8.h>
-
-#if defined(WIN32) || defined(__APPLE__)
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement the creation and destruction of OpenGL surfaces"
-#else
-#endif
-
-
-// ------ this should be in a separate file! -----------------------------------
-#ifdef FL_CFG_GFX_OPENGL
-
-#include <FL/Fl_Device.H>
-#include <FL/gl.h>
/**
- \brief OpenGL pecific graphics class.
- *
- This class is implemented only on the Mac OS X platform.
+ \file quartz_rect.cxx
+ \brief OpenGL specific line and polygon drawing with integer coordinates.
*/
-class FL_EXPORT Fl_OpenGL_Graphics_Driver : public Fl_Graphics_Driver {
-public:
- static const char *class_id;
- const char *class_name() {return class_id;};
- void draw(const char* str, int n, int x, int y) {
- gl_draw(str, n, x, y);
- }
- void color(Fl_Color c) {
- gl_color(c);
- }
- void color(uchar r, uchar g, uchar b) {
- unsigned int c = (r<<24)|(g<<16)|(b<<8);
- gl_color(c);
- }
- // --- implementation will eventually be in src/fl_rect.cxx which includes src/cfg_gfx/xlib_rect.cxx
- // --- line and polygon drawing with integer coordinates
- void point(int x, int y) {
- glBegin(GL_POINTS);
- glVertex2i(x, y);
- glEnd();
- }
- void rect(int x, int y, int w, int h) {
- glBegin(GL_LINE_LOOP);
- glVertex2i(x, y);
- glVertex2i(x+w, y);
- glVertex2i(x+w, y+h);
- glVertex2i(x, y+h);
- glEnd();
- }
- void rectf(int x, int y, int w, int h) {
- if (w<=0 || h<=0) return;
- // OpenGL has the natural origin at the bottom left. Drawing in FLTK
- // coordinates requires that we shift the rectangle one pixel up.
- glBegin(GL_POLYGON);
- glVertex2i(x, y-1);
- glVertex2i(x+w, y-1);
- glVertex2i(x+w, y+h-1);
- glVertex2i(x, y+h-1);
- glEnd();
- }
- void line(int x, int y, int x1, int y1) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y1);
- glEnd();
- point(x1, y1);
- }
- void line(int x, int y, int x1, int y1, int x2, int y2) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
- point(x2, y2);
- }
- void xyline(int x, int y, int x1) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y);
- glEnd();
- point(x1, y);
- }
- void xyline(int x, int y, int x1, int y2) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y);
- glVertex2i(x1, y2);
- glEnd();
- point(x1, y2);
- }
- void xyline(int x, int y, int x1, int y2, int x3) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x1, y);
- glVertex2i(x1, y2);
- glVertex2i(x3, y2);
- glEnd();
- point(x3, y2);
- }
- void yxline(int x, int y, int y1) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x, y1);
- glEnd();
- point(x, y1);
- }
- void yxline(int x, int y, int y1, int x2) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x, y1);
- glVertex2i(x2, y1);
- glEnd();
- point(x2, y1);
- }
- void yxline(int x, int y, int y1, int x2, int y3) {
- glBegin(GL_LINE_STRIP);
- glVertex2i(x, y);
- glVertex2i(x, y1);
- glVertex2i(x2, y1);
- glVertex2i(x2, y3);
- glEnd();
- point(x2, y3);
- }
- void loop(int x0, int y0, int x1, int y1, int x2, int y2) {
- glBegin(GL_LINE_LOOP);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
- }
- void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
- glBegin(GL_LINE_LOOP);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glVertex2i(x3, y3);
- glEnd();
- }
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
- glBegin(GL_POLYGON);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glEnd();
- }
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
- glBegin(GL_POLYGON);
- glVertex2i(x0, y0);
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
- glVertex2i(x3, y3);
- glEnd();
- }
- void push_clip(int x, int y, int w, int h) {
- // TODO: implement OpenGL clipping
- if (rstackptr < region_stack_max) rstack[++rstackptr] = 0L;
- else Fl::warning("Fl_OpenGL_Graphics_Driver::push_clip: clip stack overflow!\n");
- }
- int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {
- // TODO: implement OpenGL clipping
- X = x; Y = y; W = w, H = h;
- return 0;
- }
- int not_clipped(int x, int y, int w, int h) {
- // TODO: implement OpenGL clipping
- return 1;
- }
- void push_no_clip() {
- // TODO: implement OpenGL clipping
- if (rstackptr < region_stack_max) rstack[++rstackptr] = 0;
- else Fl::warning("Fl_OpenGL_Graphics_Driver::push_no_clip: clip stack overflow!\n");
- restore_clip();
- }
- void pop_clip() {
- // TODO: implement OpenGL clipping
- if (rstackptr > 0) {
- rstackptr--;
- } else Fl::warning("Fl_OpenGL_Graphics_Driver::pop_clip: clip stack underflow!\n");
- restore_clip();
- }
- void restore_clip() {
- // TODO: implement OpenGL clipping
- fl_clip_state_number++;
- }
-};
-
-const char *Fl_OpenGL_Graphics_Driver::class_id = "Fl_OpenGL_Graphics_Driver";
-
-Fl_OpenGL_Display_Device *Fl_OpenGL_Display_Device::display_device() {
- static Fl_OpenGL_Display_Device *display = new Fl_OpenGL_Display_Device(new Fl_OpenGL_Graphics_Driver());
- return display;
-};
+#include <FL/gl.h>
+#include "opengl.h"
-Fl_OpenGL_Display_Device::Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *graphics_driver)
-: Fl_Surface_Device(graphics_driver)
-{
+void Fl_OpenGL_Graphics_Driver::draw(const char* str, int n, int x, int y) {
+ gl_draw(str, n, x, y);
}
+void Fl_OpenGL_Graphics_Driver::color(Fl_Color c) {
+ gl_color(c);
+}
-const char *Fl_OpenGL_Display_Device::class_id = "Fl_OpenGL_Display_Device";
-
-
-
-#endif
-// ------ end of separate file! ------------------------------------------------
-
-
-////////////////////////////////////////////////////////////////
-
-// The symbol SWAP_TYPE defines what is in the back buffer after doing
-// a glXSwapBuffers().
-
-// The OpenGl documentation says that the contents of the backbuffer
-// are "undefined" after glXSwapBuffers(). However, if we know what
-// is in the backbuffers then we can save a good deal of time. For
-// this reason you can define some symbols to describe what is left in
-// the back buffer.
-
-// Having not found any way to determine this from glx (or wgl) I have
-// resorted to letting the user specify it with an environment variable,
-// GL_SWAP_TYPE, it should be equal to one of these symbols:
-
-// contents of back buffer after glXSwapBuffers():
-#define UNDEFINED 1 // anything
-#define SWAP 2 // former front buffer (same as unknown)
-#define COPY 3 // unchanged
-#define NODAMAGE 4 // unchanged even by X expose() events
-
-static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable
+void Fl_OpenGL_Graphics_Driver::color(uchar r, uchar g, uchar b) {
+ unsigned int c = (r<<24)|(g<<16)|(b<<8);
+ gl_color(c);
+}
-////////////////////////////////////////////////////////////////
+// --- line and polygon drawing with integer coordinates
-/** 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;
+void Fl_OpenGL_Graphics_Driver::point(int x, int y) {
+ glBegin(GL_POINTS);
+ glVertex2i(x, y);
+ glEnd();
}
-void Fl_Gl_Window::show() {
-#if defined(__APPLE__)
- int need_redraw = 0;
-#endif
- if (!shown()) {
- if (!g) {
- g = Fl_Gl_Choice::find(mode_,alist);
- if (!g && (mode_ & FL_DOUBLE) == FL_SINGLE) {
- g = Fl_Gl_Choice::find(mode_ | FL_DOUBLE,alist);
- if (g) mode_ |= FL_FAKE_SINGLE;
- }
-
- if (!g) {
- Fl::error("Insufficient GL support");
- return;
- }
- }
-#if !defined(WIN32) && !defined(__APPLE__)
- Fl_X::make_xid(this, g->vis, g->colormap);
- if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
-#elif defined(__APPLE__)
- if( ! parent() ) need_redraw=1;
-#endif
- }
- Fl_Window::show();
-
-#ifdef __APPLE__
- set_visible();
- if(need_redraw) redraw();//necessary only after creation of a top-level GL window
-#endif /* __APPLE__ */
+void Fl_OpenGL_Graphics_Driver::rect(int x, int y, int w, int h) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(x, y);
+ glVertex2i(x+w, y);
+ glVertex2i(x+w, y+h);
+ glVertex2i(x, y+h);
+ glEnd();
}
-#if defined(__APPLE__)
-
-int Fl_Gl_Window::pixels_per_unit()
-{
- return (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(this) && Fl_X::i(this)->mapped_to_retina()) ? 2 : 1;
+void Fl_OpenGL_Graphics_Driver::rectf(int x, int y, int w, int h) {
+ if (w<=0 || h<=0) return;
+ // OpenGL has the natural origin at the bottom left. Drawing in FLTK
+ // coordinates requires that we shift the rectangle one pixel up.
+ glBegin(GL_POLYGON);
+ glVertex2i(x, y-1);
+ glVertex2i(x+w, y-1);
+ glVertex2i(x+w, y+h-1);
+ glVertex2i(x, y+h-1);
+ glEnd();
}
-#endif // __APPLE__
-
-/**
- The invalidate() method turns off valid() and is
- equivalent to calling value(0).
-*/
-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
+void Fl_OpenGL_Graphics_Driver::line(int x, int y, int x1, int y1) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x1, y1);
+ glEnd();
+ point(x1, y1);
}
-int Fl_Gl_Window::mode(int m, const int *a) {
- if (m == mode_ && a == alist) return 0;
-#ifndef __APPLE__
- int oldmode = mode_;
-#endif
-#if defined(__APPLE__) || defined(USE_X11)
- 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__)
- kCGLPFADoubleBuffer
-# else
- GLX_DOUBLEBUFFER
-# endif
- ) { m |= FL_DOUBLE; break; }
- }
- }
-#endif // !__APPLE__
-#if !defined(WIN32) && !defined(__APPLE__)
- Fl_Gl_Choice* oldg = g;
-#endif // !WIN32 && !__APPLE__
- 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__)
- redraw();
-#else
-# error unsupported platform
-#endif
- } else {
- g = 0;
- }
- return 1;
+void Fl_OpenGL_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x1, y1);
+ glVertex2i(x2, y2);
+ glEnd();
+ point(x2, y2);
}
-#define NON_LOCAL_CONTEXT 0x80000000
+void Fl_OpenGL_Graphics_Driver::xyline(int x, int y, int x1) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x1, y);
+ glEnd();
+ point(x1, y);
+}
-/**
- The make_current() method selects the OpenGL context for the
- widget. It is called automatically prior to the draw() method
- being called and can also be used to implement feedback and/or
- selection within the handle() method.
-*/
-
-void Fl_Gl_Window::make_current() {
-// puts("Fl_Gl_Window::make_current()");
-// printf("make_current: context_=%p\n", context_);
-#if defined(__APPLE__)
- // detect if the window was moved between low and high resolution displays
- if (Fl_X::i(this)->changed_resolution()){
- Fl_X::i(this)->changed_resolution(false);
- invalidate();
- Fl_X::GLcontext_update(context_);
- }
-#endif
- if (!context_) {
- mode_ &= ~NON_LOCAL_CONTEXT;
- context_ = fl_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(fl_gc, fl_palette, FALSE);
- RealizePalette(fl_gc);
- }
-#endif // USE_COLORMAP
- if (mode_ & FL_FAKE_SINGLE) {
- glDrawBuffer(GL_FRONT);
- glReadBuffer(GL_FRONT);
- }
- current_ = this;
+void Fl_OpenGL_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x1, y);
+ glVertex2i(x1, y2);
+ glEnd();
+ point(x1, y2);
}
-/**
- Sets the projection so 0,0 is in the lower left of the window and each
- pixel is 1 unit wide/tall. If you are drawing 2D images, your
- draw() method may want to call this if valid() is false.
-*/
-void Fl_Gl_Window::ortho() {
-// Alpha NT seems to have a broken OpenGL that does not like negative coords:
-#ifdef _M_ALPHA
- glLoadIdentity();
- glViewport(0, 0, w(), h());
- glOrtho(0, w(), 0, h(), -1, 1);
-#else
- GLint v[2];
- glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
- glLoadIdentity();
- glViewport(pixel_w()-v[0], pixel_h()-v[1], v[0], v[1]);
- glOrtho(pixel_w()-v[0], pixel_w(), pixel_h()-v[1], pixel_h(), -1, 1);
-#endif
+void Fl_OpenGL_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x1, y);
+ glVertex2i(x1, y2);
+ glVertex2i(x3, y2);
+ glEnd();
+ point(x3, y2);
}
-/**
- The swap_buffers() method swaps the back and front buffers.
- 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_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE);
- DWORD err = GetLastError();;
-# else
- SwapBuffers(Fl_X::i(this)->private_dc);
-# endif
-#elif defined(__APPLE_QUARTZ__)
- 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
+void Fl_OpenGL_Graphics_Driver::yxline(int x, int y, int y1) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x, y1);
+ glEnd();
+ point(x, y1);
}
-#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_X::i(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_X::i(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
-
- make_current();
-
- if (mode_ & FL_DOUBLE) {
-
- glDrawBuffer(GL_BACK);
-
- if (!SWAP_TYPE) {
-#if defined (__APPLE_QUARTZ__) || defined (USE_X11)
- SWAP_TYPE = COPY;
-#else
- SWAP_TYPE = UNDEFINED;
-#endif
- const char* c = fl_getenv("GL_SWAP_TYPE");
- if (c) {
- if (!strcmp(c,"COPY")) SWAP_TYPE = COPY;
- else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE;
- else if (!strcmp(c, "SWAP")) SWAP_TYPE = SWAP;
- else SWAP_TYPE = UNDEFINED;
- }
- }
-
- if (SWAP_TYPE == NODAMAGE) {
-
- // don't draw if only overlay damage or expose events:
- if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !save_valid)
- draw();
- swap_buffers();
-
- } else if (SWAP_TYPE == COPY) {
-
- // don't draw if only the overlay is damaged:
- if (damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
- swap_buffers();
-
- } else if (SWAP_TYPE == SWAP){
- damage(FL_DAMAGE_ALL);
- draw();
- if (overlay == this) draw_overlay();
- swap_buffers();
- } else if (SWAP_TYPE == UNDEFINED){ // SWAP_TYPE == UNDEFINED
-
- // If we are faking the overlay, use CopyPixels to act like
- // SWAP_TYPE == COPY. Otherwise overlay redraw is way too slow.
- if (overlay == this) {
- // don't draw if only the overlay is damaged:
- if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
- // we use a separate context for the copy because rasterpos must be 0
- // and depth test needs to be off:
- 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 || !save_valid || ortho_window != this) {
- glDisable(GL_DEPTH_TEST);
- glReadBuffer(GL_BACK);
- glDrawBuffer(GL_FRONT);
- glLoadIdentity();
- glViewport(0, 0, pixel_w(), pixel_h());
- glOrtho(0, pixel_w(), 0, pixel_h(), -1, 1);
- glRasterPos2i(0,0);
- ortho_window = this;
- }
- glCopyPixels(0,0,pixel_w(),pixel_h(),GL_COLOR);
- make_current(); // set current context back to draw overlay
- damage1_ = 0;
-
- } else {
- damage1_ = damage();
- clear_damage(0xff); draw();
- swap_buffers();
- }
-
- }
-#ifdef __APPLE__
- Fl_X::GLcontext_flushbuffer(context_);
-#endif
-
- if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
- glDrawBuffer(GL_FRONT);
- draw_overlay();
- glDrawBuffer(GL_BACK);
- glFlush();
- }
-
- } else { // single-buffered context is simpler:
-
- draw();
- if (overlay == this) draw_overlay();
- glFlush();
-
- }
-
- valid(1);
- context_valid(1);
+void Fl_OpenGL_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x, y1);
+ glVertex2i(x2, y1);
+ glEnd();
+ point(x2, y1);
}
-void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
-// printf("Fl_Gl_Window::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
-// printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h());
-
- int is_a_resize = (W != Fl_Widget::w() || H != Fl_Widget::h());
- if (is_a_resize) valid(0);
-
-#ifdef __APPLE__
- Fl_X *flx = Fl_X::i(this);
- if (flx && flx->in_windowDidResize()) Fl_X::GLcontext_update(context_);
-#endif
-
-#if ! ( defined(__APPLE__) || defined(WIN32) )
- if (is_a_resize && !resizable() && overlay && overlay != this) {
- ((Fl_Gl_Window*)overlay)->resize(0,0,W,H);
- }
-#endif
-
- Fl_Window::resize(X,Y,W,H);
+void Fl_OpenGL_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x, y);
+ glVertex2i(x, y1);
+ glVertex2i(x2, y1);
+ glVertex2i(x2, y3);
+ glEnd();
+ point(x2, y3);
+}
+
+void Fl_OpenGL_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(x0, y0);
+ glVertex2i(x1, y1);
+ glVertex2i(x2, y2);
+ glEnd();
+}
+
+void Fl_OpenGL_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(x0, y0);
+ glVertex2i(x1, y1);
+ glVertex2i(x2, y2);
+ glVertex2i(x3, y3);
+ glEnd();
+}
+
+void Fl_OpenGL_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
+ glBegin(GL_POLYGON);
+ glVertex2i(x0, y0);
+ glVertex2i(x1, y1);
+ glVertex2i(x2, y2);
+ glEnd();
+}
+
+void Fl_OpenGL_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ glBegin(GL_POLYGON);
+ glVertex2i(x0, y0);
+ glVertex2i(x1, y1);
+ glVertex2i(x2, y2);
+ glVertex2i(x3, y3);
+ glEnd();
}
-/**
- Sets a pointer to the GLContext that this window is using.
- This is a system-dependent structure, but it is portable to copy
- the context from one window to another. You can also set it to NULL,
- which will force FLTK to recreate the context the next time make_current()
- is called, this is useful for getting around bugs in OpenGL implementations.
-
- If <i>destroy_flag</i> is true the context will be destroyed by
- fltk when the window is destroyed, or when the mode() is changed,
- 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_);
- context_ = (GLContext)v;
- if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT;
- else mode_ |= NON_LOCAL_CONTEXT;
-}
+void Fl_OpenGL_Graphics_Driver::push_clip(int x, int y, int w, int h) {
+ // TODO: implement OpenGL clipping
+ if (rstackptr < region_stack_max) rstack[++rstackptr] = 0L;
+ else Fl::warning("Fl_OpenGL_Graphics_Driver::push_clip: clip stack overflow!\n");
+}
+
+int Fl_OpenGL_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {
+ // TODO: implement OpenGL clipping
+ X = x; Y = y; W = w, H = h;
+ return 0;
+}
-/**
- Hides the window and destroys the OpenGL context.
-*/
-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
- Fl_Window::hide();
+int Fl_OpenGL_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
+ // TODO: implement OpenGL clipping
+ return 1;
}
-/**
- The destructor removes the widget and destroys the OpenGL context
- associated with it.
-*/
-Fl_Gl_Window::~Fl_Gl_Window() {
- hide();
-// delete overlay; this is done by ~Fl_Group
+void Fl_OpenGL_Graphics_Driver::push_no_clip() {
+ // TODO: implement OpenGL clipping
+ if (rstackptr < region_stack_max) rstack[++rstackptr] = 0;
+ else Fl::warning("Fl_OpenGL_Graphics_Driver::push_no_clip: clip stack overflow!\n");
+ restore_clip();
}
-void Fl_Gl_Window::init() {
- end(); // we probably don't want any children
- box(FL_NO_BOX);
-
- mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE;
- alist = 0;
- context_ = 0;
- g = 0;
- overlay = 0;
- valid_f_ = 0;
- damage1_ = 0;
-
-#if 0 // This breaks resizing on Linux/X11
- int H = h();
- h(1); // Make sure we actually do something in resize()...
- resize(x(), y(), w(), H);
-#endif // 0
+void Fl_OpenGL_Graphics_Driver::pop_clip() {
+ // TODO: implement OpenGL clipping
+ if (rstackptr > 0) {
+ rstackptr--;
+ } else Fl::warning("Fl_OpenGL_Graphics_Driver::pop_clip: clip stack underflow!\n");
+ restore_clip();
}
-/**
- You must implement this virtual function if you want to draw into the
- overlay. The overlay is cleared before this is called. You should
- draw anything that is not clear using OpenGL. You must use
- gl_color(i) to choose colors (it allocates them from the colormap
- using system-specific calls), and remember that you are in an indexed
- OpenGL mode and drawing anything other than flat-shaded will probably
- not work.
-
- Both this function and Fl_Gl_Window::draw() should check
- Fl_Gl_Window::valid() and set the same transformation. If you
- don't your code may not work on other systems. Depending on the OS,
- and on whether overlays are real or simulated, the OpenGL context may
- be the same or different between the overlay and main window.
-*/
-void Fl_Gl_Window::draw_overlay() {}
-
-#endif
-
- /**
- 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
- reinitializing the viewport and lights and other things by checking
- valid() at the start of draw() and only doing the
- initialization if it is false.
-
- The draw() method can <I>only</I> use OpenGL calls. Do not
- attempt to call X, any of the functions in <FL/fl_draw.H>, or glX
- directly. Do not call gl_start() or gl_finish().
-
- If double-buffering is enabled in the window, the back and front
- buffers are swapped after this function is completed.
-*/
-void Fl_Gl_Window::draw() {
-#ifdef FL_CFG_GFX_OPENGL
- Fl_Surface_Device *prev_device = Fl_Surface_Device::surface();
- Fl_OpenGL_Display_Device::display_device()->set_current();
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_DEPTH_TEST);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-0.5, w()-0.5, h()-0.5, -0.5, -1, 1);
-// glOrtho(0, w(), h(), 0, -1, 1);
- glLineWidth(pixels_per_unit()); // should be 1 or 2 (2 if highres OpenGL)
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // FIXME: push on state stack
- glEnable(GL_BLEND); // FIXME: push on state stack
-
- Fl_Window::draw();
-
- glPopMatrix();
- glPushAttrib(GL_ENABLE_BIT);
- prev_device->set_current();
-#else
- Fl::fatal("Fl_Gl_Window::draw() *must* be overriden. Please refer to the documentation.");
-#endif
+void Fl_OpenGL_Graphics_Driver::restore_clip() {
+ // TODO: implement OpenGL clipping
+ fl_clip_state_number++;
}
+const char *Fl_OpenGL_Graphics_Driver::class_id = "Fl_OpenGL_Graphics_Driver";
-/**
- Handle some FLTK events as needed.
- */
-int Fl_Gl_Window::handle(int event)
-{
- return Fl_Window::handle(event);
-}
-// don't remove me! this serves only to force linking of Fl_Gl_Device_Plugin.o
-int Fl_Gl_Window::gl_plugin_linkage() {
- return fl_gl_load_plugin;
-}
+#endif // FL_CFG_GFX_OPENGL_RECT_CXX
//
// End of "$Id$".
diff --git a/src/cfg_gfx/quartz_rect.cxx b/src/cfg_gfx/quartz_rect.cxx
index dd72e6532..78b358b8c 100644
--- a/src/cfg_gfx/quartz_rect.cxx
+++ b/src/cfg_gfx/quartz_rect.cxx
@@ -17,8 +17,8 @@
//
-#ifndef FL_CFG_GFX_QUARTZ_CXX
-#define FL_CFG_GFX_QUARTZ_CXX
+#ifndef FL_CFG_GFX_QUARTZ_RECT_CXX
+#define FL_CFG_GFX_QUARTZ_RECT_CXX
/**
@@ -282,7 +282,7 @@ void Fl_Quartz_Graphics_Driver::restore_clip() {
}
-#endif
+#endif // FL_CFG_GFX_QUARTZ_RECT_CXX
//
// End of "$Id$".