summaryrefslogtreecommitdiff
path: root/src/Fl_Gl_Window.cxx
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2014-12-20 07:19:23 +0000
committerManolo Gouy <Manolo>2014-12-20 07:19:23 +0000
commitf3a84c0ee5f88fe664d759106724f786c706f817 (patch)
tree3541953164e2d24c31ae46ef11f2c2e86b3873a3 /src/Fl_Gl_Window.cxx
parenta7dc3ea9e24399f318a9478fbcffe04ff2870de6 (diff)
Changed OpenGL support for the Mac OS X platform: use cocoa instead of deprecated AGL.
All changes are mac-specific, except a very minor change in file src/gl_draw.cxx where string drawing wrongly claimed to support @symbol, not possible because symbols are drawn using non-GL primitives. Unchanged application code can use the new FLTK code. In addition, the new code allows mac applications to draw OpenGL scenes at high resolution on so-called 'retina' displays, but this requires some support from app code. They must call, before opening GL windows, Fl::use_high_resolution(1); and change their glViewport() calls as follows glViewport(0, 0, pxel_w(), pixel_h()); This uses 2 new member functions of the Fl_Gl_Window class, pixel_w() and pixel_h() returning the window dimensions in pixel units, that is, twice the w() and h() when the window is mapped on a retina display. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10498 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Gl_Window.cxx')
-rw-r--r--src/Fl_Gl_Window.cxx112
1 files changed, 53 insertions, 59 deletions
diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx
index f23b8e2ab..d4fdfe5a1 100644
--- a/src/Fl_Gl_Window.cxx
+++ b/src/Fl_Gl_Window.cxx
@@ -26,10 +26,12 @@ extern void gl_texture_reset();
#include <FL/Fl.H>
#include <FL/x.H>
+#include "Fl_Gl_Choice.H"
#ifdef __APPLE__
#include <FL/gl.h>
+extern void gl_context_update(NSOpenGLContext*);
+extern void gl_context_flushbuffer(NSOpenGLContext*);
#endif
-#include "Fl_Gl_Choice.H"
#include <FL/Fl_Gl_Window.H>
#include <stdlib.h>
#include <FL/fl_utf8.h>
@@ -97,6 +99,20 @@ void Fl_Gl_Window::show() {
#endif /* __APPLE__ */
}
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+
+int Fl_Gl_Window::pixel_w()
+{
+ return Fl_X::resolution_scaling_factor(this) * w();
+}
+
+int Fl_Gl_Window::pixel_h()
+{
+ return Fl_X::resolution_scaling_factor(this) * h();
+}
+
+#endif
+
/**
The invalidate() method turns off valid() and is
equivalent to calling value(0).
@@ -140,7 +156,6 @@ int Fl_Gl_Window::mode(int m, const int *a) {
show();
}
#elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
redraw();
#else
# error unsupported platform
@@ -163,6 +178,14 @@ 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__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ // 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();
+ gl_context_update(context_);
+ }
+#endif
if (!context_) {
mode_ &= ~NON_LOCAL_CONTEXT;
context_ = fl_create_gl_context(this, g);
@@ -170,26 +193,12 @@ void Fl_Gl_Window::make_current() {
context_valid(0);
#ifdef __APPLE__
// resets the pile of string textures used to draw strings
+ // necessary when the context is renewed
gl_texture_reset();
#endif
}
fl_set_gl_context(this, context_);
-#ifdef __APPLE__
- // Set the buffer rectangle here, since in resize() we won't have the
- // correct parent window size to work with...
- GLint xywh[4];
-
- xywh[0] = 0;
- xywh[1] = 0;
- xywh[2] = w();
- xywh[3] = h();
-
- aglSetInteger(context_, AGL_BUFFER_RECT, xywh);
- aglEnable(context_, AGL_BUFFER_RECT);
-// printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]);
-#endif // __APPLE__
-
#if defined(WIN32) && USE_COLORMAP
if (fl_palette) {
fl_GetDC(fl_xid(this));
@@ -219,8 +228,8 @@ void Fl_Gl_Window::ortho() {
GLint v[2];
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
glLoadIdentity();
- glViewport(w()-v[0], h()-v[1], v[0], v[1]);
- glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1);
+ 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
}
@@ -244,7 +253,7 @@ void Fl_Gl_Window::swap_buffers() {
// STR# 2944 [1]
// Save matrixmode/proj/modelview/rasterpos before doing overlay.
//
- int wo=w(), ho=h();
+ int wo=pixel_w(), ho=pixel_h();
GLint matrixmode;
GLfloat pos[4];
glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
@@ -270,8 +279,10 @@ void Fl_Gl_Window::swap_buffers() {
glMatrixMode(matrixmode);
glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos
}
- else
+ /* // nothing to do here under Cocoa because [NSOpenGLContext -flushBuffer] done later replaces it
+ else
aglSwapBuffers((AGLContext)context_);
+ */
#else
# error unsupported platform
#endif
@@ -290,19 +301,6 @@ void Fl_Gl_Window::flush() {
uchar save_valid_f = valid_f_;
#endif
-#if defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
- //: clear previous clipping in this shared port
-#if ! __LP64__
-/*GrafPtr port = GetWindowPort( Fl_X::i(this)->window_ref() );
- Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff );
- GrafPtr old; GetPort( &old );
- SetPort( port );
- ClipRect( &rect );
- SetPort( old );*/
-#endif
-#endif
-
#if HAVE_GL_OVERLAY && defined(WIN32)
// Draw into hardware overlay planes if they are damaged:
@@ -383,22 +381,25 @@ void Fl_Gl_Window::flush() {
glReadBuffer(GL_BACK);
glDrawBuffer(GL_FRONT);
glLoadIdentity();
- glViewport(0, 0, w(), h());
- glOrtho(0, w(), 0, h(), -1, 1);
+ 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,w(),h(),GL_COLOR);
+ 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();
+ damage1_ = damage();
+ clear_damage(0xff); draw();
+ swap_buffers();
}
}
+#ifdef __APPLE__
+ gl_context_flushbuffer(context_);
+#endif
if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
glDrawBuffer(GL_FRONT);
@@ -423,22 +424,27 @@ 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());
- if (W != w() || H != h()) valid(0);
+ int is_a_resize = (W != Fl_Widget::w() || H != Fl_Widget::h());
+ if (is_a_resize) valid(0);
-#ifdef __APPLE__
- if (X != x() || Y != y() || W != w() || H != h()) aglUpdateContext(context_);
-#elif !defined(WIN32)
- if ((W != w() || H != h()) && !resizable() && overlay && overlay != this) {
+#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);
+#ifdef __APPLE__
+ if (is_a_resize) {
+ gl_context_update(context_);
+ redraw();
+ }
+#endif
}
/**
- Returns or sets a pointer to the GLContext that this window is
- using. This is a system-dependent structure, but it is portable to copy
+ 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.
@@ -540,18 +546,6 @@ void Fl_Gl_Window::draw() {
*/
int Fl_Gl_Window::handle(int event)
{
-#ifdef __APPLE_QUARTZ__
- if (event==FL_HIDE) {
- // if we are not hidden, just the parent was hidden, so we must throw away the context
- if (!visible_r())
- context(0); // remove context without setting the hidden flags
- }
- if (event==FL_SHOW) {
- // if we are not hidden, just the parent was shown, so we must create a new context
- if (visible_r())
- show(); //
- }
-#endif
return Fl_Window::handle(event);
}