Просмотр исходного кода

OpenGL support.

tags/v0.99.beta14
Jean-Yves Lamoureux jylam 19 лет назад
Родитель
Сommit
5dc72bc0b1
5 измененных файлов: 422 добавлений и 3 удалений
  1. +18
    -1
      configure.ac
  2. +26
    -1
      src/caca.c
  3. +9
    -0
      src/caca_internals.h
  4. +64
    -0
      src/event.c
  5. +305
    -1
      src/graphics.c

+ 18
- 1
configure.ac Просмотреть файл

@@ -35,6 +35,8 @@ AC_ARG_ENABLE(conio,
[ --enable-conio DOS conio.h graphics support (autodetected)])
AC_ARG_ENABLE(x11,
[ --enable-x11 X11 support (autodetected)])
AC_ARG_ENABLE(gl,
[ --enable-gl OpenGL support (autodetected)])

dnl example programs features
AC_ARG_ENABLE(imlib2,
@@ -123,6 +125,19 @@ if test "${enable_x11}" != "no"; then
fi
fi

if test "${enable_gl}" != "no"; then
ac_cv_my_have_gl="no"
AC_CHECK_HEADERS(GL/gl.h GL/glut.h,
[AC_CHECK_LIB(glut, glutMainLoopEvent,
[ac_cv_my_have_gl="yes"
AC_DEFINE(USE_GL, 1, Define to activate the OpenGL backend driver)
CACA_LIBS="${CACA_LIBS} -lGL -lglut"
CACA_DRIVERS="${CACA_DRIVERS} gl"])])
if test "${ac_cv_my_have_gl}" = "no" -a "${enable_gl}" = "yes"; then
AC_MSG_ERROR([cannot find OpenGL+FreeGLUT development files])
fi
fi

if test "${enable_ncurses}" != "no"; then
ac_cv_my_have_ncurses="no"
AC_CHECK_HEADERS(curses.h ncurses.h,
@@ -155,7 +170,9 @@ AC_SUBST(CACA_LIBS)
# Optimizations
CFLAGS="${CFLAGS} -g -O2 -fno-strength-reduce -fomit-frame-pointer"
# Code qui fait des warnings == code de porc == deux baffes dans ta gueule
CFLAGS="${CFLAGS} -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wstrict-prototypes -Wshadow -Waggregate-return -Wmissing-prototypes -Wnested-externs -Wsign-compare"
# [Jylam] Removed -Wshadow in order to avoid ncurses/gl conflict
# (Comme quoi on est pas les seuls porcs)
CFLAGS="${CFLAGS} -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wstrict-prototypes -Waggregate-return -Wmissing-prototypes -Wnested-externs -Wsign-compare"

# Build the PIC library?
case "${target_os}" in


+ 26
- 1
src/caca.c Просмотреть файл

@@ -55,7 +55,9 @@
#if defined(USE_WIN32)
# include <windows.h>
#endif

#if defined(USE_GL)
# include <GL/gl.h>
#endif
#include <stdlib.h>
#include <string.h>

@@ -194,6 +196,13 @@ int caca_init(void)
SetConsoleMode(win32_hout, ENABLE_MOUSE_INPUT);
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
/* Nothing to do */
}
else
#endif
{
/* Dummy */
@@ -425,6 +434,13 @@ void caca_end(void)
CloseHandle(win32_hout);
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
/* Nothing to do */
}
else
#endif
{
/* Dummy */
@@ -458,6 +474,11 @@ static void caca_init_driver(void)
_caca_driver = CACA_DRIVER_X11;
else
#endif
#if defined(USE_GL)
if(!strcasecmp(var, "gl"))
_caca_driver = CACA_DRIVER_GL;
else
#endif
#if defined(USE_SLANG)
if(!strcasecmp(var, "slang"))
_caca_driver = CACA_DRIVER_SLANG;
@@ -491,6 +512,10 @@ static void caca_init_driver(void)
return;
}
#endif
#if defined(USE_GL)
_caca_driver = CACA_DRIVER_GL;
return;
#endif
#if defined(USE_SLANG)
_caca_driver = CACA_DRIVER_SLANG;
return;


+ 9
- 0
src/caca_internals.h Просмотреть файл

@@ -47,6 +47,9 @@ enum caca_driver
#endif
#if defined(USE_WIN32)
CACA_DRIVER_WIN32 = 5,
#endif
#if defined(USE_GL)
CACA_DRIVER_GL = 6,
#endif
CACA_DRIVER_NONE = 0
};
@@ -97,4 +100,10 @@ extern unsigned int x11_new_width, x11_new_height;
extern HANDLE win32_hin, win32_hout;
#endif

