some doc bug fixes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1465 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			162 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        glcanvas.cpp
 | 
						|
// Purpose:     wxGLCanvas, for using OpenGL with wxWindows 2.0 for Motif.
 | 
						|
//              Uses the GLX extension.
 | 
						|
// Author:      Julian Smart and Wolfram Gloger
 | 
						|
// Modified by:
 | 
						|
// Created:     1995, 1999
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) Julian Smart, Wolfram Gloger
 | 
						|
// Licence:   	wxWindows licence
 | 
						|
/////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifdef __GNUG__
 | 
						|
#pragma implementation "glcanvas.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include "glcanvas.h"
 | 
						|
#include "wx/utils.h"
 | 
						|
#include "wx/app.h"
 | 
						|
 | 
						|
#include <Xm/Xm.h>
 | 
						|
#include "wx/motif/private.h"
 | 
						|
 | 
						|
#ifdef OLD_MESA
 | 
						|
// workaround for bug in Mesa's glx.c
 | 
						|
static int bitcount( unsigned long n )
 | 
						|
{
 | 
						|
    int bits;
 | 
						|
    for (bits=0; n>0;) {
 | 
						|
	if(n & 1) bits++;
 | 
						|
	n = n >> 1;
 | 
						|
    }
 | 
						|
    return bits;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * GLCanvas implementation
 | 
						|
 */
 | 
						|
 | 
						|
IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
 | 
						|
 | 
						|
wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos,
 | 
						|
  const wxSize& size, long style, 
 | 
						|
  const wxString& name, int *attrib_list, const wxPalette& palette):
 | 
						|
    wxScrolledWindow(parent, id, pos, size, style, name)
 | 
						|
{
 | 
						|
    XVisualInfo *vi, vi_templ;
 | 
						|
    XWindowAttributes xwa;
 | 
						|
    int val, n;
 | 
						|
 | 
						|
    Display* display = (Display*) GetXDisplay();
 | 
						|
 | 
						|
    glx_cx = 0;
 | 
						|
    // Check for the presence of the GLX extension
 | 
						|
    if(!glXQueryExtension(display, NULL, NULL)) {
 | 
						|
	wxDebugMsg("wxGLCanvas: GLX extension is missing\n");
 | 
						|
	return;
 | 
						|
    }
 | 
						|
 | 
						|
    if(attrib_list) {
 | 
						|
	// Get an appropriate visual
 | 
						|
	vi = glXChooseVisual(display, DefaultScreen(display), attrib_list);
 | 
						|
	if(!vi) return;
 | 
						|
 | 
						|
	// Here we should make sure that vi is the same visual as the
 | 
						|
	// one used by the xwindow drawable in wxCanvas.  However,
 | 
						|
	// there is currently no mechanism for this in wx_canvs.cc.
 | 
						|
    } else {
 | 
						|
	// By default, we use the visual of xwindow
 | 
						|
	XGetWindowAttributes(display, (Window) GetXWindow(), &xwa);
 | 
						|
	vi_templ.visualid = XVisualIDFromVisual(xwa.visual);
 | 
						|
	vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n);
 | 
						|
	if(!vi) return;
 | 
						|
	glXGetConfig(display, vi, GLX_USE_GL, &val);
 | 
						|
	if(!val) return;
 | 
						|
	// Basically, this is it.  It should be possible to use vi
 | 
						|
	// in glXCreateContext() below.  But this fails with Mesa.
 | 
						|
	// I notified the Mesa author about it; there may be a fix.
 | 
						|
#ifdef OLD_MESA
 | 
						|
	// Construct an attribute list matching the visual
 | 
						|
	int a_list[32];
 | 
						|
	n = 0;
 | 
						|
	if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual
 | 
						|
	    a_list[n++] = GLX_RGBA;
 | 
						|
	    a_list[n++] = GLX_RED_SIZE;
 | 
						|
	    a_list[n++] = bitcount(vi->red_mask);
 | 
						|
	    a_list[n++] = GLX_GREEN_SIZE;
 | 
						|
	    a_list[n++] = bitcount(vi->green_mask);
 | 
						|
	    a_list[n++] = GLX_BLUE_SIZE;
 | 
						|
	    a_list[n++] = bitcount(vi->blue_mask);
 | 
						|
	    glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val);
 | 
						|
	    a_list[n++] = GLX_ALPHA_SIZE;
 | 
						|
	    a_list[n++] = val;
 | 
						|
	} else { // Color index visual
 | 
						|
	    glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val);
 | 
						|
	    a_list[n++] = GLX_BUFFER_SIZE;
 | 
						|
	    a_list[n++] = val;
 | 
						|
	}
 | 
						|
	a_list[n] = None;
 | 
						|
	XFree(vi);
 | 
						|
	vi = glXChooseVisual(display, DefaultScreen(display), a_list);
 | 
						|
	if(!vi) return;
 | 
						|
#endif /* OLD_MESA */
 | 
						|
    }
 | 
						|
 | 
						|
    // Create the GLX context and make it current
 | 
						|
    glx_cx = glXCreateContext(display, vi, 0, GL_TRUE);
 | 
						|
#ifndef OLD_MESA
 | 
						|
    XFree(vi);
 | 
						|
#endif
 | 
						|
    SetCurrent();
 | 
						|
}
 | 
						|
 | 
						|
wxGLCanvas::~wxGLCanvas(void)
 | 
						|
{
 | 
						|
    Display* display = (Display*) GetXDisplay();
 | 
						|
    if(glx_cx) glXDestroyContext(display, glx_cx);
 | 
						|
}
 | 
						|
 | 
						|
void wxGLCanvas::SwapBuffers()
 | 
						|
{
 | 
						|
    Display* display = (Display*) GetXDisplay();
 | 
						|
    if(glx_cx) glXSwapBuffers(display, (Window) GetXWindow());
 | 
						|
}
 | 
						|
 | 
						|
void wxGLCanvas::SetCurrent()
 | 
						|
{
 | 
						|
    Display* display = (Display*) GetXDisplay();
 | 
						|
    if(glx_cx) glXMakeCurrent(display, (Window) GetXWindow(), glx_cx);
 | 
						|
}
 | 
						|
 | 
						|
void wxGLCanvas::SetColour(const char *col)
 | 
						|
{
 | 
						|
    wxColour *the_colour = wxTheColourDatabase->FindColour(col);
 | 
						|
    if(the_colour) {
 | 
						|
	GLboolean b;
 | 
						|
	glGetBooleanv(GL_RGBA_MODE, &b);
 | 
						|
	if(b) {
 | 
						|
	    glColor3ub(the_colour->Red(),
 | 
						|
		       the_colour->Green(),
 | 
						|
		       the_colour->Blue());
 | 
						|
	} else {
 | 
						|
	    GLint pix = (GLint)the_colour->m_pixel;
 | 
						|
	    if(pix == -1) {
 | 
						|
		XColor exact_def;
 | 
						|
		exact_def.red = (unsigned short)the_colour->Red() << 8;
 | 
						|
		exact_def.green = (unsigned short)the_colour->Green() << 8;
 | 
						|
		exact_def.blue = (unsigned short)the_colour->Blue() << 8;
 | 
						|
		exact_def.flags = DoRed | DoGreen | DoBlue;
 | 
						|
		if(!XAllocColor((Display*) GetXDisplay(), (Colormap) wxTheApp->GetMainColormap(GetXDisplay()), &exact_def)) {
 | 
						|
		    wxDebugMsg("wxGLCanvas: cannot allocate color\n");
 | 
						|
		    return;
 | 
						|
		}
 | 
						|
		pix = the_colour->m_pixel = exact_def.pixel;
 | 
						|
	    }
 | 
						|
	    glIndexi(pix);
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 |