diff options
Diffstat (limited to 'smelt/sdl')
-rw-r--r-- | smelt/sdl/gfx_sdl.cpp | 101 | ||||
-rw-r--r-- | smelt/sdl/glimports.hpp | 3 | ||||
-rw-r--r-- | smelt/sdl/smelt_internal.hpp | 12 |
3 files changed, 103 insertions, 13 deletions
diff --git a/smelt/sdl/gfx_sdl.cpp b/smelt/sdl/gfx_sdl.cpp index f0dca92..1c8545f 100644 --- a/smelt/sdl/gfx_sdl.cpp +++ b/smelt/sdl/gfx_sdl.cpp @@ -91,19 +91,38 @@ bool SMELT_IMPL::smRenderEnd() pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget,primTex?(((glTexture*)primTex)->name):0); delete[] px; } + if(curTarget&&curTarget->ms) + { + glTexture *pTex=(glTexture*)curTarget->tex; + if(pTex&&pTex->lost) + configTexture(pTex,pTex->rw,pTex->rh,pTex->px); + int w=curTarget->w,h=curTarget->h; + pOpenGLDevice->glFinish(); + DWORD *px=new DWORD[w*h]; + pOpenGLDevice->glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,curTarget->frame); + pOpenGLDevice->glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,curTarget->sframe); + pOpenGLDevice->glBlitFramebufferEXT(0,0,w,h,0,0,w,h,GL_COLOR_BUFFER_BIT,GL_NEAREST); + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,curTarget->sframe); + pOpenGLDevice->glReadPixels(0,0,w,h,GL_RGBA,GL_UNSIGNED_BYTE,px); + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget,pTex->name); + pOpenGLDevice->glTexSubImage2D(pOpenGLDevice->TextureTarget,0,0,0,w,h,GL_RGBA,GL_UNSIGNED_BYTE,px); + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget,primTex?(((glTexture*)primTex)->name):0); + delete[] px; + } if(!curTarget)SDL_GL_SwapWindow((SDL_Window*)hwnd); return true; } -void SMELT_IMPL::smClrscr(DWORD color) +void SMELT_IMPL::smClrscr(DWORD color,bool clearcol,bool cleardep) { GLfloat a=(GLfloat)(GETA(color))/255.f; GLfloat r=(GLfloat)(GETR(color))/255.f; GLfloat g=(GLfloat)(GETG(color))/255.f; GLfloat b=(GLfloat)(GETB(color))/255.f; + if(clearcol) pOpenGLDevice->glClearColor(r,g,b,a); if(tdmode)pOpenGLDevice->glClearDepth(1); else if(zbufenabled)pOpenGLDevice->glClearDepth(0); - pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT|((zbufenabled||tdmode)?GL_DEPTH_BUFFER_BIT:0)); + pOpenGLDevice->glClear((clearcol?GL_COLOR_BUFFER_BIT:0)|(((zbufenabled||tdmode)&&cleardep)?GL_DEPTH_BUFFER_BIT:0)); } void SMELT_IMPL::sm3DCamera6f2v(float *pos,float *rot) { @@ -281,7 +300,7 @@ void SMELT_IMPL::smDrawCustomIndexedVertices(smVertex* vb,WORD* ib,int vbc,int i pOpenGLDevice->glTexCoordPointer(2,GL_FLOAT,sizeof(smVertex),&vertexBuf[0].tx); } } -SMTRG SMELT_IMPL::smTargetCreate(int w,int h) +SMTRG SMELT_IMPL::smTargetCreate(int w,int h,int ms) { bool ok=false; TRenderTargetList *pTarget=new TRenderTargetList; @@ -291,7 +310,7 @@ SMTRG SMELT_IMPL::smTargetCreate(int w,int h) gltex->isTarget=true;gltex->lost=false; configTexture(gltex,w,h,NULL,false); pTarget->w=w;pTarget->h=h; - ok=buildTarget(pTarget,gltex->name,w,h); + ok=buildTarget(pTarget,gltex->name,w,h,ms); if(!ok) { smLog("%s:" SLINE ": Failed to create render target.\n",GFX_SDL_SRCFN); @@ -324,6 +343,13 @@ void SMELT_IMPL::smTargetFree(SMTRG targ) if(pTarget->depth) pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->depth); pOpenGLDevice->glDeleteFramebuffersEXT(1,&pTarget->frame); + if(pTarget->ms) + { + pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->colorms); + pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->scolor); + pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->sdepth); + pOpenGLDevice->glDeleteFramebuffersEXT(1,&pTarget->sframe); + } } if(curTarget==(TRenderTargetList*)targ)curTarget=0; smTextureFree(pTarget->tex); @@ -361,7 +387,7 @@ SMTEX SMELT_IMPL::smTextureLoad(const char *path) if(!buff)return 0; rsize=fread(buff,1,size,pFile); if(rsize!=size)return 0; - ret=smTextureLoadFromMemory(buff,size); + ret=smTextureLoadFromMemory(buff,size);if(!ret)return 0; glTexture *t=(glTexture*)ret; configTexture(t,t->rw,t->rh,t->px); delete[] t->px;t->px=NULL; @@ -380,7 +406,7 @@ SMTEX SMELT_IMPL::smTextureLoadFromMemory(const char *ptr,DWORD size) TTextureList *tex=new TTextureList; tex->tex=ret;tex->w=w;tex->h=h; tex->next=textures;textures=tex; - } + }else smLog("%s:" SLINE ": Unsupported texture format.\n",GFX_SDL_SRCFN); return ret; } void SMELT_IMPL::smTextureFree(SMTEX tex) @@ -588,9 +614,57 @@ void SMELT_IMPL::bindTexture(glTexture *t) primTex=(SMTEX)t; } } -bool SMELT_IMPL::buildTarget(TRenderTargetList *pTarget,GLuint texid,int w,int h) +bool SMELT_IMPL::buildTarget(TRenderTargetList *pTarget,GLuint texid,int w,int h,int ms=0) { bool ok=true; + if(ms) + { + if(!pOpenGLDevice->have_GL_EXT_framebuffer_object|| + !pOpenGLDevice->have_GL_EXT_framebuffer_multisample|| + !pOpenGLDevice->have_GL_EXT_framebuffer_blit) + ms=0; + else + { + pOpenGLDevice->glGenFramebuffersEXT(1,&pTarget->sframe); + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,pTarget->sframe); + pOpenGLDevice->glGenRenderbuffersEXT(1,&pTarget->scolor); + pOpenGLDevice->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,pTarget->scolor); + pOpenGLDevice->glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_RGBA,w,h); + pOpenGLDevice->glGenRenderbuffersEXT(1,&pTarget->sdepth); + pOpenGLDevice->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,pTarget->sdepth); + pOpenGLDevice->glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24,w,h); + pOpenGLDevice->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_RENDERBUFFER_EXT,pTarget->scolor); + pOpenGLDevice->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT,pTarget->sdepth); + + pOpenGLDevice->glGenFramebuffersEXT(1,&pTarget->frame); + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,pTarget->frame); + pOpenGLDevice->glGenRenderbuffersEXT(1,&pTarget->colorms); + pOpenGLDevice->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,pTarget->colorms); + pOpenGLDevice->glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,ms,GL_RGBA,w,h); + pOpenGLDevice->glGenRenderbuffersEXT(1,&pTarget->depth); + pOpenGLDevice->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,pTarget->depth); + pOpenGLDevice->glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,ms,GL_DEPTH_COMPONENT24,w,h); + pOpenGLDevice->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_RENDERBUFFER_EXT,pTarget->colorms); + pOpenGLDevice->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT,pTarget->depth); + GLenum rc=pOpenGLDevice->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if((rc==GL_FRAMEBUFFER_COMPLETE_EXT)&&(pOpenGLDevice->glGetError()==GL_NO_ERROR)) + { + pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + ok=true;pTarget->ms=ms; + } + else + { + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); + pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->colorms); + pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->depth); + pOpenGLDevice->glDeleteFramebuffersEXT(1,&pTarget->frame); + pOpenGLDevice->glDeleteFramebuffersEXT(1,&pTarget->sframe); + ok=false;ms=0; + } + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,curTarget?curTarget->frame:0); + } + } + if(!ms) if(pOpenGLDevice->have_GL_EXT_framebuffer_object) { pOpenGLDevice->glGenFramebuffersEXT(1,&pTarget->frame); @@ -604,13 +678,14 @@ bool SMELT_IMPL::buildTarget(TRenderTargetList *pTarget,GLuint texid,int w,int h if((rc==GL_FRAMEBUFFER_COMPLETE_EXT)&&(pOpenGLDevice->glGetError()==GL_NO_ERROR)) { pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - ok=true; + ok=true;pTarget->ms=0; } else { pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); pOpenGLDevice->glDeleteRenderbuffersEXT(1,&pTarget->depth); pOpenGLDevice->glDeleteFramebuffersEXT(1,&pTarget->frame); + ok=false; } pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,curTarget?curTarget->frame:0); } @@ -813,6 +888,8 @@ bool SMELT_IMPL::loadGLEntryPoints() pOpenGLDevice->have_GL_EXT_framebuffer_object=true; pOpenGLDevice->have_GL_EXT_texture_compression_s3tc=false; pOpenGLDevice->have_GL_ARB_vertex_buffer_object=true; + pOpenGLDevice->have_GL_EXT_framebuffer_multisample=true; + pOpenGLDevice->have_GL_EXT_framebuffer_blit=true; #define GL_PROC(ext,fn,call,ret,params) \ if(pOpenGLDevice->have_##ext) \ { \ @@ -889,6 +966,14 @@ bool SMELT_IMPL::loadGLEntryPoints() smLog("%s:" SLINE ": OpenGL: Using GL_ARB_vertex_buffer_object.\n",GFX_SDL_SRCFN); else smLog("%s:" SLINE ": OpenGL: WARNING! No VBO support; performance may suffer.\n",GFX_SDL_SRCFN); + pOpenGLDevice->have_GL_EXT_framebuffer_multisample= + checkGLExtension(exts,"GL_EXT_framebuffer_multisample"); + pOpenGLDevice->have_GL_EXT_framebuffer_blit= + checkGLExtension(exts,"GL_EXT_framebuffer_blit"); + if(!pOpenGLDevice->have_GL_EXT_framebuffer_multisample||!pOpenGLDevice->have_GL_EXT_framebuffer_blit) + smLog("%s:" SLINE ": Multisampling is not supported.\n",GFX_SDL_SRCFN); + else + smLog("%s:" SLINE ": Multisampling is supported. Still experimental!\n",GFX_SDL_SRCFN); return true; } bool SMELT_IMPL::initOGL() diff --git a/smelt/sdl/glimports.hpp b/smelt/sdl/glimports.hpp index c16d69a..1d78071 100644 --- a/smelt/sdl/glimports.hpp +++ b/smelt/sdl/glimports.hpp @@ -49,6 +49,9 @@ GL_PROC(GL_EXT_framebuffer_object,glCheckFramebufferStatusEXT,,GLenum,(GLenum)) GL_PROC(GL_EXT_framebuffer_object,glFramebufferRenderbufferEXT,,void,(GLenum, GLenum, GLenum, GLuint)) GL_PROC(GL_EXT_framebuffer_object,glFramebufferTexture2DEXT,,void,(GLenum, GLenum, GLenum, GLuint, GLint)) +GL_PROC(GL_EXT_framebuffer_multisample,glRenderbufferStorageMultisampleEXT,,void,(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) +GL_PROC(GL_EXT_framebuffer_blit,glBlitFramebufferEXT,,void,(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) + GL_PROC(GL_ARB_vertex_buffer_object,glBindBufferARB,,void,(GLenum, GLuint)) GL_PROC(GL_ARB_vertex_buffer_object,glDeleteBuffersARB,,void,(GLsizei, const GLuint *)) GL_PROC(GL_ARB_vertex_buffer_object,glGenBuffersARB,,void,(GLsizei, GLuint *)) diff --git a/smelt/sdl/smelt_internal.hpp b/smelt/sdl/smelt_internal.hpp index 7825f51..f514c54 100644 --- a/smelt/sdl/smelt_internal.hpp +++ b/smelt/sdl/smelt_internal.hpp @@ -56,15 +56,17 @@ public: bool have_GL_EXT_framebuffer_object; bool have_GL_EXT_texture_compression_s3tc; bool have_GL_ARB_vertex_buffer_object; + bool have_GL_EXT_framebuffer_multisample; + bool have_GL_EXT_framebuffer_blit; }; struct glTexture; class TRenderTargetList { public: - int w,h; + int w,h,ms; SMTEX tex; - GLuint depth,frame; + GLuint depth,frame,colorms,sframe,sdepth,scolor; TRenderTargetList *next; }; class TTextureList @@ -147,7 +149,7 @@ public: virtual void sm3DCamera6f2v(float *pos,float *rot); virtual void sm2DCamera5f3v(float *pos,float *dpos,float *rot); virtual void smMultViewMatrix(float *mat); - virtual void smClrscr(DWORD color); + virtual void smClrscr(DWORD color,bool clearcol=true,bool cleardep=true); virtual void smRenderLinefd(float x1,float y1,float z1,float x2,float y2,float z2,DWORD color); virtual void smRenderLinefvd(float *p1,float *p2,DWORD color); virtual void smRenderTriangle(smTriangle *t); @@ -156,7 +158,7 @@ public: virtual void smDrawVertArray(int prim,SMTEX texture,int blend,int _primcnt); virtual void smDrawCustomIndexedVertices(smVertex* vb,WORD* ib,int vbc,int ibc,int blend,SMTEX texture); - virtual SMTRG smTargetCreate(int w,int h); + virtual SMTRG smTargetCreate(int w,int h,int ms=0); virtual SMTEX smTargetTexture(SMTRG targ); virtual void smTargetFree(SMTRG targ); @@ -214,7 +216,7 @@ public: void batchOGL(bool endScene=false); void configTexture(glTexture *t,int w,int h,DWORD *px,bool compress=true); void bindTexture(glTexture *t); - bool buildTarget(TRenderTargetList *pTarget,GLuint texid,int w,int h); + bool buildTarget(TRenderTargetList *pTarget,GLuint texid,int w,int h,int ms); SMTEX buildTexture(int w,int h,DWORD *px); void setBlend(int blend); void configProjectionMatrix2D(int w,int h); |