mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
refactored drawing to a texture; HQ shots can now be saved using OpenGL
This commit is contained in:
parent
84980e55fc
commit
8e8ece7162
@ -32,7 +32,7 @@ TTF_Font *font[256];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CAP_SDL
|
#if CAP_SDL
|
||||||
SDL_Surface *s;
|
SDL_Surface *s, *s_screen;
|
||||||
|
|
||||||
int qpixel_pixel_outside;
|
int qpixel_pixel_outside;
|
||||||
|
|
||||||
@ -220,13 +220,13 @@ void selectEyeMask(int ed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGLProjection() {
|
void setGLProjection(int col) {
|
||||||
DEBB(DF_GRAPH, (debugfile,"setGLProjection\n"));
|
DEBB(DF_GRAPH, (debugfile,"setGLProjection\n"));
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
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);
|
glClearColor(c[2] / 255.0, c[1] / 255.0, c[0]/255.0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
@ -956,7 +956,7 @@ void IMAGESAVE(SDL_Surface *s, const char *fname) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hookset<void(SDL_Surface*)> *hooks_hqshot;
|
hookset<void(renderbuffer*)> *hooks_hqshot;
|
||||||
|
|
||||||
#if CAP_SDL
|
#if CAP_SDL
|
||||||
void saveHighQualityShot(const char *fname, const char *caption, int fade) {
|
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++;
|
while(vid.xres & 15) vid.xres++;
|
||||||
}
|
}
|
||||||
|
|
||||||
vid.usingGL = false;
|
|
||||||
// if(vid.pmodel == 0) vid.scale = 0.99;
|
// if(vid.pmodel == 0) vid.scale = 0.99;
|
||||||
calcparam();
|
calcparam();
|
||||||
#if CAP_ROGUEVIZ
|
#if CAP_ROGUEVIZ
|
||||||
rogueviz::fixparam();
|
rogueviz::fixparam();
|
||||||
#endif
|
#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;
|
darken = 0;
|
||||||
|
|
||||||
int numi = (fname?1:2);
|
int numi = (fname?1:2);
|
||||||
|
|
||||||
for(int i=0; i<numi; i++) {
|
for(int i=0; i<numi; i++) {
|
||||||
SDL_FillRect(s, NULL, numi==1 ? backcolor : i ? 0xFFFFFF : 0);
|
glbuf.clear(numi==1 ? backcolor : i ? 0xFFFFFF : 0);
|
||||||
drawfullmap();
|
|
||||||
|
|
||||||
callhooks(hooks_hqshot, s);
|
if(rug::rugged)
|
||||||
|
rug::drawRugScene();
|
||||||
|
else
|
||||||
|
drawfullmap();
|
||||||
|
|
||||||
|
callhooks(hooks_hqshot, &glbuf);
|
||||||
|
|
||||||
if(fade < 255)
|
if(fade < 255)
|
||||||
for(int y=0; y<vid.yres; y++)
|
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));
|
char buf[128]; strftime(buf, 128, "bigshota-%y%m%d-%H%M%S" IMAGEEXT, localtime(&timer));
|
||||||
buf[7] += i;
|
buf[7] += i;
|
||||||
if(!fname) fname = buf;
|
if(!fname) fname = buf;
|
||||||
IMAGESAVE(s, fname);
|
IMAGESAVE(glbuf.render(), fname);
|
||||||
|
|
||||||
|
|
||||||
if(i == 0) addMessage(XLAT("Saved the high quality shot to %1", fname));
|
if(i == 0) addMessage(XLAT("Saved the high quality shot to %1", fname));
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FreeSurface(s);
|
glbuf.disable();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1069,13 +1072,13 @@ void setvideomode() {
|
|||||||
|
|
||||||
int sizeflag = (vid.full ? SDL_FULLSCREEN : SDL_RESIZABLE);
|
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) {
|
if(vid.full && !s) {
|
||||||
vid.xres = vid.xscr;
|
vid.xres = vid.xscr;
|
||||||
vid.yres = vid.yscr;
|
vid.yres = vid.yscr;
|
||||||
do_setfsize();
|
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) {
|
if(!s) {
|
||||||
@ -1084,7 +1087,7 @@ void setvideomode() {
|
|||||||
vid.yres = 480;
|
vid.yres = 480;
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||||
vid.antialias &= ~AA_MULTI;
|
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
|
#if CAP_GL
|
||||||
|
@ -57,6 +57,7 @@ bool inv::on;
|
|||||||
#include "nofont.cpp"
|
#include "nofont.cpp"
|
||||||
#endif
|
#endif
|
||||||
#include "basegraph.cpp"
|
#include "basegraph.cpp"
|
||||||
|
#include "renderbuffer.cpp"
|
||||||
#include "help.cpp"
|
#include "help.cpp"
|
||||||
#include "config.cpp"
|
#include "config.cpp"
|
||||||
#include "scores.cpp"
|
#include "scores.cpp"
|
||||||
|
25
hyper.h
25
hyper.h
@ -798,7 +798,10 @@ namespace polygonal {
|
|||||||
void selectEyeGL(int ed);
|
void selectEyeGL(int ed);
|
||||||
void selectEyeMask(int ed);
|
void selectEyeMask(int ed);
|
||||||
extern int ticks;
|
extern int ticks;
|
||||||
void setGLProjection();
|
|
||||||
|
extern unsigned backcolor, bordcolor, forecolor;
|
||||||
|
|
||||||
|
void setGLProjection(int col = backcolor);
|
||||||
|
|
||||||
// passable flags
|
// passable flags
|
||||||
|
|
||||||
@ -1433,8 +1436,6 @@ extern cell *recallCell;
|
|||||||
extern eLand cheatdest;
|
extern eLand cheatdest;
|
||||||
void cheatMoveTo(eLand l);
|
void cheatMoveTo(eLand l);
|
||||||
|
|
||||||
extern unsigned backcolor, bordcolor, forecolor;
|
|
||||||
|
|
||||||
extern bool overgenerate;
|
extern bool overgenerate;
|
||||||
void doOvergenerate();
|
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);
|
bool is_cell_removed(cell *c);
|
||||||
void set_if_removed(cell*& c, cell *val);
|
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);
|
||||||
|
};
|
||||||
|
152
rug.cpp
152
rug.cpp
@ -9,28 +9,6 @@
|
|||||||
#define TEXTURESIZE (texturesize)
|
#define TEXTURESIZE (texturesize)
|
||||||
#define HTEXTURESIZE (texturesize/2)
|
#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 {
|
namespace rug {
|
||||||
|
|
||||||
struct rug_exception { };
|
struct rug_exception { };
|
||||||
@ -1083,114 +1061,32 @@ void drawTriangle(triangle& t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint FramebufferName = 0;
|
renderbuffer *glbuf;
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void prepareTexture() {
|
void prepareTexture() {
|
||||||
videopar svid = vid;
|
videopar svid = vid;
|
||||||
|
|
||||||
setVidParam();
|
setVidParam();
|
||||||
|
|
||||||
if(rendernogl) {
|
glbuf->enable();
|
||||||
vid.usingGL = false;
|
|
||||||
SDL_Surface *sav = s;
|
|
||||||
s = texture;
|
|
||||||
SDL_FillRect(s, NULL, 0);
|
|
||||||
|
|
||||||
drawfullmap();
|
glbuf->clear(0);
|
||||||
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);
|
|
||||||
|
|
||||||
setGLProjection();
|
ptds.clear();
|
||||||
ptds.clear();
|
drawthemap();
|
||||||
drawthemap();
|
if(mousing && !renderonce) {
|
||||||
if(mousing && !renderonce) {
|
for(int i=0; i<numplayers(); i++) if(multi::playerActive(i))
|
||||||
for(int i=0; i<numplayers(); i++) if(multi::playerActive(i))
|
queueline(tC0(shmup::ggmatrix(playerpos(i))), mouseh, 0xFF00FF, 8);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
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;
|
vid = svid;
|
||||||
if(!rendernogl) glViewport(0,0,vid.xres,vid.yres);
|
glbuf->disable();
|
||||||
}
|
|
||||||
|
|
||||||
void closeTexture() {
|
|
||||||
if(rendernogl) {
|
|
||||||
SDL_FreeSurface(texture);
|
|
||||||
glDeleteTextures(1, &renderedTexture);
|
|
||||||
delete[] expanded_data;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if !ISPANDORA
|
|
||||||
glDeleteTextures(1, &renderedTexture);
|
|
||||||
glDeleteRenderbuffers(1, &depth_stencil_rb);
|
|
||||||
glDeleteFramebuffers(1, &FramebufferName);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double xview, yview;
|
double xview, yview;
|
||||||
@ -1215,7 +1111,7 @@ void drawRugScene() {
|
|||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glEnable(GL_LIGHT0);
|
glEnable(GL_LIGHT0);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, renderedTexture);
|
glbuf->use_as_texture();
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@ -1310,20 +1206,10 @@ void drawRugScene() {
|
|||||||
transmatrix currentrot;
|
transmatrix currentrot;
|
||||||
|
|
||||||
void init() {
|
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;
|
if(rugged) return;
|
||||||
rugged = true;
|
rugged = true;
|
||||||
if(scale < .01 || scale > 100) scale = 1;
|
if(scale < .01 || scale > 100) scale = 1;
|
||||||
initTexture();
|
glbuf = new renderbuffer(TEXTURESIZE, TEXTURESIZE, vid.usingGL && !rendernogl);
|
||||||
if(renderonce) prepareTexture();
|
if(renderonce) prepareTexture();
|
||||||
if(!rugged) return;
|
if(!rugged) return;
|
||||||
|
|
||||||
@ -1364,7 +1250,7 @@ void init() {
|
|||||||
void close() {
|
void close() {
|
||||||
if(!rugged) return;
|
if(!rugged) return;
|
||||||
rugged = false;
|
rugged = false;
|
||||||
closeTexture();
|
delete glbuf;
|
||||||
triangles.clear();
|
triangles.clear();
|
||||||
for(int i=0; i<size(points); i++) delete points[i];
|
for(int i=0; i<size(points); i++) delete points[i];
|
||||||
points.clear();
|
points.clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user