//original file from https://github.com/Baughn/Dwarf-Fortress--libgraphics- #ifndef RENDERER_OPENGL_INCLUDED #define RENDERER_OPENGL_INCLUDED #include "tinythread.h" #include "fast_mutex.h" #include "Core.h" #include #include "df/renderer.h" #include "df/init.h" #include "df/enabler.h" #include "df/zoom_commands.h" #include "df/texture_handler.h" #include "df/graphic.h" #include using df::renderer; using df::init; using df::enabler; struct old_opengl:public renderer { void* sdlSurface; int32_t dispx,dispy; float *vertexes, *fg, *bg, *tex; int32_t zoom_steps,forced_steps,natural_w,natural_h; int32_t off_x,off_y,size_x,size_y; }; struct renderer_wrap : public renderer { private: void set_to_null() { screen = NULL; screentexpos = NULL; screentexpos_addcolor = NULL; screentexpos_grayscale = NULL; screentexpos_cf = NULL; screentexpos_cbr = NULL; screen_old = NULL; screentexpos_old = NULL; screentexpos_addcolor_old = NULL; screentexpos_grayscale_old = NULL; screentexpos_cf_old = NULL; screentexpos_cbr_old = NULL; } void copy_from_inner() { screen = parent->screen; screentexpos = parent->screentexpos; screentexpos_addcolor = parent->screentexpos_addcolor; screentexpos_grayscale = parent->screentexpos_grayscale; screentexpos_cf = parent->screentexpos_cf; screentexpos_cbr = parent->screentexpos_cbr; screen_old = parent->screen_old; screentexpos_old = parent->screentexpos_old; screentexpos_addcolor_old = parent->screentexpos_addcolor_old; screentexpos_grayscale_old = parent->screentexpos_grayscale_old; screentexpos_cf_old = parent->screentexpos_cf_old; screentexpos_cbr_old = parent->screentexpos_cbr_old; } void copy_to_inner() { parent->screen = screen; parent->screentexpos = screentexpos; parent->screentexpos_addcolor = screentexpos_addcolor; parent->screentexpos_grayscale = screentexpos_grayscale; parent->screentexpos_cf = screentexpos_cf; parent->screentexpos_cbr = screentexpos_cbr; parent->screen_old = screen_old; parent->screentexpos_old = screentexpos_old; parent->screentexpos_addcolor_old = screentexpos_addcolor_old; parent->screentexpos_grayscale_old = screentexpos_grayscale_old; parent->screentexpos_cf_old = screentexpos_cf_old; parent->screentexpos_cbr_old = screentexpos_cbr_old; } public: renderer_wrap(renderer* parent):parent(parent) { copy_from_inner(); } virtual void update_tile(int32_t x, int32_t y) { copy_to_inner(); parent->update_tile(x,y); }; virtual void update_all() { copy_to_inner(); parent->update_all(); }; virtual void render() { copy_to_inner(); parent->render(); }; virtual void set_fullscreen() { copy_to_inner(); parent->set_fullscreen(); }; virtual void zoom(df::zoom_commands z) { copy_to_inner(); parent->zoom(z); }; virtual void resize(int32_t w, int32_t h) { copy_to_inner(); parent->resize(w,h); copy_from_inner(); }; virtual void grid_resize(int32_t w, int32_t h) { copy_to_inner(); parent->grid_resize(w,h); copy_from_inner(); }; virtual ~renderer_wrap() { df::global::enabler->renderer=parent; }; virtual bool get_mouse_coords(int32_t* x, int32_t* y) { return parent->get_mouse_coords(x,y); }; virtual bool uses_opengl() { return parent->uses_opengl(); }; void invalidateRect(int32_t x,int32_t y,int32_t w,int32_t h) { for(int i=x;idimy + j; screen_old[index*4]=screen[index*4]+1;//ensure tile is different } }; void invalidate() { invalidateRect(0,0,df::global::gps->dimx,df::global::gps->dimy); //df::global::gps->force_full_display_count++; }; protected: renderer* parent; }; struct renderer_trippy : public renderer_wrap { private: float rFloat() { return rand()/(float)RAND_MAX; } void colorizeTile(int x,int y) { const int tile = x*(df::global::gps->dimy) + y; old_opengl* p=reinterpret_cast(parent); float *fg = p->fg + tile * 4 * 6; float *bg = p->bg + tile * 4 * 6; float *tex = p->tex + tile * 2 * 6; const float val=1/2.0; float r=rFloat()*val - val/2; float g=rFloat()*val - val/2; float b=rFloat()*val - val/2; float backr=rFloat()*val - val/2; float backg=rFloat()*val - val/2; float backb=rFloat()*val - val/2; for (int i = 0; i < 6; i++) { *(fg++) += r; *(fg++) += g; *(fg++) += b; *(fg++) = 1; *(bg++) += backr; *(bg++) += backg; *(bg++) += backb; *(bg++) = 1; } } public: renderer_trippy(renderer* parent):renderer_wrap(parent) { } virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); colorizeTile(x,y); }; virtual void update_all() { renderer_wrap::update_all(); for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) colorizeTile(x,y); }; }; struct lightCell { float r,g,b; lightCell():r(0),g(0),b(0) { } lightCell(float r,float g,float b):r(r),g(g),b(b) { } lightCell operator-(lightCell cell) const { return lightCell(r-cell.r,g-cell.g,b-cell.b); } lightCell operator*(float val)const { return lightCell(r*val,g*val,b*val); } lightCell operator/(float val) const { return lightCell(r/val,g/val,b/val); } lightCell operator*(lightCell cell) const { return lightCell(r*cell.r,g*cell.g,b*cell.b); } lightCell operator*=(lightCell cell) { r*=cell.r; g*=cell.g; b*=cell.b; return *this; } lightCell operator+(const lightCell& other) const { return lightCell(r+other.r,g+other.g,b+other.b); } bool operator<=(const lightCell& other) const { return r<=other.r && g<=other.g && b<=other.b; } float dot(const lightCell& other) const { return r*other.r+g*other.g+b*other.b; } lightCell power(const float exp) const { return lightCell(pow(r, exp), pow(g, exp), pow(b, exp)); } lightCell power(const int exp) const { return lightCell(pow(r, exp), pow(g, exp), pow(b, exp)); } }; struct renderer_test : public renderer_wrap { private: void colorizeTile(int x,int y) { const int tile = x*(df::global::gps->dimy) + y; old_opengl* p=reinterpret_cast(parent); float *fg = p->fg + tile * 4 * 6; float *bg = p->bg + tile * 4 * 6; float *tex = p->tex + tile * 2 * 6; lightCell light=lightGrid[tile]; for (int i = 0; i < 6; i++) { *(fg++) *= light.r; *(fg++) *= light.g; *(fg++) *= light.b; *(fg++) = 1; *(bg++) *= light.r; *(bg++) *= light.g; *(bg++) *= light.b; *(bg++) = 1; } } void reinitLightGrid(int w,int h) { tthread::lock_guard guard(dataMutex); lightGrid.resize(w*h); } void reinitLightGrid() { reinitLightGrid(df::global::gps->dimy,df::global::gps->dimx); } public: tthread::fast_mutex dataMutex; std::vector lightGrid; renderer_test(renderer* parent):renderer_wrap(parent) { reinitLightGrid(); } virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); tthread::lock_guard guard(dataMutex); colorizeTile(x,y); //some sort of mutex or sth? //and then map read }; virtual void update_all() { renderer_wrap::update_all(); tthread::lock_guard guard(dataMutex); for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) colorizeTile(x,y); //some sort of mutex or sth? //and then map read //same stuff for all of them i guess... }; virtual void grid_resize(int32_t w, int32_t h) { renderer_wrap::grid_resize(w,h); reinitLightGrid(w,h); }; virtual void resize(int32_t w, int32_t h) { renderer_wrap::resize(w,h); reinitLightGrid(w,h); } }; struct rgba { float r,g,b,a; }; struct renderer_lua : public renderer_wrap { private: void overwriteTile(int x,int y) { const int tile = xyToTile(x,y); old_opengl* p=reinterpret_cast(parent); float *fg = p->fg + tile * 4 * 6; float *bg = p->bg + tile * 4 * 6; float *tex = p->tex + tile * 2 * 6; lightCell fm=foreMult[tile]; lightCell fo=foreOffset[tile]; lightCell bm=backMult[tile]; lightCell bo=backOffset[tile]; for (int i = 0; i < 6; i++) { rgba* fore=reinterpret_cast(fg); fore->r=fore->r*fm.r+fo.r; fore->g=fore->g*fm.g+fo.g; fore->b=fore->b*fm.b+fo.b; fg+=4; rgba* back=reinterpret_cast(bg); back->r=back->r*bm.r+bo.r; back->g=back->g*bm.g+bo.g; back->b=back->b*bm.b+bo.b; bg+=4; } } void reinitGrids(int w,int h) { tthread::lock_guard guard(dataMutex); foreOffset.resize(w*h); foreMult.resize(w*h); backOffset.resize(w*h); backMult.resize(w*h); } void reinitGrids() { reinitGrids(df::global::gps->dimy,df::global::gps->dimx); } public: tthread::fast_mutex dataMutex; std::vector foreOffset,foreMult; std::vector backOffset,backMult; inline int xyToTile(int x, int y) { return x*(df::global::gps->dimy) + y; } renderer_lua(renderer* parent):renderer_wrap(parent) { reinitGrids(); } virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); tthread::lock_guard guard(dataMutex); overwriteTile(x,y); //some sort of mutex or sth? //and then map read }; virtual void update_all() { renderer_wrap::update_all(); tthread::lock_guard guard(dataMutex); for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) overwriteTile(x,y); //some sort of mutex or sth? //and then map read //same stuff for all of them i guess... }; virtual void grid_resize(int32_t w, int32_t h) { renderer_wrap::grid_resize(w,h); reinitGrids(w,h); }; virtual void resize(int32_t w, int32_t h) { renderer_wrap::resize(w,h); reinitGrids(w,h); } }; #endif