Joined: Apr 2008
Posts: 1860
|
Hi. I went back to finish some of the surface functions I was working on, and I still can't figure this one out. I have this code:
int sprite_create_from_surface(int id,int x,int y,int w,int h,bool removeback,bool smooth,int xorig,int yorig) { enigma::surface* surf=enigma::surface_array[id]; int sprid=enigma::sprite_idmax, full_width=nlpo2dc(w)+1, full_height=nlpo2dc(h)+1; enigma::sprite_new_empty(sprid, 1, w, h, xorig, yorig, 0, h, 0, w, 1,0);
unsigned sz=full_width*full_height; unsigned char *surfbuf=new unsigned char[sz*4]; int prevFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prevFbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surf->fbo); glReadPixels(x,y,w,h,GL_RGBA,GL_UNSIGNED_BYTE,surfbuf); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFbo);
enigma::sprite_set_subimage(sprid, 0, xorig, yorig, w, h, surfbuf); delete[] surfbuf; return sprid; }
Pretty simple, and it works. The problem is that it breaks after certain amount of usage. For me this breaks when I execute it 4 times. Then artifacts appear on the surface (when something is drawn on it). After fifth time the artifacts become more massive (like solid rectangles) and after that the surface just becomes totally solid color. The game doesn't break though (no freezing) so I don't think I overwrite anything important, but I do overwrite something. So, ideas?
Also, I guess I could put this here as well: I have made surface_save and surface_save_part functions. The problem is that the output bmp is vertically flipped. I used basically the same function that is used to save the screen and it works right there. This functions is like so:
int surface_save(int id, string filename) { FILE *bmp=fopen(filename.c_str(),"wb"); if(!bmp) return -1; enigma::surface* surf=enigma::surface_array[id]; unsigned int w=surf->width,h=surf->height,sz=w*h; char *surfbuf=new char[sz*3]; int prevFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prevFbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surf->fbo); glReadPixels(0,0,w,h,GL_BGR,GL_UNSIGNED_BYTE,surfbuf); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFbo); fwrite("BM",2,1,bmp); sz<<=2;
fwrite(&sz,4,1,bmp); fwrite("\0\0\0\0\x36\0\0\0\x28\0\0",12,1,bmp); fwrite(&w,4,1,bmp); fwrite(&h,4,1,bmp); fwrite("\1\0\x18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",28,1,bmp);
if(w&3) { size_t pad=w&3; w*=3; sz-=sz>>2; for(unsigned int i=0;i<sz;i+=w) { fwrite(surfbuf+i,w,1,bmp); fwrite("\0\0",pad,1,bmp); } } else fwrite(surfbuf,w*3,h,bmp); fclose(bmp); delete[] surfbuf; return 1; } Also, I would want to know how png's could be saved. ENIGMA already uses zlib for that I think, so maybe we could add two functions like: save_texture_bmp and save_texture_png. Then saving surfaces, backgrounds and sprites would be identical and would only require a small wrapping function.
|