mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	refactored drawing to a texture; HQ shots can now be saved using OpenGL
This commit is contained in:
		| @@ -32,7 +32,7 @@ TTF_Font *font[256]; | ||||
| #endif | ||||
|  | ||||
| #if CAP_SDL | ||||
| SDL_Surface *s; | ||||
| SDL_Surface *s, *s_screen; | ||||
|  | ||||
| int qpixel_pixel_outside; | ||||
|  | ||||
| @@ -220,13 +220,13 @@ void selectEyeMask(int ed) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void setGLProjection() { | ||||
| void setGLProjection(int col) { | ||||
|   DEBB(DF_GRAPH, (debugfile,"setGLProjection\n")); | ||||
|  | ||||
|   glMatrixMode(GL_PROJECTION); | ||||
|   glLoadIdentity(); | ||||
|    | ||||
|   unsigned char *c = (unsigned char*) (&backcolor); | ||||
|   unsigned char *c = (unsigned char*) (&col); | ||||
|   glClearColor(c[2] / 255.0, c[1] / 255.0, c[0]/255.0, 1); | ||||
|   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
|    | ||||
| @@ -956,7 +956,7 @@ void IMAGESAVE(SDL_Surface *s, const char *fname) { | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| hookset<void(SDL_Surface*)> *hooks_hqshot; | ||||
| hookset<void(renderbuffer*)> *hooks_hqshot; | ||||
|  | ||||
| #if CAP_SDL | ||||
| void saveHighQualityShot(const char *fname, const char *caption, int fade) { | ||||
| @@ -988,26 +988,30 @@ void saveHighQualityShot(const char *fname, const char *caption, int fade) { | ||||
|     while(vid.xres & 15) vid.xres++; | ||||
|     } | ||||
|  | ||||
|   vid.usingGL = false; | ||||
|   // if(vid.pmodel == 0) vid.scale = 0.99; | ||||
|   calcparam(); | ||||
|   #if CAP_ROGUEVIZ | ||||
|   rogueviz::fixparam(); | ||||
|   #endif | ||||
|  | ||||
|   // printf("format = %d, %d x %d\n", pngformat, vid.xres, vid.yres); | ||||
|   renderbuffer glbuf(vid.xres, vid.yres, vid.usingGL); | ||||
|   glbuf.enable(); | ||||
|  | ||||
|   dynamicval<SDL_Surface*> v5(s, SDL_CreateRGBSurface(SDL_SWSURFACE,vid.xres,vid.yres,32,0,0,0,0)); | ||||
|   // printf("format = %d, %d x %d\n", pngformat, vid.xres, vid.yres); | ||||
|  | ||||
|   darken = 0; | ||||
|    | ||||
|   int numi = (fname?1:2); | ||||
|  | ||||
|   for(int i=0; i<numi; i++) { | ||||
|     SDL_FillRect(s, NULL, numi==1 ? backcolor : i ? 0xFFFFFF : 0); | ||||
|     drawfullmap(); | ||||
|     glbuf.clear(numi==1 ? backcolor : i ? 0xFFFFFF : 0); | ||||
|      | ||||
|     callhooks(hooks_hqshot, s); | ||||
|     if(rug::rugged) | ||||
|       rug::drawRugScene(); | ||||
|     else | ||||
|       drawfullmap(); | ||||
|      | ||||
|     callhooks(hooks_hqshot, &glbuf); | ||||
|  | ||||
|     if(fade < 255)  | ||||
|       for(int y=0; y<vid.yres; y++) | ||||
| @@ -1024,13 +1028,12 @@ void saveHighQualityShot(const char *fname, const char *caption, int fade) { | ||||
|     char buf[128]; strftime(buf, 128, "bigshota-%y%m%d-%H%M%S" IMAGEEXT, localtime(&timer)); | ||||
|     buf[7] += i; | ||||
|     if(!fname) fname = buf; | ||||
|     IMAGESAVE(s, fname); | ||||
|     IMAGESAVE(glbuf.render(), fname); | ||||
|      | ||||
|  | ||||
|     if(i == 0) addMessage(XLAT("Saved the high quality shot to %1", fname)); | ||||
|     } | ||||
|    | ||||
|   SDL_FreeSurface(s); | ||||
|   glbuf.disable(); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| @@ -1069,13 +1072,13 @@ void setvideomode() { | ||||
|  | ||||
|   int sizeflag = (vid.full ? SDL_FULLSCREEN : SDL_RESIZABLE); | ||||
|    | ||||
|   s= SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | sizeflag); | ||||
|   s = s_screen = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | sizeflag); | ||||
|    | ||||
|   if(vid.full && !s) { | ||||
|     vid.xres = vid.xscr; | ||||
|     vid.yres = vid.yscr; | ||||
|     do_setfsize(); | ||||
|     s = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | SDL_FULLSCREEN); | ||||
|     s = s_screen = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | SDL_FULLSCREEN); | ||||
|     } | ||||
|  | ||||
|   if(!s) { | ||||
| @@ -1084,7 +1087,7 @@ void setvideomode() { | ||||
|     vid.yres = 480; | ||||
|     SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); | ||||
|     vid.antialias &= ~AA_MULTI; | ||||
|     s = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | SDL_RESIZABLE); | ||||
|     s = s_screen = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | SDL_RESIZABLE); | ||||
|     } | ||||
|  | ||||
| #if CAP_GL | ||||
|   | ||||
| @@ -57,6 +57,7 @@ bool inv::on; | ||||
| #include "nofont.cpp" | ||||
| #endif | ||||
| #include "basegraph.cpp" | ||||
| #include "renderbuffer.cpp" | ||||
| #include "help.cpp" | ||||
| #include "config.cpp" | ||||
| #include "scores.cpp" | ||||
|   | ||||
							
								
								
									
										25
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -798,7 +798,10 @@ namespace polygonal { | ||||
| void selectEyeGL(int ed); | ||||
| void selectEyeMask(int ed); | ||||
| extern int ticks; | ||||
| void setGLProjection(); | ||||
|  | ||||
| extern unsigned backcolor, bordcolor, forecolor; | ||||
|  | ||||
| void setGLProjection(int col = backcolor); | ||||
|  | ||||
| // passable flags | ||||
|  | ||||
| @@ -1433,8 +1436,6 @@ extern cell *recallCell; | ||||
| extern eLand cheatdest; | ||||
| void cheatMoveTo(eLand l); | ||||
|  | ||||
| extern unsigned backcolor, bordcolor, forecolor; | ||||
|  | ||||
| extern bool overgenerate; | ||||
| void doOvergenerate(); | ||||
|  | ||||
| @@ -2508,3 +2509,21 @@ template<class T, class U> void eliminate_if(vector<T>& data, U pred) { | ||||
|  | ||||
| bool is_cell_removed(cell *c); | ||||
| void set_if_removed(cell*& c, cell *val); | ||||
|  | ||||
| struct renderbuffer { | ||||
|   int x, y, tx, ty; | ||||
|   GLuint FramebufferName; | ||||
|   GLuint renderedTexture; | ||||
|   GLuint depth_stencil_rb; | ||||
|   SDL_Surface *srf; | ||||
|   Uint32 *expanded_data; | ||||
|    | ||||
|   void make_surface(); | ||||
|   renderbuffer(int x, int y, bool gl); | ||||
|   ~renderbuffer(); | ||||
|   void enable(); | ||||
|   void disable(); | ||||
|   SDL_Surface *render(); | ||||
|   void use_as_texture(); | ||||
|   void clear(int col); | ||||
|   }; | ||||
|   | ||||
							
								
								
									
										154
									
								
								rug.cpp
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								rug.cpp
									
									
									
									
									
								
							| @@ -9,28 +9,6 @@ | ||||
| #define TEXTURESIZE (texturesize) | ||||
| #define HTEXTURESIZE (texturesize/2) | ||||
|  | ||||
| #if !CAP_GLEW | ||||
| #if ISLINUX | ||||
| extern "C" { | ||||
| GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); | ||||
| GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); | ||||
| GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); | ||||
| GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); | ||||
| GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); | ||||
| GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); | ||||
| GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); | ||||
| GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); | ||||
| GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); | ||||
| GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); | ||||
| GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if ISMAC | ||||
| #define glFramebufferTexture glFramebufferTextureEXT  | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| namespace rug { | ||||
|  | ||||
| struct rug_exception { }; | ||||
| @@ -1083,114 +1061,32 @@ void drawTriangle(triangle& t) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| GLuint FramebufferName = 0; | ||||
| GLuint renderedTexture = 0; | ||||
| GLuint depth_stencil_rb = 0; | ||||
|  | ||||
| SDL_Surface *texture; | ||||
| Uint32 *expanded_data; | ||||
|  | ||||
| void initTexture() { | ||||
|  | ||||
|   if(!rendernogl) { | ||||
| #if !ISPANDORA | ||||
|     FramebufferName = 0; | ||||
|     glGenFramebuffers(1, &FramebufferName); | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); | ||||
|      | ||||
|     glGenTextures(1, &renderedTexture); | ||||
|     glBindTexture(GL_TEXTURE_2D, renderedTexture); | ||||
|     glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, TEXTURESIZE, TEXTURESIZE, 0,GL_RGB, GL_UNSIGNED_BYTE, 0); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|    | ||||
| #ifdef TEX | ||||
|     glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);   | ||||
| #else | ||||
|     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedTexture, 0);   | ||||
| #endif | ||||
|     GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; | ||||
|     glDrawBuffers(1, DrawBuffers); | ||||
|      | ||||
|     glGenRenderbuffers(1, &depth_stencil_rb); | ||||
|     glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil_rb); | ||||
|     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, TEXTURESIZE, TEXTURESIZE); | ||||
|     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_stencil_rb); | ||||
|     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth_stencil_rb); | ||||
|      | ||||
|     if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|       addMessage("Failed to initialize the framebuffer"); | ||||
|       rugged = false; | ||||
|       }   | ||||
| #endif | ||||
|     } | ||||
|   else { | ||||
|     texture = SDL_CreateRGBSurface(SDL_SWSURFACE,TEXTURESIZE,TEXTURESIZE,32,0,0,0,0);   | ||||
|     glGenTextures( 1, &renderedTexture ); | ||||
|     glBindTexture( GL_TEXTURE_2D, renderedTexture); | ||||
|     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); | ||||
|     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); | ||||
|     expanded_data = new Uint32[TEXTURESIZE * TEXTURESIZE]; | ||||
|     } | ||||
|   } | ||||
| renderbuffer *glbuf; | ||||
|  | ||||
| void prepareTexture() { | ||||
|   videopar svid = vid; | ||||
|    | ||||
|   setVidParam(); | ||||
|    | ||||
|   if(rendernogl) { | ||||
|     vid.usingGL = false; | ||||
|     SDL_Surface *sav = s; | ||||
|     s = texture; | ||||
|     SDL_FillRect(s, NULL, 0); | ||||
|  | ||||
|     drawfullmap(); | ||||
|     s = sav; | ||||
|     for(int y=0; y<TEXTURESIZE; y++) for(int x=0; x<TEXTURESIZE; x++) | ||||
|       expanded_data[y*TEXTURESIZE + x] = qpixel(texture, x, TEXTURESIZE-1-y) | 0xFF000000; | ||||
|     glBindTexture( GL_TEXTURE_2D, renderedTexture); | ||||
|     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, TEXTURESIZE, TEXTURESIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, expanded_data );     | ||||
|     } | ||||
|   else {  | ||||
| #if !ISPANDORA | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); | ||||
|     glViewport(0,0,TEXTURESIZE,TEXTURESIZE); | ||||
|   glbuf->enable(); | ||||
|    | ||||
|     setGLProjection(); | ||||
|     ptds.clear(); | ||||
|     drawthemap(); | ||||
|     if(mousing && !renderonce) { | ||||
|       for(int i=0; i<numplayers(); i++) if(multi::playerActive(i)) | ||||
|         queueline(tC0(shmup::ggmatrix(playerpos(i))), mouseh, 0xFF00FF, 8); | ||||
|       } | ||||
|     if(finger_center) { | ||||
|       transmatrix V = rgpushxto0(finger_center->h); | ||||
|       queuechr(V, 0.5, 'X', 0xFFFFFFFF, 2); | ||||
|       for(int i=0; i<72; i++) | ||||
|         queueline(tC0(V * spin(i*M_PI/32) * xpush(finger_range)), tC0(V * spin((i+1)*M_PI/32) * xpush(finger_range)), 0xFFFFFFFF, 0); | ||||
|       } | ||||
|     drawqueue();   | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
| #endif | ||||
|     } | ||||
|   vid = svid; | ||||
|   if(!rendernogl) glViewport(0,0,vid.xres,vid.yres); | ||||
|   } | ||||
|   glbuf->clear(0); | ||||
|  | ||||
| void closeTexture() { | ||||
|   if(rendernogl) { | ||||
|     SDL_FreeSurface(texture); | ||||
|     glDeleteTextures(1, &renderedTexture); | ||||
|     delete[] expanded_data; | ||||
|   ptds.clear(); | ||||
|   drawthemap(); | ||||
|   if(mousing && !renderonce) { | ||||
|     for(int i=0; i<numplayers(); i++) if(multi::playerActive(i)) | ||||
|       queueline(tC0(shmup::ggmatrix(playerpos(i))), mouseh, 0xFF00FF, 8); | ||||
|     } | ||||
|   else { | ||||
| #if !ISPANDORA | ||||
|     glDeleteTextures(1, &renderedTexture); | ||||
|     glDeleteRenderbuffers(1, &depth_stencil_rb); | ||||
|     glDeleteFramebuffers(1, &FramebufferName); | ||||
| #endif | ||||
|   if(finger_center) { | ||||
|     transmatrix V = rgpushxto0(finger_center->h); | ||||
|     queuechr(V, 0.5, 'X', 0xFFFFFFFF, 2); | ||||
|     for(int i=0; i<72; i++) | ||||
|       queueline(tC0(V * spin(i*M_PI/32) * xpush(finger_range)), tC0(V * spin((i+1)*M_PI/32) * xpush(finger_range)), 0xFFFFFFFF, 0); | ||||
|     } | ||||
|   drawqueue(); | ||||
|   vid = svid; | ||||
|   glbuf->disable(); | ||||
|   } | ||||
|  | ||||
| double xview, yview; | ||||
| @@ -1214,8 +1110,8 @@ void drawRugScene() { | ||||
|  | ||||
|   glEnable(GL_LIGHTING); | ||||
|   glEnable(GL_LIGHT0); | ||||
|  | ||||
|   glBindTexture(GL_TEXTURE_2D, renderedTexture); | ||||
|    | ||||
|   glbuf->use_as_texture(); | ||||
|  | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glLoadIdentity(); | ||||
| @@ -1310,20 +1206,10 @@ void drawRugScene() { | ||||
| transmatrix currentrot; | ||||
|      | ||||
| void init() { | ||||
| #if CAP_GLEW | ||||
|   if(!glew) {  | ||||
|     glew = true;  | ||||
|     GLenum err = glewInit(); | ||||
|     if (GLEW_OK != err) { | ||||
|       addMessage("Failed to initialize GLEW"); | ||||
|       return; | ||||
|       } | ||||
|     } | ||||
| #endif | ||||
|   if(rugged) return; | ||||
|   rugged = true; | ||||
|   if(scale < .01 || scale > 100) scale = 1; | ||||
|   initTexture(); | ||||
|   glbuf = new renderbuffer(TEXTURESIZE, TEXTURESIZE, vid.usingGL && !rendernogl); | ||||
|   if(renderonce) prepareTexture(); | ||||
|   if(!rugged) return; | ||||
|    | ||||
| @@ -1364,7 +1250,7 @@ void init() { | ||||
| void close() { | ||||
|   if(!rugged) return; | ||||
|   rugged = false; | ||||
|   closeTexture(); | ||||
|   delete glbuf; | ||||
|   triangles.clear(); | ||||
|   for(int i=0; i<size(points); i++) delete points[i]; | ||||
|   points.clear(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue