Re: [gtk-list] Re: Using Mesa (openGL) with GTK
- From: Ivo Clarysse <soggie riv be>
- To: gtk-list redhat com
- Subject: Re: [gtk-list] Re: Using Mesa (openGL) with GTK
- Date: Tue, 4 Nov 1997 11:57:39 +0100 (MET)
On Tue, 4 Nov 1997, Ivo Clarysse wrote:
> On Sun, 19 Oct 1997, Bj|rn Augustsson wrote:
>
> > Juergen A. Erhard (jae@laden.ilk.de) wrote:
> > >It works for me after changing dbuf in gui_init to start with GL_RGBA
> > >and put the GLX_DOUBLEBUFFER at the end. Took me a couple minutes, and
> > >comparing with glxdemo.c in Mesa 2.3...
> >
> > I also inserted GLX_RGBA, but doing just that that doesn't work well at
> > all, since the toplevel widget gets the default visual (In my case
> > PseudoColor 8), and then the program tries to attach the TrueColor 24
> > visualled glarea widget to it.
> >
> > The results are some pretty nasty kernel messages about failed asserts
> > and the GL rendering seems to be in black&white. (not grayscale, B&W)
> >
> > This should really be possible to do, as it seems there is an OpenGL
> > widget for motif that can do it. (As seen in Mark Kilgards excellent
> > article from the X Journal, which can be found at
> > http://www.sgi.com/Technology/openGL/mjk.motif/ )
> > I don't know how though.
OK, I played around a bit, and I think I've got it. The following
code works both on my Linux box (8-bit display) using Mesa, as
on a SGI box with 32-bit display and true OpenGL. It only uses a
TrueColor visual for the OpenGL stuff, the rest is in whatever
visual GTK decides it wants. (I must say, the gtk_widget_{push|pop}_visual
semantics are not very intuitive, it doesn't really 'push' the
argument, but pushes the current value and replaces it with the
argument).
Instead of using 'gtk_preview_get_visual', I use 'glXChooseVisual'.
The gtk_preview_get_visual returns (AFAIK) a visual which gtk_preview
would like to use should it be created. Mostly this is something
with 24-bit color. On my SGI box, however, it returned a 24-bit color
visual, but not one which SGI's OpenGL is happy to render into.
Anyway, here goes:
----8<------8<------8<------------
/*
* glgtk.c
*
* Release: 971104-2
*
* Displays a rotating triangle with Open/GL | Mesa
*
*/
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h> /* A clean way to get to GDK's private parts */
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
int redraw_needed=TRUE;
Display *dpy=NULL;
GLXContext glx_context;
GLfloat cam_xspin=0.0;
GLfloat cam_yspin=0.0;
GLfloat cam_zspin=0.0;
GLfloat cam_xpos=0.0;
GLfloat cam_ypos=0.0;
GLfloat cam_zpos=-4.0;
GtkWidget *glarea;
void object_redraw();
gint timer_callback(gpointer data)
{
cam_zspin+=4;
cam_xspin+=1;
redraw_needed=TRUE;
object_redraw(); /* Redraw object if needed */
return(TRUE);
}
/* Define model in displaylist */
void object_define()
{
glNewList(1, GL_COMPILE_AND_EXECUTE);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP);
glVertex3f(-1, 0, 0);
glVertex3f( 0, -1, 0);
glVertex3f( 1, -1, 0);
glEnd();
glEndList();
}
void object_redraw()
{
static int list_inited=FALSE;
if (!redraw_needed) return;
glXMakeCurrent(dpy,GDK_WINDOW_XWINDOW(glarea->window),glx_context);
glShadeModel(GL_FLAT);
glClearColor(0.0,0.0,0.0,0.0);
glColor3f(1.0, 1.0, 1.0);
glLineWidth(1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(cam_xpos, cam_ypos, cam_zpos);
glRotatef(cam_xspin, 1.0, 0.0, 0.0); /* rotate modelmatrix */
glRotatef(cam_yspin, 0.0, 1.0, 0.0); /* rotate modelmatrix */
glRotatef(cam_zspin, 0.0, 0.0, 1.0); /* rotate modelmatrix */
if (list_inited) glCallList(1);
else {
object_define();
list_inited=TRUE;
}
glFlush();
glXSwapBuffers(dpy,GDK_WINDOW_XWINDOW(glarea->window));
redraw_needed=FALSE;
}
/*
* Callback function for 'Quit' button
*
*/
void quit_button(GtkWidget *widget, gpointer *data)
{
gtk_main_quit();
}
/*
* Callback for GTK events in glarea
*
*/
gint glarea_events(GtkWidget *area, GdkEvent *event)
{
GdkEventConfigure *configevent;
switch (event->type) {
case GDK_EXPOSE:
redraw_needed=TRUE;
object_redraw();
break;
case GDK_CONFIGURE: /* aka Resize */
redraw_needed=TRUE;
configevent=(GdkEventConfigure *)event;
/* Resize OpenGL context in glarea */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glViewport(0, 0, configevent->width, configevent->height);
glMatrixMode(GL_MODELVIEW);
break;
default:
break;
}
return (FALSE);
}
void gui_init()
{
gint TimerTag;
GtkWidget *appwindow, *vbox, *button;
XVisualInfo *vi;
int dbuf[] = {GLX_RGBA,GLX_RED_SIZE,1,GLX_GREEN_SIZE,1,
GLX_BLUE_SIZE,1,GLX_DOUBLEBUFFER,None};
/* Look for a visual that OpenGL is happy with.. */
dpy=GDK_DISPLAY();
vi=glXChooseVisual(dpy,DefaultScreen(dpy),dbuf);
if (vi==NULL) { fprintf(stderr,"ERROR: Could not find a visual OpenGL likes.\n"); exit(-1); }
if (vi->class != TrueColor) printf("Non-TrueColor visual selected\n");
printf("Selected OpenGL visual = 0x%x\n",(unsigned int)(vi->visualid));
/* Define GTK's window */
appwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(appwindow), "GL-GTK Test");
vbox=gtk_vbox_new(FALSE,0);
/* Upper row */
/* replace current colormap and visual by one OpenGL/Mesa is happy with */
gtk_widget_push_colormap(
gdk_colormap_new(gdkx_visual_get(vi->visualid),TRUE));
gtk_widget_push_visual(gdkx_visual_get(vi->visualid));
glarea = gtk_drawing_area_new();
gtk_drawing_area_size(GTK_DRAWING_AREA(glarea),300,300);
gtk_widget_set_events(glarea,GDK_EXPOSURE_MASK);
gtk_signal_connect(GTK_OBJECT(glarea), "event", (GtkSignalFunc)glarea_events, NULL);
gtk_box_pack_start(GTK_BOX(vbox), glarea, FALSE, FALSE, 0);
gtk_widget_show(glarea);
/* Now switch back to the original colormap and visual */
gtk_widget_pop_visual();
gtk_widget_pop_colormap();
/* Lower row */
button=gtk_button_new_with_label("Quit");
gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(quit_button), NULL);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
gtk_widget_show(button);
/* ** */
gtk_widget_show(vbox);
gtk_container_add(GTK_CONTAINER(appwindow),vbox);
gtk_widget_show(appwindow);
/* Initialize OpenGL */
glx_context = glXCreateContext(dpy,vi,None,GL_TRUE);
if (glx_context==NULL) { fprintf(stderr,"ERROR: Could not create context\n"); exit(-1); }
/* Initialize OpenGL context for rendering */
glXMakeCurrent(dpy,GDK_WINDOW_XWINDOW(glarea->window),glx_context);
glShadeModel(GL_FLAT);
glClearColor(0.0,0.0,0.0,0.0);
glColor3f(1.0, 1.0, 1.0);
glLineWidth(1.0);
/* Attach callback to timer */
TimerTag=gtk_timeout_add(50,timer_callback,NULL);
}
/**********************************
*
* Main function - delegate :)
*
**********************************/
int main(int argc, char *argv[])
{
gtk_init (&argc, &argv);
gui_init();
gtk_main();
return 0;
}
----8<------8<------8<------------
I don't know if making a specific OpenGL drawingarea widget is really
useful ? It would only save you about four lines of code for every
(Open|Mesa)GL widget you'd use in your program.
Soggie.
-----------------------------------------------------------------------
Ivo Clarysse <soggie@riv.be>, Riverland Research Group
Research Assistant http://www.riv.be/research/
Excelsiorlaan 42
http://www.riv.be/~soggie/me/ B-1930 Zaventem, Belgium
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]