GLw demo doesn't belong here
This commit is contained in:
parent
17756df903
commit
334f2d8077
|
@ -1,451 +0,0 @@
|
|||
/*
|
||||
|
||||
BOILERPLATE
|
||||
|
||||
To get started with mixed model programming with Motif and OpenGL, this
|
||||
boilerplate `application' might help get you started.
|
||||
|
||||
This program honors two environment variables:
|
||||
|
||||
SETVISUAL <id> Makes the application use the indicated visual,
|
||||
instead of the one chosen by glxChooseVisual.
|
||||
|
||||
SAMEVISUAL Make the application use the same visual for the
|
||||
GUI as for the 3D GL Widget.
|
||||
|
||||
The basic idea is to minimize colormap `flash' on systems with only one
|
||||
hardware colormap, especially when focus shifts between several
|
||||
of the application's windows, e.g. the about box.
|
||||
|
||||
If you have suggestions for improvements, please mail to:
|
||||
|
||||
|
||||
Jeroen van der Zijp <jvz@cyberia.cfdrc.com>
|
||||
|
||||
|
||||
Feel free to turn this into a useful program!!
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This code is hereby placed under GNU GENERAL PUBLIC LICENSE.
|
||||
Copyright (C) 1996 Jeroen van der Zijp <jvz@cyberia.cfdrc.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/* Include the kitchen sink */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/MainW.h>
|
||||
#include <Xm/RowColumn.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/CascadeB.h>
|
||||
#include <Xm/BulletinB.h>
|
||||
#include <Xm/DialogS.h>
|
||||
#include <Xm/Frame.h>
|
||||
#include <Xm/MessageB.h>
|
||||
#include <Xm/Form.h>
|
||||
#include <Xm/Separator.h>
|
||||
#include <Xm/MwmUtil.h>
|
||||
|
||||
/* Now some good stuff */
|
||||
#include <GLwMDrawA.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
|
||||
/* Stuff */
|
||||
Display *display;
|
||||
Visual *gui_visual;
|
||||
Colormap gui_colormap;
|
||||
Colormap gl_colormap;
|
||||
XVisualInfo *gl_visualinfo;
|
||||
XtAppContext app_context;
|
||||
Widget toplevel;
|
||||
Widget mainwindow;
|
||||
Widget menubar;
|
||||
Widget mainform;
|
||||
Widget mainframe;
|
||||
Widget glwidget;
|
||||
Widget button;
|
||||
Widget separator;
|
||||
GLXContext glx_context;
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define c_class class
|
||||
#endif
|
||||
|
||||
/* Requested attributes; fix as you see fit */
|
||||
static int glxConfig[]={
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 16,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
None
|
||||
};
|
||||
|
||||
|
||||
/* Forwards */
|
||||
static void exposeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
|
||||
static void initCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
|
||||
static void resizeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
|
||||
static void inputCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
|
||||
static void byeCB(Widget w,XtPointer client_data,XtPointer call_data);
|
||||
static void aboutCB(Widget w,XtPointer client_data,XtPointer call_data);
|
||||
static char* showvisualclass(int cls);
|
||||
|
||||
|
||||
|
||||
/* Sample application */
|
||||
int main(int argc, char *argv[]){
|
||||
char *thevisual;
|
||||
XVisualInfo vi;
|
||||
int nvisinfos,visid,n;
|
||||
Arg args[30];
|
||||
Widget pane,cascade,but;
|
||||
|
||||
/*
|
||||
** Initialize toolkit
|
||||
** We do *not* use XtAppInitialize as we want to figure visual and
|
||||
** colormap BEFORE we create the top level shell!!!
|
||||
*/
|
||||
XtToolkitInitialize();
|
||||
|
||||
/* Make application context */
|
||||
app_context=XtCreateApplicationContext();
|
||||
|
||||
/* Try open display */
|
||||
display=XtOpenDisplay(app_context,NULL,"boilerPlate","BoilerPlate",NULL,0,&argc,argv);
|
||||
|
||||
/* Report failure */
|
||||
if(!display){
|
||||
fprintf(stderr,"Unable to open the specified display.\n");
|
||||
fprintf(stderr,"Set your `DISPLAY' environment variable properly or\n");
|
||||
fprintf(stderr,"use the `xhost' command to authorize access to the display.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check for extension; for Mesa, this is always cool */
|
||||
if(!glXQueryExtension(display,NULL,NULL)){
|
||||
fprintf(stderr,"The specified display does not support the OpenGL extension\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Init with default visual and colormap */
|
||||
gui_visual=DefaultVisual(display,0);
|
||||
gui_colormap=DefaultColormap(display,0);
|
||||
gl_colormap=DefaultColormap(display,0);
|
||||
|
||||
/* User insists on a specific visual */
|
||||
if((thevisual=getenv("SETVISUAL"))!=NULL){
|
||||
if(sscanf(thevisual,"%x",&visid)==1){
|
||||
vi.visualid=visid;
|
||||
gl_visualinfo=XGetVisualInfo(display,VisualIDMask,&vi,&nvisinfos);
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"Please set the `SETVISUAL' variable in hexadecimal\n");
|
||||
fprintf(stderr,"Use one of the Visual ID's reported by `xdpyinfo'\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find visual the regular way */
|
||||
else{
|
||||
gl_visualinfo=glXChooseVisual(display,DefaultScreen(display),glxConfig);
|
||||
}
|
||||
|
||||
/* Make sure we have a visual */
|
||||
if(!gl_visualinfo){
|
||||
fprintf(stderr,"Unable to obtain visual for graphics\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Show what visual is being used */
|
||||
fprintf(stderr,"Using the following visual:\n");
|
||||
fprintf(stderr," visualid: %lx\n",gl_visualinfo->visualid);
|
||||
fprintf(stderr," depth: %d\n",gl_visualinfo->depth);
|
||||
fprintf(stderr," screen: %d\n",gl_visualinfo->screen);
|
||||
fprintf(stderr," bits/rgb: %d\n",gl_visualinfo->bits_per_rgb);
|
||||
fprintf(stderr," class: %s\n",showvisualclass(gl_visualinfo->c_class));
|
||||
|
||||
/*
|
||||
** If not using default visual, we need a colormap for this visual.
|
||||
** Yes, the GL widget can allocate one itself, but we want to make
|
||||
** sure the GUI and the 3D have the same one (if hardware does not
|
||||
** allow more than one simultaneously).
|
||||
** This prevents nasty flashing when the window with the 3D widget
|
||||
** looses the focus.
|
||||
*/
|
||||
if(gl_visualinfo->visual!=DefaultVisual(display,0)){
|
||||
fprintf(stderr,"Making another colormap\n");
|
||||
gl_colormap=XCreateColormap(display,
|
||||
RootWindow(display,0),
|
||||
gl_visualinfo->visual,
|
||||
AllocNone);
|
||||
if(!gl_colormap){
|
||||
fprintf(stderr,"Unable to create private colormap\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Use common visual for GUI and GL?
|
||||
** Maybe you can invoke some hardware interrogation function and
|
||||
** see if more than one hardware map is supported. For the purpose
|
||||
** of this demo, we'll use an environment variable instead.
|
||||
*/
|
||||
if(getenv("SAMEVISUAL")!=NULL){
|
||||
gui_visual=gl_visualinfo->visual;
|
||||
gui_colormap=gl_colormap;
|
||||
}
|
||||
|
||||
fprintf(stderr,"GUI uses visual: %lx\n",XVisualIDFromVisual(gui_visual));
|
||||
|
||||
/* Create application shell, finally */
|
||||
n=0;
|
||||
XtSetArg(args[n],XmNvisual,gui_visual); n++; /* Plug in that visual */
|
||||
XtSetArg(args[n],XmNcolormap,gui_colormap); n++; /* And that colormap */
|
||||
toplevel=XtAppCreateShell("boilerPlate","BoilerPlate",
|
||||
applicationShellWidgetClass,display,args,n);
|
||||
|
||||
|
||||
/* Main window */
|
||||
n=0;
|
||||
mainwindow=XmCreateMainWindow(toplevel,"window",args,n);
|
||||
XtManageChild(mainwindow);
|
||||
|
||||
/* Make a menu */
|
||||
n=0;
|
||||
XtSetArg(args[n],XmNmarginWidth,0); n++;
|
||||
XtSetArg(args[n],XmNmarginHeight,0); n++;
|
||||
menubar=XmCreateMenuBar(mainwindow,"menubar",args,2);
|
||||
XtManageChild(menubar);
|
||||
|
||||
n=0;
|
||||
pane=XmCreatePulldownMenu(menubar,"pane",args,n);
|
||||
n=0;
|
||||
but=XmCreatePushButton(pane,"Open",args,n);
|
||||
XtManageChild(but);
|
||||
but=XmCreatePushButton(pane,"Save",args,n);
|
||||
XtManageChild(but);
|
||||
but=XmCreatePushButton(pane,"Save As",args,n);
|
||||
XtManageChild(but);
|
||||
but=XmCreatePushButton(pane,"Quit",args,n);
|
||||
XtAddCallback(but,XmNactivateCallback,byeCB,(XtPointer)NULL);
|
||||
XtManageChild(but);
|
||||
XtSetArg(args[0],XmNsubMenuId,pane);
|
||||
cascade=XmCreateCascadeButton(menubar,"File",args,1);
|
||||
XtManageChild(cascade);
|
||||
|
||||
n=0;
|
||||
pane=XmCreatePulldownMenu(menubar,"pane",args,n);
|
||||
n=0;
|
||||
but=XmCreatePushButton(pane,"About",args,n);
|
||||
XtAddCallback(but,XmNactivateCallback,aboutCB,(XtPointer)NULL);
|
||||
XtManageChild(but);
|
||||
XtSetArg(args[0],XmNsubMenuId,pane);
|
||||
cascade=XmCreateCascadeButton(menubar,"Help",args,1);
|
||||
XtManageChild(cascade);
|
||||
XtVaSetValues(menubar,XmNmenuHelpWidget,cascade,NULL);
|
||||
|
||||
/* Main window form */
|
||||
n=0;
|
||||
XtSetArg(args[n],XmNmarginWidth,5); n++;
|
||||
XtSetArg(args[n],XmNmarginHeight,5); n++;
|
||||
mainform=XmCreateForm(mainwindow,"mainForm",args,n);
|
||||
XtManageChild(mainform);
|
||||
|
||||
/* Some nice button */
|
||||
n=0;
|
||||
XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM); n++;
|
||||
XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
|
||||
button=XmCreatePushButton(mainform,"Bye",args,n);
|
||||
XtAddCallback(button,XmNactivateCallback,byeCB,(XtPointer)NULL);
|
||||
XtManageChild(button);
|
||||
|
||||
n=0;
|
||||
XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM); n++;
|
||||
XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
|
||||
XtSetArg(args[n],XmNbottomAttachment,XmATTACH_WIDGET); n++;
|
||||
XtSetArg(args[n],XmNbottomWidget,button); n++;
|
||||
XtSetArg(args[n],XmNshadowType,XmSHADOW_ETCHED_IN); n++;
|
||||
separator=XmCreateSeparator(mainform,"separator",args,n);
|
||||
XtManageChild(separator);
|
||||
|
||||
/* Main window frame */
|
||||
n = 0;
|
||||
XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM); n++;
|
||||
XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
|
||||
XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM); n++;
|
||||
XtSetArg(args[n],XmNbottomAttachment,XmATTACH_WIDGET); n++;
|
||||
XtSetArg(args[n],XmNbottomWidget,separator); n++;
|
||||
XtSetArg(args[n],XmNshadowType,XmSHADOW_IN); n++;
|
||||
mainframe = XmCreateFrame(mainform,"mainFrame",args,n);
|
||||
XtManageChild(mainframe);
|
||||
|
||||
/* GL drawing area */
|
||||
n = 0;
|
||||
XtSetArg(args[n],XmNcolormap,gl_colormap); n++;
|
||||
XtSetArg(args[n],GLwNvisualInfo,gl_visualinfo); n++;
|
||||
XtSetArg(args[n],GLwNinstallColormap,True); n++;
|
||||
XtSetArg(args[n],XmNtraversalOn,True); n++;
|
||||
XtSetArg(args[n],XmNwidth,400); n++;
|
||||
XtSetArg(args[n],XmNheight,300); n++;
|
||||
glwidget = GLwCreateMDrawingArea(mainframe,"glWidget",args,n);
|
||||
XtAddCallback(glwidget,GLwNexposeCallback,(XtCallbackProc)exposeCB,(XtPointer)NULL);
|
||||
XtAddCallback(glwidget,GLwNresizeCallback,(XtCallbackProc)resizeCB,(XtPointer)NULL);
|
||||
XtAddCallback(glwidget,GLwNginitCallback,(XtCallbackProc)initCB,(XtPointer)NULL);
|
||||
XtAddCallback(glwidget,GLwNinputCallback,(XtCallbackProc)inputCB,(XtPointer)NULL);
|
||||
XtManageChild(glwidget);
|
||||
|
||||
/* Set into main window */
|
||||
XmMainWindowSetAreas(mainwindow,menubar,NULL,NULL,NULL,mainform);
|
||||
XtRealizeWidget(toplevel);
|
||||
|
||||
/* Loop until were done */
|
||||
XtAppMainLoop(app_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Show visual class */
|
||||
static char* showvisualclass(int cls){
|
||||
if(cls==TrueColor) return "TrueColor";
|
||||
if(cls==DirectColor) return "DirectColor";
|
||||
if(cls==PseudoColor) return "PseudoColor";
|
||||
if(cls==StaticColor) return "StaticColor";
|
||||
if(cls==GrayScale) return "GrayScale";
|
||||
if(cls==StaticGray) return "StaticGray";
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
|
||||
static void exposeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
|
||||
GLwDrawingAreaMakeCurrent(glwidget,glx_context);
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
glLoadIdentity();
|
||||
glOrtho(-1.0,1.0,-1.0,1.0,0.0,1.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glLoadIdentity();
|
||||
|
||||
glColor3f(1.0,0.0,0.0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-1.0,-1.0,0.0);
|
||||
glVertex3f( 1.0, 1.0,0.0);
|
||||
glEnd();
|
||||
glXSwapBuffers(display,XtWindow(glwidget));
|
||||
}
|
||||
|
||||
|
||||
/* Initialize widget */
|
||||
static void initCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
|
||||
|
||||
/* First, create context. We prefer direct rendering */
|
||||
glx_context=glXCreateContext(display,gl_visualinfo,0,TRUE);
|
||||
if(!glx_context){
|
||||
fprintf(stderr,"Unable to create gl context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Make it current */
|
||||
GLwDrawingAreaMakeCurrent(glwidget,glx_context);
|
||||
|
||||
/* Set a viewport */
|
||||
glViewport(0,0,cbs->width,cbs->height);
|
||||
|
||||
/* You might want to do a lot more here ... */
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glClearColor(1.0,1.0,1.0,1.0);
|
||||
glClearDepth(1.0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Widget changed size, so adjust txform */
|
||||
static void resizeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
|
||||
GLwDrawingAreaMakeCurrent(glwidget,glx_context);
|
||||
glViewport(0,0,cbs->width,cbs->height);
|
||||
|
||||
/* blablabla */
|
||||
}
|
||||
|
||||
|
||||
/* Boilerplate event handling */
|
||||
static void inputCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
|
||||
switch(cbs->event->type){
|
||||
case ButtonPress:
|
||||
switch(cbs->event->xbutton.button){
|
||||
case Button1: fprintf(stderr,"Pressed 1\n"); break;
|
||||
case Button2: fprintf(stderr,"Pressed 2\n"); break;
|
||||
case Button3: fprintf(stderr,"Pressed 3\n"); break;
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
switch(cbs->event->xbutton.button){
|
||||
case Button1: fprintf(stderr,"Released 1\n"); break;
|
||||
case Button2: fprintf(stderr,"Released 2\n"); break;
|
||||
case Button3: fprintf(stderr,"Released 3\n"); break;
|
||||
}
|
||||
break;
|
||||
case MotionNotify:
|
||||
fprintf(stderr,"Moved mouse to (%d %d)\n",
|
||||
cbs->event->xbutton.x,
|
||||
cbs->event->xbutton.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Hasta la vista, baby */
|
||||
static void byeCB(Widget w,XtPointer client_data,XtPointer call_data){
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/* Pop informative panel */
|
||||
static void aboutCB(Widget w,XtPointer client_data,XtPointer call_data){
|
||||
Arg args[10];
|
||||
XmString str;
|
||||
Widget box;
|
||||
str=XmStringCreateLtoR("Boilerplate Mixed Model Programming Example\n\n (C) 1996 Jeroen van der Zijp \n\n jvz@cyberia.cfdrc.com",XmSTRING_DEFAULT_CHARSET);
|
||||
XtSetArg(args[0],XmNnoResize,True);
|
||||
XtSetArg(args[1],XmNautoUnmanage,True);
|
||||
XtSetArg(args[2],XmNmessageString,str);
|
||||
XtSetArg(args[3],XmNdefaultPosition,False);
|
||||
box=XmCreateInformationDialog(toplevel,"About Boilerplate",args,4);
|
||||
XtManageChild(box);
|
||||
XtUnmanageChild(XmMessageBoxGetChild(box,XmDIALOG_HELP_BUTTON));
|
||||
XtUnmanageChild(XmMessageBoxGetChild(box,XmDIALOG_CANCEL_BUTTON));
|
||||
XmStringFree(str);
|
||||
}
|
Loading…
Reference in New Issue