summaryrefslogtreecommitdiff
path: root/src/gl_start.cxx
blob: c897e97fae9bc718e8f1b532a52e8ee3dc244b43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// "$Id$"
//
// OpenGL context routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 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
//

// You MUST use gl_visual() to select the default visual before doing
// show() of any windows.  Mesa will crash if you try to use a visual
// not returned by glxChooseVisual.

// This does not work with Fl_Double_Window's!  It will try to draw
// into the front buffer.  Depending on the system this will either
// crash or do nothing (when pixmaps are being used as back buffer
// and GL is being done by hardware), work correctly (when GL is done
// with software, such as Mesa), or draw into the front buffer and
// be erased when the buffers are swapped (when double buffer hardware
// is being used)

#if defined(WIN32) || defined(__APPLE__) // PORTME: platform opengl
#elif defined(FL_PORTING)
#  pragma message "FL_PORTING: if possible, add OpenGL rendering in non-OpenGL contexts"
#else
#endif

#include <config.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"

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

Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx

/** 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
  }
  fl_set_gl_context(Fl_Window::current(), context);
#ifdef __APPLE__
  Fl_X::GLcontext_update(context); // supports window resizing
#elif !defined(WIN32)
  glXWaitX();
#endif
  if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
    pw = Fl_Window::current()->w();
    ph = Fl_Window::current()->h();
    glLoadIdentity();
    glViewport(0, 0, pw, ph);
    glOrtho(0, pw, 0, ph, -1, 1);
    glDrawBuffer(GL_FRONT);
  }
  if (clip_state_number != fl_graphics_driver->fl_clip_state_number) {
    clip_state_number = fl_graphics_driver->fl_clip_state_number;
    int x, y, w, h;
    if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(),
		    x, y, w, h)) {
      fl_clip_region(XRectangleRegion(x,y,w,h));
      glScissor(x, Fl_Window::current()->h()-(y+h), w, h);
      glEnable(GL_SCISSOR_TEST);
    } else {
      glDisable(GL_SCISSOR_TEST);
    }
  }
}

/** Releases an OpenGL context */
void gl_finish() {
  glFlush();
#if !defined(WIN32) && !defined(__APPLE__)
  glXWaitGL();
#endif
}

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)
  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
  return 1;
}
#endif

//
// End of "$Id$".
//