#if defined(USE_GL)
#include <GL/glut.h>
extern unsigned int gl_width, gl_height;
#endif


#endif /* __CACA_INTERNALS_H__ */

+ 64
- 0
src/event.c Просмотреть файл

@@ -54,7 +54,18 @@
#if defined(USE_WIN32)
# include <windows.h>
#endif
#if defined(USE_GL)
#include <GL/gl.h>
#include <GL/glut.h>
extern int gl_special_key;
extern unsigned char gl_key;
extern unsigned char gl_resized;
extern float gl_font_width;
extern float gl_font_height;
extern int gl_new_width;
extern int gl_new_height;

#endif
#include "caca.h"
#include "caca_internals.h"

@@ -718,6 +729,59 @@ static unsigned int _lowlevel_event(void)
return CACA_EVENT_NONE;
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
glutMainLoopEvent();

if(gl_resized)
{
if(!_caca_resize)
{


_caca_resize = 1;
gl_resized=0;
return CACA_EVENT_RESIZE;
}
}

if(gl_key!=0)
{
event |= CACA_EVENT_KEY_PRESS;
event |= gl_key;
gl_key = 0;
}

if(gl_special_key != 0)
{
event |= CACA_EVENT_KEY_PRESS;
switch(gl_special_key)
{
case GLUT_KEY_F1 : gl_special_key = 0; return event | CACA_KEY_F1;
case GLUT_KEY_F2 : gl_special_key = 0; return event | CACA_KEY_F2;
case GLUT_KEY_F3 : gl_special_key = 0; return event | CACA_KEY_F3;
case GLUT_KEY_F4 : gl_special_key = 0; return event | CACA_KEY_F4;
case GLUT_KEY_F5 : gl_special_key = 0; return event | CACA_KEY_F5;
case GLUT_KEY_F6 : gl_special_key = 0; return event | CACA_KEY_F6;
case GLUT_KEY_F7 : gl_special_key = 0; return event | CACA_KEY_F7;
case GLUT_KEY_F8 : gl_special_key = 0; return event | CACA_KEY_F8;
case GLUT_KEY_F9 : gl_special_key = 0; return event | CACA_KEY_F9;
case GLUT_KEY_F10 : gl_special_key = 0; return event | CACA_KEY_F10;
case GLUT_KEY_F11 : gl_special_key = 0; return event | CACA_KEY_F11;
case GLUT_KEY_F12 : gl_special_key = 0; return event | CACA_KEY_F12;
case GLUT_KEY_LEFT : gl_special_key = 0; return event | CACA_KEY_LEFT;
case GLUT_KEY_RIGHT: gl_special_key = 0; return event | CACA_KEY_RIGHT;
case GLUT_KEY_UP : gl_special_key = 0; return event | CACA_KEY_UP;
case GLUT_KEY_DOWN : gl_special_key = 0; return event | CACA_KEY_DOWN;
default: return CACA_EVENT_NONE;
}
}
return event;
}
else
#endif
{
/* Dummy */


+ 305
- 1
src/graphics.c Просмотреть файл

@@ -58,7 +58,10 @@
#if defined(USE_WIN32)
# include <windows.h>
#endif

#if defined(USE_GL)
# include <GL/gl.h>
# include <GL/glut.h>
#endif
#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
@@ -232,6 +235,38 @@ static int const win32_bg_palette[] =
BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
};
#endif
#if defined(USE_GL)

static unsigned int const gl_bg_palette[] =
{
0,
0x0000007F,
0x00007F00,
0x00007F7F,
0x007F0000,
0x007F007F,
0x007F7F00,
0x007F7F7F,
// + intensity
0x00000000,
0x000000FF,
0x0000FF00,
0x0000FFFF,
0x00FF0000,
0x00FF00FF,
0x00FFFF00,
0x00FFFFFF,

};

int gl_window;
unsigned int gl_width, gl_height;
float gl_font_width, gl_font_height;
float gl_incx, gl_incy;
int id[94];
unsigned char gl_resized=0, gl_bit=0;
#endif


static char *_caca_empty_line;
static char *_caca_scratch_line;
@@ -262,6 +297,39 @@ static RETSIGTYPE sigwinch_handler(int);
static int x11_error_handler(Display *, XErrorEvent *);
#endif

#if defined(USE_GL)
unsigned char gl_key = 0;
int gl_special_key=0;
int gl_new_width;
int gl_new_height;


static void gl_handle_keyboard(unsigned char key, int x, int y)
{
gl_key = key;
}
static void gl_handle_special_key(int key, int x, int y)
{
gl_special_key = key;
}
static void gl_handle_reshape (int w, int h)
{
if(gl_bit) /* Do not handle reshaping at the first time*/
{

gl_new_width = w;
gl_new_height = h;
gl_resized = 1;
}
else
gl_bit=1;
}
#endif



/** \brief Set the default colour pair.
*
* This function sets the default colour pair. String functions such as
@@ -329,6 +397,11 @@ void caca_set_color(enum caca_color fgcolor, enum caca_color bgcolor)
case CACA_DRIVER_WIN32:
/* Nothing to do */
break;
#endif
#if defined(USE_GL)
case CACA_DRIVER_GL:
/* Nothing to do */
break;
#endif
default:
break;
@@ -414,6 +487,10 @@ void caca_putchar(int x, int y, char c)
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
break;
#endif
#if defined(USE_GL)
case CACA_DRIVER_GL:
break;
#endif
default:
break;
@@ -509,6 +586,10 @@ void caca_putstr(int x, int y, char const *s)
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
break;
#endif
#if defined(USE_GL)
case CACA_DRIVER_GL:
break;
#endif
default:
break;
@@ -880,6 +961,89 @@ int _caca_init_graphics(void)
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
int i;
char *empty;

if(!_caca_width)
_caca_width = 80;
if(!_caca_height)
_caca_height = 32;

gl_font_width = 9;
gl_font_height = 15;

gl_width = _caca_width*gl_font_width;
gl_height = _caca_height*gl_font_height;

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(gl_width, gl_height);
gl_window = glutCreateWindow("caca for GL");

gluOrtho2D(0,gl_width, gl_height, 0);

glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);

glutKeyboardFunc(gl_handle_keyboard);
glutSpecialFunc(gl_handle_special_key);
glutReshapeFunc(gl_handle_reshape);

glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, gl_width, gl_height, 0);

glMatrixMode(GL_MODELVIEW);


glClear(GL_COLOR_BUFFER_BIT);



empty = malloc(16*16*4);
if(empty == NULL)
return -1;

memset(empty, 255, 16*16*4);
glEnable(GL_TEXTURE_2D);
for(i=0;i<94;i++)
{
glGenTextures(1,&id[i]);
glBindTexture(GL_TEXTURE_2D, id[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
16,16,
0, GL_RGB, GL_UNSIGNED_BYTE, empty);
}
for(i=0;i<94;i++)
{
glDisable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1,1,1);
glRasterPos2f(0,15);
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,i+32);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,id[i]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, gl_height-16, 16,16, 0);
glutMainLoopEvent();
glutPostRedisplay();
}
}
else
#endif

