Files
gzz-mirror/Modules/openGL/ZZOpenGLGraphics.cc

475 lines
11 KiB
C++
Raw Normal View History

2026-09-14 20:19:29 -04:00
/****************************************************
* INCLUDES
****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
// #include <iconv.h>
#include <math.h>
extern "C"{
#include "jni.h"
}
#include "fi_iki_lukka_ZZOpenGLGraphics.h"
#include "gltt/FTEngine.h"
#include "gltt/FTFace.h"
#include "gltt/FTInstance.h"
#include "gltt/FTGlyph.h"
#include "gltt/FTGlyphBitmap.h"
#include "gltt/FTGlyphPixmap.h"
#include "gltt/FTBitmapFont.h"
#include "gltt/GLTTBitmapFont.h"
#include "gltt/GLTTPixmapFont.h"
#include "gltt/GLTTOutlineFont.h"
#include "gltt/GLTTFont.h"
#include "gltt/GLTTGlyphPolygonizer.h"
#include "gltt/GLTTGlyphTriangulator.h"
#include <GL/glx.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <X11/Xatom.h>
#include <X11/Xmu/StdCmap.h>
#include <X11/keysym.h>
/***********************************************
* useful little macros
************************************************/
#define GET_THIS() jclass zzthis = env->GetObjectClass( obj );
#define FIELD_ID(_name, _sig) env->GetFieldID( zzthis, _name, _sig)
#define SET_INT_FIELD(_name, _value) \
env->SetIntField( obj, FIELD_ID(_name, "I"), _value)
#define GET_INT_FIELD(_name) env->GetIntField( obj, FIELD_ID(_name, "I"))
/******************************************************
* GLOBALS
******************************************************/
/* these will be in java class */
Display *disp;
Window win;
/***/
GLboolean db = GL_TRUE; /* doublebuffering */
GLint disp_list = 0;
XSizeHints sizeHints = { 0 };
XEvent event;
GLuint base;
int args[] = { GLX_DOUBLEBUFFER,
GLX_RGBA,
GLX_DEPTH_SIZE,
16,
None };
void makeRasterFont(Display *dpy)
{
XFontStruct *fontInfo;
Font id;
unsigned int first, last;
fontInfo = XLoadQueryFont(dpy,
"-*-courier-medium-r-normal-*-*-100-*-*-m-*-iso8859-1");
if (fontInfo == NULL) {
printf ("no font found\n");
exit (0);
}
id = fontInfo->fid;
first = fontInfo->min_char_or_byte2;
last = fontInfo->max_char_or_byte2;
base = glGenLists(last+1);
if (base == 0) {
printf ("out of display lists\n");
exit (0);
}
glXUseXFont(id, first, last-first+1, base+first);
}
/******************************************************
* printString
******************************************************/
void printString(const char *s)
{
glListBase(base);
glCallLists(strlen(s), GL_UNSIGNED_BYTE, (unsigned char *)s);
}
/******************************************************
* getColormap
******************************************************/
Colormap getColormap ( XVisualInfo *vis){
Status stat;
XStandardColormap *sCm;
Colormap cm;
int i;
int numCmaps;
if ( vis->c_class != TrueColor ){
printf ("No support for TrueColor!");
exit(1);
}
stat = XmuLookupStandardColormap(disp, vis->screen, vis->visualid,
vis->depth,XA_RGB_DEFAULT_MAP, False, True);
if (stat == 1) {
stat = XGetRGBColormaps( disp, RootWindow(disp, vis->screen),
&sCm, &numCmaps,
XA_RGB_DEFAULT_MAP);
if (stat == 1)
for( i = 0; i < numCmaps; i++ )
if( sCm[i].visualid == vis->visualid) {
cm = sCm[i].colormap;
XFree(sCm);
return cm;
}
}
cm = XCreateColormap (disp, RootWindow(disp,vis->screen),
vis->visual, AllocNone);
return cm;
}
/******************************************************
* openWindow
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_openWindow( JNIEnv *env,
jobject obj,
jint width,
jint height)
{
XVisualInfo *vi;
Colormap cm;
XSetWindowAttributes xswa;
XWMHints *wmHints;
Atom wmDeleteWindow;
GLXContext cx;
char *display = NULL;
/** connect to X server **/
disp = XOpenDisplay(display);
// FIX ME
if ( disp == NULL ) exit(1);
printf("__C__: openWindow\n");
/** check for glx */
if ( ! glXQueryExtension(disp, NULL, NULL))
// maybe should use some constants
return;// 2;
/** visual & colormap **/
vi = glXChooseVisual(disp, DefaultScreen(disp),args );
if ( ! vi ){
// no doublebuffering
vi = glXChooseVisual(disp, DefaultScreen(disp),&args[1] );
if ( ! vi ) exit(1);
db = GL_FALSE;
}
cm = getColormap(vi);
/** GL rendering context **/
cx = glXCreateContext(disp, vi, NULL, GL_TRUE);
if ( cx == NULL )
exit(1);
/* some hints etc */
xswa.colormap = cm;
xswa.border_pixel = 0;
xswa.event_mask = ExposureMask|ButtonPressMask|KeyPressMask;
sizeHints.width = width;
sizeHints.height = height;
sizeHints.x = 10;
sizeHints.y = 10;
win = XCreateWindow(disp, RootWindow(disp,vi->screen),
sizeHints.x, sizeHints.y,
width, height, 0, vi->depth, InputOutput,
vi->visual, CWEventMask|CWBorderPixel|CWColormap, &xswa);
wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False);
XSetWMProtocols(disp, win, &wmDeleteWindow,1);
XSetStandardProperties(disp, win, "test", "Testi",
None, None, None, &sizeHints);
wmHints = XAllocWMHints();
wmHints->initial_state = NormalState;
wmHints->flags = StateHint;
XSetWMHints(disp, win, wmHints);
/* bind context to window */
glXMakeCurrent(disp, win, cx);
glEnable ( GL_DEPTH_TEST );
glEnable ( GL_ALPHA_TEST );
glDisable ( GL_DITHER );
glDisable ( GL_LIGHTING );
glDisable ( GL_FOG );
glDisable ( GL_TEXTURE_2D );
glDisable ( GL_CULL_FACE );
glDisable ( GL_SCISSOR_TEST );
glDisable ( GL_STENCIL_TEST );
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65, (GLfloat) width
/ (GLfloat) height, 1, 1000);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(0, 0, 100, 0, 0, 0, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
XMapWindow(disp,win);
glXSwapBuffers(disp, win);
makeRasterFont(disp);
}
/******************************************************
* drawLine
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawLine(JNIEnv *env, jobject obj,
jint x1, jint y1,
jint x2, jint y2){
printf("__C__: drawLine\n");
glBegin(GL_LINES);
glVertex3d( x1, y1, 0 );
glVertex3d( x2, y2, 0 );
glEnd();
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawRect(JNIEnv *env, jobject obj,
jint x, jint y,
jint width, jint height){
printf("__C__: drawRect\n");
glBegin(GL_QUADS);
glVertex3d( x, y, 0 );
glVertex3d( x, y+height, 0 );
glVertex3d( x+width, y+height, 0 );
glVertex3d( x+width, y, 0 );
glEnd();
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawPoint(JNIEnv *env, jobject obj,
jint x, jint y);
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawText(JNIEnv *env, jobject obj,
jint x, jint y,
jstring text, jint size){
int s;
//int l;
const char *str = (const char *)env->GetStringUTFChars( text, 0 );
printf("str = %s\n", str);
s = env->GetStringLength( text);
// Check the size
printf("s = %d\n", s);
glLoadIdentity();
/*
//
// glut stroke fonts
glTranslatef(x,y,0);
glScalef(0.03,0.03,0.03);
for(l = 0; l < s; l++){
glutStrokeCharacter(GLUT_STROKE_ROMAN , str[l]);
glTranslatef(glutStrokeWidth(GLUT_STROKE_ROMAN,str[l]),0,0);
}
*/
printf("__C__: drawText\n");
//glColor3f(1,1,1);
glLoadIdentity();
FTFace face;
if( ! face.open("/dos/winnt/Fonts/couri.ttf") ){
printf("unable to open ttf file");
return ;
}
GLTTOutlineFont font(&face);
int point_size= size;
if( ! font.create(point_size) ){
printf("unable to create outline font");
return ;
}
glTranslatef(x,y,0);
//glRotatef(45,0,1,0);
//font.setPrecision(4);
font.output( str );
// bitmap fonts
//printString(str);
glLoadIdentity();
env->ReleaseStringUTFChars( text, 0);
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawingColor(JNIEnv *env, jobject obj,
jdouble r, jdouble g,
jdouble b, jdouble a){
glColor4d(r,g,b,a);
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawArrow(JNIEnv *env, jobject obj,
jint x, jint y,
jint dx, jint dy,
jint dz){
glLoadIdentity();
glScalef(dx,dy,dz);
glBegin(GL_LINES);
glVertex3f(x,y,0);
glVertex3f(x,y-1,0);
glVertex3f(x,y,0);
glVertex3f(x+2,y-2,0);
glVertex3f(x,y,0);
glVertex3f(x+1,y,0);
glEnd();
glLoadIdentity();
}
/******************************************************
* swapBuffers
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_swapBuffers(JNIEnv *env,
jobject obj){
printf("__C__: swapBuffers\n");
glXSwapBuffers(disp,win);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
}
/******************************************************
* checkEvents
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_checkEvents( JNIEnv *env, jobject obj){
XKeyEvent *e_key;
XButtonEvent *e_but;
XConfigureEvent *e_conf;
jclass cls = env->GetObjectClass( obj );
jmethodID key_id = env->GetMethodID( cls,
"addKeyEvent", "(II)V");
jmethodID button_id = env->GetMethodID( cls,
"addButtonEvent", "(IIII)V");
jmethodID conf_id = env->GetMethodID( cls,
"configureEvent", "(II)V");
printf("__C__: Check events\n");
if ( button_id == 0 || key_id == 0 ) {
printf ("no method id\n");
return ;
}
do{
int ch;
int type = 0;
XEvent event;
XNextEvent(disp, &event);
switch ( event.type ){
case ConfigureNotify:
printf("ConfNotify");
env->CallVoidMethod( obj, conf_id,
e_conf->width, e_conf->height);
break;
case ButtonPress:
e_but = (XButtonEvent *) &event;
env->CallVoidMethod( obj, button_id,
e_but->button, e_but->x, e_but->y, 0);
break;
case KeyPress:
e_key = (XKeyEvent *) &event;
ch = (int )XLookupKeysym(e_key,0);
env->CallVoidMethod( obj, key_id, ch, type);
break;
default:
;
}
} while( XPending( disp ) );
return ;
}