2 "$Id: opengl.c 11043 2008-12-21 04:44:14Z kbulgrien $";
46 #include <glade/glade.h>
51 #include <gdk/gdkwin32.h>
53 #include <gdk/gdkkeysyms.h>
75 static HDC devicecontext;
83 static void init_opengl_common(
void)
88 glEnable(GL_TEXTURE_2D);
89 glShadeModel(GL_SMOOTH);
93 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
95 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
109 glMatrixMode(GL_PROJECTION);
113 glOrtho(0.0f,width,height,0.0f,-1.0f,1.0f);
114 glMatrixMode(GL_MODELVIEW);
119 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
120 LOG(
LOG_INFO,
"gtk::opengl_common",
"Maximum texture size is %d\n", texSize);
133 int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
140 XSetWindowAttributes attr;
144 display = GDK_WINDOW_XDISPLAY(drawingarea->window);
146 gdk_x11_get_default_screen (), attrListDbl);
148 width = drawingarea->allocation.width;
149 height = drawingarea->allocation.height;
158 v = DefaultVisual(
display, gdk_x11_get_default_screen ());
159 attr.colormap= XCreateColormap(
display, GDK_WINDOW_XID(drawingarea->window),
160 vi->visual, AllocNone);
162 window = XCreateWindow(
display, GDK_WINDOW_XID(drawingarea->window),
172 LOG(
LOG_WARNING,
"gtk::init_glx_opengl",
"Could not get double buffered screen!\n");
175 ctx = glXCreateContext(
display, vi, 0, GL_TRUE);
177 if (!glXMakeCurrent(
display, window, ctx)) {
178 LOG(
LOG_ERROR,
"gtk::init_glx_opengl",
"Could not set opengl context!\n");
182 LOG(
LOG_INFO,
"gtk::init_glx_opengl",
"Direct rendering is available!\n");
184 LOG(
LOG_INFO,
"gtk::init_glx_opengl",
"Direct rendering is not available!\n");
195 void init_wgl_opengl(GtkWidget* drawingarea)
200 PIXELFORMATDESCRIPTOR pfd = {
201 sizeof(PIXELFORMATDESCRIPTOR),
221 width = drawingarea->allocation.width;
222 height = drawingarea->allocation.height;
224 dctx = GetDC(GDK_WINDOW_HWND(drawingarea->window));
225 devicecontext = dctx;
228 pixelformat = ChoosePixelFormat(dctx, &pfd);
229 SetPixelFormat(dctx, pixelformat, &pfd);
231 glctx = wglCreateContext(dctx);
232 wglMakeCurrent(dctx, glctx);
248 init_wgl_opengl(drawingarea);
250 init_opengl_common();
270 #define DEFAULT_DARKNESS 0
291 static void opengl_light_space(
int x,
int y,
int mx,
int my)
309 glColor4ub(0, 0, 0, map_darkness[x*2][y*2]);
312 glColor4ub(0, 0, 0, map_darkness[x*2 + 1][y*2]);
315 glColor4ub(0, 0, 0, map_darkness[x*2 + 1][y*2 + 1]);
318 glColor4ub(0, 0, 0, map_darkness[x*2][y*2+1]);
326 glColor4ub(0, 0, 0, map_darkness[x*2+1][y*2]);
329 glColor4ub(0, 0, 0, map_darkness[x*2+2][y*2]);
332 glColor4ub(0, 0, 0, map_darkness[x*2+2][y*2+1]);
335 glColor4ub(0, 0, 0, map_darkness[x*2+1][y*2+1]);
343 glColor4ub(0, 0, 0, map_darkness[x*2][y*2+1]);
346 glColor4ub(0, 0, 0, map_darkness[x*2+1][y*2+1]);
349 glColor4ub(0, 0, 0, map_darkness[x*2+1][y*2+2]);
352 glColor4ub(0, 0, 0, map_darkness[x*2][y*2+2]);
360 glColor4ub(0, 0, 0, map_darkness[x*2+1][y*2+1]);
363 glColor4ub(0, 0, 0, map_darkness[x*2+2][y*2+1]);
366 glColor4ub(0, 0, 0, map_darkness[x*2+2][y*2+2]);
367 glVertex3i((x+1) * map_image_size, (y +1)* map_image_size, 0);
369 glColor4ub(0, 0, 0, map_darkness[x*2+1][y*2+2]);
379 static int dx[8]={0,1,1,1,0,-1,-1,-1};
380 static int dy[8]={-1,-1,0,1,1,1,0,-1};
382 static int bweights[8]={2,0,4,0,8,0,1,0};
383 static int cweights[8]={0,2,0,4,0,8,0,1};
384 static int bc_exclude[8]={
399 #define TEXTURE_OFFSET 1.0/16.0
412 static void drawsmooth_opengl (
int x,
int y,
int mx,
int my,
int layer) {
413 int partdone[8]={0,0,0,0,0,0,0,0}, slevels[8], sfaces[8], i,
414 weight,weightC, emx,emy, smoothface, dosmooth, lowest, havesmooth;
445 while (havesmooth < dosmooth) {
448 if ( (slevels[i]>0) && (!partdone[i]) && ((lowest<0) || (slevels[i]<slevels[lowest])))
459 if (slevels[i]==slevels[lowest] && sfaces[i] == sfaces[lowest]) {
461 weight=weight+bweights[i];
462 weightC&=~bc_exclude[i];
466 weightC&=~cweights[i];
470 smoothface=sfaces[lowest];
486 glBindTexture(GL_TEXTURE_2D,
pixmaps[smoothface]->fog_texture);
488 glBindTexture(GL_TEXTURE_2D,
pixmaps[smoothface]->map_texture);
498 glTexCoord2f(TEXTURE_OFFSET * weight, 0.0f);
499 glVertex3i(x * map_image_size, y * map_image_size, 0);
501 glTexCoord2f(TEXTURE_OFFSET * (weight+1), 0.0f);
502 glVertex3i((x+1) * map_image_size, y * map_image_size, 0);
504 glTexCoord2f(TEXTURE_OFFSET * (weight+1), 0.5f);
505 glVertex3i((x+1) * map_image_size, (y+1) * map_image_size, 0);
507 glTexCoord2f(TEXTURE_OFFSET * weight, 0.5f);
508 glVertex3i(x * map_image_size, (y+1) * map_image_size, 0);
515 glTexCoord2f(TEXTURE_OFFSET * weight, 0.5f);
516 glVertex3i(x * map_image_size, y * map_image_size, 0);
518 glTexCoord2f(TEXTURE_OFFSET * (weight+1), 0.5f);
519 glVertex3i((x+1) * map_image_size, y * map_image_size, 0);
521 glTexCoord2f(TEXTURE_OFFSET * (weight+1), 1.0f);
522 glVertex3i((x+1) * map_image_size, (y+1) * map_image_size, 0);
524 glTexCoord2f(TEXTURE_OFFSET * weight, 1.0f);
525 glVertex3i(x * map_image_size, (y+1) * map_image_size, 0);
536 static void draw_smoothing(
int layer)
547 drawsmooth_opengl(x, y, mx, my, layer);
568 long elapsed1, elapsed2;
569 struct timeval tv1, tv2,tv3;
570 int mx,my, layer,x,y, d1, d2, d3, num_dark, got_smooth, face, t1, t2;
573 gettimeofday(&tv1, NULL);
575 glClear(GL_COLOR_BUFFER_BIT);
581 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
593 for (layer=0; layer<=
MAXLAYERS; layer++) {
601 glBindTexture(GL_TEXTURE_2D, 0);
630 opengl_light_space(x, y, mx, my);
659 map_darkness[x*2 + 1][y*2 + 1] = DEFAULT_DARKNESS;
661 d1 = DEFAULT_DARKNESS;
662 d2 = DEFAULT_DARKNESS;
663 d3 = DEFAULT_DARKNESS;
687 map_darkness[x*2][y*2] = (d1 + d2 +d3 + map_darkness[x*2 + 1][y*2 + 1]) / num_dark;
690 map_darkness[x*2][y*2 + 1] = (d1 + map_darkness[x*2 + 1][y*2 + 1]) / 2;
692 map_darkness[x*2][y*2 + 1] = map_darkness[x*2 + 1][y*2 + 1];
696 map_darkness[x*2 +1 ][y*2] = (d3 + map_darkness[x*2 + 1][y*2 + 1]) / 2;
698 map_darkness[x*2 + 1][y*2] = map_darkness[x*2 + 1][y*2 + 1];
706 map_darkness[x*2][y*2] = MAX( MAX(d1, d2), MAX(d3, map_darkness[x*2 + 1][y*2 + 1]));
707 map_darkness[x*2][y*2 + 1] = MAX(d1, map_darkness[x*2 + 1][y*2 + 1]);
708 map_darkness[x*2 + 1][y*2] = MAX(d3, map_darkness[x*2 + 1][y*2 + 1]);
740 glTexCoord2f(0.0f, 0.0f);
741 glVertex3i(nx, ny, 0);
743 glTexCoord2f(1.0f, 0.0f);
744 glVertex3i( (x+1) * map_image_size, ny, 0);
746 glTexCoord2f(1.0f, 1.0f);
747 glVertex3i( (x+1) * map_image_size, (y+1) * map_image_size, 0);
749 glTexCoord2f(0.0f, 1.0f);
750 glVertex3i(nx, (y+1) * map_image_size, 0);
761 if (
pixmaps[face]->map_texture) {
768 nx = (x+1) * map_image_size -
pixmaps[face]->map_width;
769 ny = (y+1) * map_image_size -
pixmaps[face]->map_height;
782 glBindTexture(GL_TEXTURE_2D,
pixmaps[face]->fog_texture);
784 glBindTexture(GL_TEXTURE_2D,
pixmaps[face]->map_texture);
788 glTexCoord2f(0.0f, 0.0f);
789 glVertex3i(nx, ny, 0);
791 glTexCoord2f(1.0f, 0.0f);
792 glVertex3i( (x+1) * map_image_size, ny, 0);
794 glTexCoord2f(1.0f, 1.0f);
795 glVertex3i( (x+1) * map_image_size, (y+1) * map_image_size, 0);
797 glTexCoord2f(0.0f, 1.0f);
798 glVertex3i(nx, (y+1) * map_image_size, 0);
818 draw_smoothing(layer);
822 gettimeofday(&tv2, NULL);
825 glXSwapBuffers(
display, window);
827 SwapBuffers(devicecontext);
831 gettimeofday(&tv3, NULL);
832 elapsed1 = (tv2.tv_sec - tv1.tv_sec)*1000000 + (tv2.tv_usec - tv1.tv_usec);
833 elapsed2 = (tv3.tv_sec - tv2.tv_sec)*1000000 + (tv3.tv_usec - tv2.tv_usec);
838 if ((elapsed1 + elapsed2)>10000)
839 LOG(
LOG_INFO,
"gtk::opengl_gen_map",
"gen took %7ld, flip took %7ld, total = %7ld",
840 elapsed1, elapsed2, elapsed1 + elapsed2);
853 static uint8 *newdata;
855 int nwidth, nheight, numshifts, i;
856 uint8 *data_to_use = data, *l;
865 for (nwidth = pi->
map_width, numshifts=0; nwidth >1; nwidth >>=1, numshifts++) ;
866 nwidth <<= numshifts;
867 if (nwidth != pi->
map_width) nwidth <<=1;
869 for (nheight = pi->
map_height, numshifts=0; nheight >1; nheight >>=1, numshifts++) ;
870 nheight <<= numshifts;
893 if (nwidth * nheight * 4 > size) {
894 size = nwidth * nheight * 4;
895 newdata = realloc(newdata, size);
903 memset(newdata, 0, (nheight - pi->
map_height) * nwidth * 4);
904 datastart = newdata + (nheight - pi->
map_height) * nwidth * 4;
909 memset(datastart + y * nwidth * 4, 0, (nwidth - pi->
map_width) * 4);
910 memcpy(datastart + y * nwidth * 4 + (nwidth - pi->
map_width) * 4,
913 data_to_use = newdata;
918 glGenTextures(1, &pi->map_texture);
919 glBindTexture(GL_TEXTURE_2D, pi->map_texture);
920 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
921 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
924 0, GL_RGBA, GL_UNSIGNED_BYTE, data_to_use);
934 newdata = realloc(newdata, size);
938 if (data_to_use != newdata) {
943 l = (
uint8 *) (newdata + i*4);
946 p = (
uint32*) newdata + i;
947 *p = g | (g << 8) | (g << 16) | (*(l + 3) << 24);
950 glGenTextures(1, &pi->fog_texture);
951 glBindTexture(GL_TEXTURE_2D, pi->fog_texture);
952 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
953 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
956 0, GL_RGBA, GL_UNSIGNED_BYTE, newdata);
965 if (pi->map_texture) {
966 glDeleteTextures(1, &pi->map_texture);
969 if (pi->fog_texture) {
970 glDeleteTextures(1, &pi->fog_texture);
975 #include "../../pixmaps/question.111"
986 GLubyte question[question_height][question_width][4];
987 int xb, x, y, offset=0;
993 for (y=0; y<question_height; y++) {
994 for (xb=0; xb<question_width/8; xb++) {
995 for (x=0; x<8; x++) {
996 if (question_bits[offset] & (1 << x)) {
997 question[y][xb * 8 + x][0] = 255;
998 question[y][xb * 8 + x][1] = 255;
999 question[y][xb * 8 + x][2] = 255;
1000 question[y][xb * 8 + x][3] = 255;
1002 question[y][xb * 8 + x][0] = 0;
1003 question[y][xb * 8 + x][1] = 0;
1004 question[y][xb * 8 + x][2] = 0;
1005 question[y][xb * 8 + x][3] = 0;
1012 glGenTextures(1, &
pixmaps[0]->map_texture);
1013 glBindTexture(GL_TEXTURE_2D,
pixmaps[0]->map_texture);
1014 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1015 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1017 glTexImage2D(GL_TEXTURE_2D, 0, 4, question_width, question_height,
1018 0, GL_RGBA, GL_UNSIGNED_BYTE, &question[0][0][0]);
1020 glGenTextures(1, &
pixmaps[0]->fog_texture);
1021 glBindTexture(GL_TEXTURE_2D,
pixmaps[0]->fog_texture);
1022 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1023 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1025 glTexImage2D(GL_TEXTURE_2D, 0, 4, question_width, question_height,
1026 0, GL_RGBA, GL_UNSIGNED_BYTE, &question[0][0][0]);
#define CAN_SMOOTH(__SQUARE, __LEVEL)
sint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh)
void opengl_free_pixmap(PixmapInfo *pi)
void create_opengl_map_image(uint8 *data, PixmapInfo *pi)
PixmapInfo * pixmaps[MAXPIXMAPNUM]
void LOG(LogLevel level, const char *origin, const char *format,...)
void init_glx_opengl(GtkWidget *drawingarea)
void create_opengl_question_mark(void)
sint16 use_config[CONFIG_NUMS]
const char *const rcsid_gtk2_opengl_c
void init_opengl(GtkWidget *drawingarea)
void opengl_gen_map(int redraw)
struct MapCellLayer heads[MAXLAYERS]