{
/* Dummy */
}
@@ -953,6 +1117,13 @@ int _caca_end_graphics(void)
CloseHandle(win32_front);
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
glutDestroyWindow(gl_window);
}
else
#endif
{
/* Dummy */
@@ -987,6 +1158,13 @@ int caca_set_window_title(char const *title)
SetConsoleTitle(title);
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
glutSetWindowTitle(title);
}
else
#endif
{
/* Not supported */
@@ -1020,6 +1198,13 @@ unsigned int caca_get_window_width(void)
/* FIXME */
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
return gl_width;
}
else
#endif
{
/* Dummy */
@@ -1053,6 +1238,13 @@ unsigned int caca_get_window_height(void)
/* FIXME */
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
return gl_height;
}
else
#endif
{
/* Dummy */
@@ -1220,6 +1412,98 @@ void caca_refresh(void)
WriteConsoleOutput(win32_front, win32_buffer, size, pos, &rect);
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
unsigned int x, y, offsetx, offsety;

glClear(GL_COLOR_BUFFER_BIT);
offsety=0;
for(y=0;y<gl_height;y+=gl_font_height)
{
offsetx = 0;
for(x=0;x<gl_width;x+=gl_font_width)
{
uint8_t *attr = cache_attr + offsetx + offsety * _caca_width;
int offset;
float br, bg, bb;
offset = attr[0]>>4;

br = ((gl_bg_palette[offset]&0x00FF0000)>>16)/255.0f;
bg = ((gl_bg_palette[offset]&0x0000FF00)>>8)/255.0f;
bb = ((gl_bg_palette[offset]&0x000000FF))/255.0f;
glDisable(GL_TEXTURE_2D);
glColor3f(br, bg, bb);
glBegin(GL_QUADS);
glVertex2f(x,y);
glVertex2f(x+gl_font_width,y);
glVertex2f(x+gl_font_width,y+gl_font_height);
glVertex2f(x,y+gl_font_height);
glEnd();

offsetx++;
}

offsety++;
}



/* 2nd pass, avoids changing render state too much */
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE, GL_ONE);
offsety=0;
for(y=0;y<gl_height;y+=gl_font_height)
{
offsetx = 0;
for(x=0;x<gl_width;x+=gl_font_width)
{
uint8_t *attr = cache_attr + offsetx + offsety * _caca_width;
unsigned char *chr = cache_char + offsetx + offsety * _caca_width;
float fr, fg, fb;
fr = ((gl_bg_palette[attr[0] & 0xf]&0x00FF0000)>>16)/255.0f;
fg = ((gl_bg_palette[attr[0] & 0xf]&0x0000FF00)>>8)/255.0f;
fb = ((gl_bg_palette[attr[0] & 0xf]&0x000000FF))/255.0f;

if(chr[0] != ' ')
{
glBindTexture(GL_TEXTURE_2D, id[chr[0]-32]);
glColor3f(fr, fg, fb);
glBegin(GL_QUADS);
glTexCoord2f(0,1);
glVertex2f(x,y);
glTexCoord2f(0.5,1);
glVertex2f(x+gl_font_width,y);
glTexCoord2f(0.5,0);
glVertex2f(x+gl_font_width,y+gl_font_height);
glTexCoord2f(0,0);
glVertex2f(x,y+gl_font_height);
glEnd();
}
offsetx++;
}
offsety++;
}
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);



glutMainLoopEvent();
glutSwapBuffers();
glutPostRedisplay();
}
else
#endif
{
/* Dummy */
@@ -1321,6 +1605,26 @@ static void caca_handle_resize(void)
{
}
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
gl_width = gl_new_width;
gl_height = gl_new_height;
_caca_width = gl_width/gl_font_width;
_caca_height = (gl_height/gl_font_height)+1;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glViewport(0,0,gl_width, gl_height);
gluOrtho2D(0, gl_width, gl_height, 0);
glMatrixMode(GL_MODELVIEW);

}
else
#endif
{
/* Dummy */


Загрузка…
Отмена
Сохранить