// Parameters: grid units void reshape(pair<int,int> size) { int w = MIN(MAX(size.first, MIN_GRID_X), MAX_GRID_X); int h = MIN(MAX(size.second, MIN_GRID_Y), MAX_GRID_Y); #ifdef DEBUG cout << "Resizing grid to " << w << "x" << h << endl; #endif gps_allocate(w, h); reshape_gl(); }
void renderer_cool::draw(int vertex_count) { static bool initial_resize = false; if (!initial_resize) { if (enabler->fullscreen) resize(size_x, size_y); else resize((size_x/init->font.small_font_dispx)*init->font.small_font_dispx, (size_y/init->font.small_font_dispy)*init->font.small_font_dispy); //resize(gps->dimx*init->font.small_font_dispx, gps->dimy*init->font.small_font_dispy); reshape_gl(); initial_resize = true; } static df::viewscreen *prevws = NULL; df::viewscreen *ws = Gui::getCurViewscreen(); is_main_scr = df::viewscreen_dwarfmodest::_identity.is_direct_instance(ws) || df::viewscreen_dungeonmodest::_identity.is_direct_instance(ws); if (ws != prevws) { gps->force_full_display_count = 1; prevws = ws; /*if (is_main_scr) { for (int x = 1; x < gps->dimx-gmenu_w-1; x++) { for (int y = 1; y < gps->dimy-1; y++) { const int tile1 = x * gps->dimy + y; for (int i = 0; i < 6; i++) *(fg + tile * 4 * i + 3) = 0; } } }*/ } display_new(is_main_scr); #ifdef WIN32 // We can't do this in plugin_init() because OpenGL context isn't initialized by that time static bool glew_init = false; if (!glew_init) { GLenum err = glewInit(); if (err != GLEW_OK) *out2 << glewGetErrorString(err); glew_init = true; } #endif static int old_dimx, old_dimy, old_winx, old_winy; if (domapshot) { if (domapshot == 10) { old_dimx = gps->dimx; old_dimy = gps->dimy; old_winx = *df::global::window_x; old_winy = *df::global::window_y; grid_resize(world->map.x_count + 36, world->map.y_count + 2); *df::global::window_x = 0; *df::global::window_y = 0; gps->force_full_display_count = 1; } domapshot--; } GLuint framebuffer, renderbuffer; GLenum status; if (domapshot == 5) { // Set the width and height appropriately for your image GLuint imageWidth = gps->dimx * dispx, imageHeight = gps->dimy * dispy; //Set up a FBO with one renderbuffer attachment glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glGenRenderbuffers(1, &renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, imageWidth, imageHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); glViewport(0, 0, gps->dimx * dispx, gps->dimy * dispy); /*glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,gps->dimx,gps->dimy,0,-1,1);*/ } if (is_main_scr) { bool skip = false; if (df::viewscreen_dungeonmodest::_identity.is_direct_instance(ws)) { int m = df::global::ui_advmode->menu; bool tmode = advmode_needs_map(m); skip = !tmode; } if (!skip) { ///// glViewport(goff_x, goff_y_gl, gdimx * gdispx, gdimy * gdispy); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, gdimx, gdimy, 0, -1, 1); //glTranslatef(1,-1,0); //glScissor(off_x+(float)size_x/gps->dimx, off_y+(float)size_y/gps->dimy, gsize_x, gsize_y); //glEnable(GL_SCISSOR_TEST); //glClearColor(1,0,0,1); //glClear(GL_COLOR_BUFFER_BIT); if (multi_rendered && fogdensity > 0) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, fogcolor); glFogf(GL_FOG_DENSITY, fogdensity); glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD); glEnableClientState(GL_FOG_COORD_ARRAY); glFogCoordPointer(GL_FLOAT, 0, fogcoord); } glVertexPointer(2, GL_FLOAT, 0, gvertexes); // Render background colors glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); glColorPointer(4, GL_FLOAT, 0, gbg); glDrawArrays(GL_TRIANGLES, 0, gdimx * gdimy * 6); // Render foreground glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointer(2, GL_FLOAT, 0, gtex); glColorPointer(4, GL_FLOAT, 0, gfg); glDrawArrays(GL_TRIANGLES, 0, gdimx * gdimy * 6); if (multi_rendered) { glDisableClientState(GL_FOG_COORD_ARRAY); glDisable(GL_FOG); } // Prepare and render shadows if (multi_rendered) { int elemcnt = 0; //TODO: don't do this if view not moved and tiles with shadows not changed { gl_texpos *txt = (gl_texpos *) enabler->textures.gl_texpos; int x1 = std::min(gdimx, world->map.x_count-gwindow_x); int y1 = std::min(gdimy, world->map.y_count-gwindow_y); for (int tile = 0; tile < gdimx * gdimy; tile++) { int xx = tile / gdimy; int yy = tile % gdimy; int d = depth[tile]; if (d && d != 0x7f) //TODO: no need for the second check in fort mode { GLfloat *tex = shadowtex + elemcnt * 2; bool top = false, left = false, btm = false, right = false; if (xx > 0 && (depth[((xx - 1)*gdimy + yy)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[0]); elemcnt += 6; left = true; } if (yy < y1 - 1 && (depth[((xx)*gdimy + yy + 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[1]); elemcnt += 6; btm = true; } if (yy > 0 && (depth[((xx)*gdimy + yy - 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[2]); elemcnt += 6; top = true; } if (xx < x1-1 && (depth[((xx + 1)*gdimy + yy)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[3]); elemcnt += 6; right = true; } if (!right && !btm && xx < x1 - 1 && yy < y1 - 1 && (depth[((xx + 1)*gdimy + yy + 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[4]); elemcnt += 6; } if (!left && !btm && xx > 0 && yy < y1 - 1 && (depth[((xx - 1)*gdimy + yy + 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[5]); elemcnt += 6; } if (!left && !top && xx > 0 && yy > 0 && (depth[((xx - 1)*gdimy + yy - 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[6]); elemcnt += 6; } if (!top && !right && xx < x1 - 1 && yy > 0 && (depth[((xx + 1)*gdimy + yy - 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[7]); elemcnt += 6; } } } } if (elemcnt) { glDisableClientState(GL_COLOR_ARRAY); glColor4fv(shadowcolor); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointer(2, GL_FLOAT, 0, shadowtex); glVertexPointer(2, GL_FLOAT, 0, shadowvert); glDrawArrays(GL_TRIANGLES, 0, elemcnt); glEnableClientState(GL_COLOR_ARRAY); } } glDisable(GL_SCISSOR_TEST); glViewport(off_x, off_y, size_x, size_y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, tdimx, tdimy, 0, -1, 1); } } { glVertexPointer(2, GL_FLOAT, 0, vertexes); // Render background colors glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glColorPointer(4, GL_FLOAT, 0, bg); glDrawArrays(GL_TRIANGLES, 0, tdimx*tdimy*6); // Render foreground glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointer(2, GL_FLOAT, 0, tex); glColorPointer(4, GL_FLOAT, 0, fg); glDrawArrays(GL_TRIANGLES, 0, tdimx*tdimy*6); } if (domapshot == 1) { int w = world->map.x_count * dispx; int h = world->map.y_count * dispy; unsigned char *data = (unsigned char *) malloc(w * h * 3); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glReadPixels(dispx, dispy, w, h, GL_BGR, GL_UNSIGNED_BYTE, data); #pragma pack(push,1) typedef struct _TgaHeader { unsigned char IDLength; /* 00h Size of Image ID field */ unsigned char ColorMapType; /* 01h Color map type */ unsigned char ImageType; /* 02h Image type code */ unsigned short CMapStart; /* 03h Color map origin */ unsigned short CMapLength; /* 05h Color map length */ unsigned char CMapDepth; /* 07h Depth of color map entries */ unsigned short XOffset; /* 08h X origin of image */ unsigned short YOffset; /* 0Ah Y origin of image */ unsigned short Width; /* 0Ch Width of image */ unsigned short Height; /* 0Eh Height of image */ unsigned char PixelDepth; /* 10h Image pixel size */ unsigned char ImageDescriptor; /* 11h Image descriptor byte */ } TGAHEAD; #pragma pop TGAHEAD hdr; memset(&hdr, 0, sizeof(hdr)); hdr.ImageType = 2; hdr.Width = w; hdr.Height = h; hdr.PixelDepth = 24; *out2 << w << " " << h << std::endl; std::ofstream img("mapshot.tga", std::ofstream::binary); img.write((const char *)&hdr, sizeof(hdr)); /* for (int j = 0; j<w*h*3; j++) { unsigned char c = data[j+0]; data[0] = data[j+2]; data[j+2] = c; }*/ img.write((const char *)data, w * h * 3); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Delete the renderbuffer attachment glDeleteRenderbuffers(1, &renderbuffer); grid_resize(old_dimx, old_dimy); *df::global::window_x = old_winx; *df::global::window_y = old_winy; gps->force_full_display_count = 1; domapshot = 0; } }