]> git.saurik.com Git - wxWidgets.git/blame - src/motif/glcanvas.cpp
*** empty log message ***
[wxWidgets.git] / src / motif / glcanvas.cpp
CommitLineData
8b089c5e
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: glcanvas.cpp
3// Purpose: wxGLCanvas, for using OpenGL with wxWindows 2.0 for Motif.
4// Uses the GLX extension.
5// Author: Julian Smart and Wolfram Gloger
6// Modified by:
7// Created: 1995, 1999
8// RCS-ID: $Id$
9// Copyright: (c) Julian Smart, Wolfram Gloger
10// Licence: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13#ifdef __GNUG__
14#pragma implementation "glcanvas.h"
15#endif
16
17#include "wx/setup.h"
18
19#if wxUSE_GLCANVAS
20
21#include "wx/glcanvas.h"
22#include "wx/utils.h"
23#include "wx/app.h"
24
25#include <Xm/Xm.h>
26#include "wx/motif/private.h"
27
28#ifdef OLD_MESA
29// workaround for bug in Mesa's glx.c
30static int bitcount( unsigned long n )
31{
32 int bits;
33 for (bits=0; n>0;) {
34 if(n & 1) bits++;
35 n = n >> 1;
36 }
37 return bits;
38}
39#endif
40
41/*
42 * GLCanvas implementation
43 */
44
45IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
46
47wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos,
48 const wxSize& size, long style,
49 const wxString& name, int *attrib_list, const wxPalette& palette):
50 wxScrolledWindow(parent, id, pos, size, style, name)
51{
52 XVisualInfo *vi, vi_templ;
53 XWindowAttributes xwa;
54 int val, n;
55
56 Display* display = (Display*) GetXDisplay();
57
58 glx_cx = 0;
59 // Check for the presence of the GLX extension
60 if(!glXQueryExtension(display, NULL, NULL)) {
61 wxDebugMsg("wxGLCanvas: GLX extension is missing\n");
62 return;
63 }
64
65 if(attrib_list) {
66 // Get an appropriate visual
67 vi = glXChooseVisual(display, DefaultScreen(display), attrib_list);
68 if(!vi) return;
69
70 // Here we should make sure that vi is the same visual as the
71 // one used by the xwindow drawable in wxCanvas. However,
72 // there is currently no mechanism for this in wx_canvs.cc.
73 } else {
74 // By default, we use the visual of xwindow
75 XGetWindowAttributes(display, (Window) GetXWindow(), &xwa);
76 vi_templ.visualid = XVisualIDFromVisual(xwa.visual);
77 vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n);
78 if(!vi) return;
79 glXGetConfig(display, vi, GLX_USE_GL, &val);
80 if(!val) return;
81 // Basically, this is it. It should be possible to use vi
82 // in glXCreateContext() below. But this fails with Mesa.
83 // I notified the Mesa author about it; there may be a fix.
84#ifdef OLD_MESA
85 // Construct an attribute list matching the visual
86 int a_list[32];
87 n = 0;
88 if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual
89 a_list[n++] = GLX_RGBA;
90 a_list[n++] = GLX_RED_SIZE;
91 a_list[n++] = bitcount(vi->red_mask);
92 a_list[n++] = GLX_GREEN_SIZE;
93 a_list[n++] = bitcount(vi->green_mask);
94 a_list[n++] = GLX_BLUE_SIZE;
95 a_list[n++] = bitcount(vi->blue_mask);
96 glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val);
97 a_list[n++] = GLX_ALPHA_SIZE;
98 a_list[n++] = val;
99 } else { // Color index visual
100 glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val);
101 a_list[n++] = GLX_BUFFER_SIZE;
102 a_list[n++] = val;
103 }
104 a_list[n] = None;
105 XFree(vi);
106 vi = glXChooseVisual(display, DefaultScreen(display), a_list);
107 if(!vi) return;
108#endif /* OLD_MESA */
109 }
110
111 // Create the GLX context and make it current
112 glx_cx = glXCreateContext(display, vi, 0, GL_TRUE);
113#ifndef OLD_MESA
114 XFree(vi);
115#endif
116 SetCurrent();
117}
118
119wxGLCanvas::~wxGLCanvas(void)
120{
121 Display* display = (Display*) GetXDisplay();
122 if(glx_cx) glXDestroyContext(display, glx_cx);
123}
124
125void wxGLCanvas::SwapBuffers()
126{
127 Display* display = (Display*) GetXDisplay();
128 if(glx_cx) glXSwapBuffers(display, (Window) GetXWindow());
129}
130
131void wxGLCanvas::SetCurrent()
132{
133 Display* display = (Display*) GetXDisplay();
134 if(glx_cx) glXMakeCurrent(display, (Window) GetXWindow(), glx_cx);
135}
136
137void wxGLCanvas::SetColour(const char *col)
138{
139 wxColour *the_colour = wxTheColourDatabase->FindColour(col);
140 if(the_colour) {
141 GLboolean b;
142 glGetBooleanv(GL_RGBA_MODE, &b);
143 if(b) {
144 glColor3ub(the_colour->Red(),
145 the_colour->Green(),
146 the_colour->Blue());
147 } else {
148 GLint pix = (GLint)the_colour->m_pixel;
149 if(pix == -1) {
150 XColor exact_def;
151 exact_def.red = (unsigned short)the_colour->Red() << 8;
152 exact_def.green = (unsigned short)the_colour->Green() << 8;
153 exact_def.blue = (unsigned short)the_colour->Blue() << 8;
154 exact_def.flags = DoRed | DoGreen | DoBlue;
155 if(!XAllocColor((Display*) GetXDisplay(), (Colormap) wxTheApp->GetMainColormap(GetXDisplay()), &exact_def)) {
156 wxDebugMsg("wxGLCanvas: cannot allocate color\n");
157 return;
158 }
159 pix = the_colour->m_pixel = exact_def.pixel;
160 }
161 glIndexi(pix);
162 }
163 }
164}
165
166#endif
167 // wxUSE_GLCANVAS
168