From 87a25aa8fd3cb5a67747bff63711338e0f88b7c3 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Tue, 28 Apr 2020 22:06:12 +0800 Subject: Added routines needed for off-screen rendering. Make implementation-specific stuff actually private. Move glfw callbacks into a class. Correct misspelt words. --- include/smelt.hpp | 13 +++++++-- smelt/glfw/smelt_internal.hpp | 9 ++++-- smelt/glfw/sys_glfw.cpp | 65 ++++++++++++++++++++++++++++--------------- 3 files changed, 58 insertions(+), 29 deletions(-) diff --git a/include/smelt.hpp b/include/smelt.hpp index 136ad28..e078420 100644 --- a/include/smelt.hpp +++ b/include/smelt.hpp @@ -173,7 +173,7 @@ public: /** * Enters the main loop. * The main loop calls update function, focus gain function, focus - * lost function and quit function periodally, handles input events + * lost function and quit function periodically, handles input events * and flushes the buffers. * Requires the UpdateFunc set and the initialization of the SMELT * interface. @@ -242,7 +242,7 @@ public: * Take care with fullscreen video modes. Inappropriate fullscreen * resolutions will cause the failure of smInit(). */ - virtual void smVidMode(int resX,int resY,bool _windowed)=0; + virtual void smVidMode(int resX,int resY,bool _windowed,bool showWindow=true)=0; /* * Sets the log file path. * The default value is empty. @@ -257,8 +257,15 @@ public: /* * Saves the content of the application window to the given path. * The picture is saved in the BMP format. + * Deprecated. Not implemented at all in the GLFW version. */ virtual void smScreenShot(const char* path)=0; + /* + * Copy pixels from the current rendering target to the address pointed by px. + * The copied region is a rectangle originating from (origx,origy), having a width + * of w and hight of h. sz denotes the maximum number of bytes written to px. + */ + virtual void smPixelCopy(int origx,int origy,size_t w,size_t h,size_t sz,void* px)=0; /* * Sets the desired FPS value. The macros FPS_* can be used @@ -288,7 +295,7 @@ public: * Load a single sound file into memory. * Currently only ogg and wav files are supported. * This function loads and decodes the ogg data, which may take - * noticeable time to complete. Consider running it in a seperate + * noticeable time to complete. Consider running it in a separate * thread if you are loading a larger file. * Returns the SFX handle on success, or 0 on failure. */ diff --git a/smelt/glfw/smelt_internal.hpp b/smelt/glfw/smelt_internal.hpp index 72d09cb..5b8d5db 100644 --- a/smelt/glfw/smelt_internal.hpp +++ b/smelt/glfw/smelt_internal.hpp @@ -101,10 +101,11 @@ public: virtual void smWinTitle(const char* title); virtual bool smIsActive(); virtual void smNoSuspend(bool para); - virtual void smVidMode(int resX,int resY,bool _windowed); + virtual void smVidMode(int resX,int resY,bool _windowed,bool showWindow=true); virtual void smLogFile(const char* path); virtual void smLog(const char* format,...); virtual void smScreenShot(const char* path); + virtual void smPixelCopy(int origx,int origy,size_t w,size_t h,size_t sz,void* px); virtual void smSetFPS(int fps); virtual float smGetFPS(); @@ -175,8 +176,9 @@ public: virtual int smTextureGetHeight(SMTEX tex,bool original=false); virtual DWORD* smTextureLock(SMTEX tex,int l,int t,int w,int h,bool ro=true); virtual void smTexutreUnlock(SMTEX tex); -//internal routines&variables... + static SMELT_IMPL* getInterface(); +private: void focusChange(bool actif); void *hwnd; @@ -263,8 +265,9 @@ public: DWORD fixDelta,t0; int fcnt; DWORD dt; -private: SMELT_IMPL(); + + friend class glfwHandlers; }; extern SMELT_IMPL *pSM; #endif diff --git a/smelt/glfw/sys_glfw.cpp b/smelt/glfw/sys_glfw.cpp index 86be958..bca71c9 100644 --- a/smelt/glfw/sys_glfw.cpp +++ b/smelt/glfw/sys_glfw.cpp @@ -16,13 +16,17 @@ int refcnt=0; SMELT_IMPL *pSM=0; char lasterr[1024]; -void glfwErrorHandler(int err,const char* desc); -void glfwFocChangeHandler(GLFWwindow*,int foc); -void glfwCursorEnterHandler(GLFWwindow*,int ent); -void glfwKBEventHandler(GLFWwindow* window,int key,int scancode,int action,int mods); -void glfwMouseButtonHandler(GLFWwindow* w,int btn,int action,int mods); -void glfwMouseMotionHandler(GLFWwindow*,double x,double y); -void glfwMouseWheelHandler(GLFWwindow* w,double x,double y); +class glfwHandlers +{ +public: + static void glfwErrorHandler(int err,const char* desc); + static void glfwFocChangeHandler(GLFWwindow*,int foc); + static void glfwCursorEnterHandler(GLFWwindow*,int ent); + static void glfwKBEventHandler(GLFWwindow* window,int key,int scancode,int action,int mods); + static void glfwMouseButtonHandler(GLFWwindow* w,int btn,int action,int mods); + static void glfwMouseMotionHandler(GLFWwindow*,double x,double y); + static void glfwMouseWheelHandler(GLFWwindow* w,double x,double y); +}; SMELT* smGetInterface(int apilevel) { @@ -110,7 +114,7 @@ bool SMELT_IMPL::smInit() smLog("%s:" SLINE ": RAM: %ukB installed, %ukB free\n",SYS_GLFW_SRCFN,totalm,freem); fclose(a); #endif - glfwSetErrorCallback(glfwErrorHandler); + glfwSetErrorCallback(glfwHandlers::glfwErrorHandler); if(!glfwInit()) { smLog("%s:" SLINE ": glfwInit() failed with error %s\n",SYS_GLFW_SRCFN,lasterr); @@ -150,12 +154,12 @@ bool SMELT_IMPL::smInit() if(!pSM->Active)pSM->focusChange(true); } if(hideMouse)glfwSetInputMode(screen,GLFW_CURSOR,GLFW_CURSOR_HIDDEN); - glfwSetWindowFocusCallback(screen,glfwFocChangeHandler); - glfwSetCursorEnterCallback(screen,glfwCursorEnterHandler); - glfwSetKeyCallback(screen,glfwKBEventHandler); - glfwSetCursorPosCallback(screen,glfwMouseMotionHandler); - glfwSetMouseButtonCallback(screen,glfwMouseButtonHandler); - glfwSetScrollCallback(screen,glfwMouseWheelHandler); + glfwSetWindowFocusCallback(screen,glfwHandlers::glfwFocChangeHandler); + glfwSetCursorEnterCallback(screen,glfwHandlers::glfwCursorEnterHandler); + glfwSetKeyCallback(screen,glfwHandlers::glfwKBEventHandler); + glfwSetCursorPosCallback(screen,glfwHandlers::glfwMouseMotionHandler); + glfwSetMouseButtonCallback(screen,glfwHandlers::glfwMouseButtonHandler); + glfwSetScrollCallback(screen,glfwHandlers::glfwMouseWheelHandler); initInput(); if(!initOGL()){smFinale();return false;} if(!initOAL()){smFinale();return false;} @@ -214,10 +218,17 @@ void SMELT_IMPL::smQuitFunc(smHandler* h){quitHandler=h;} void SMELT_IMPL::smWinTitle(const char *title){strcpy(winTitle,title);} bool SMELT_IMPL::smIsActive(){return Active;} void SMELT_IMPL::smNoSuspend(bool para){noSuspend=para;} -void SMELT_IMPL::smVidMode(int resX,int resY,bool _windowed) +void SMELT_IMPL::smVidMode(int resX,int resY,bool _windowed,bool showWindow) { if(vertexArray)return; - if(!pOpenGLDevice)scrw=resX,scrh=resY,windowed=_windowed; + if(!pOpenGLDevice) + { + scrw=resX; + scrh=resY; + windowed=_windowed; + if(!showWindow) + glfwWindowHint(GLFW_VISIBLE,GLFW_FALSE); + } else if(windowed!=_windowed) { windowed=_windowed; @@ -248,6 +259,14 @@ void SMELT_IMPL::smScreenShot(const char* path) //glReadPixels(0,0,screen->w,screen->h,GL_RGB,GL_UNSIGNED_BYTE,surface->pixels); } } +void SMELT_IMPL::smPixelCopy(int origx,int origy,size_t w,size_t h,size_t sz,void *px) +{ + if(pOpenGLDevice) + { + glFinish(); + glReadnPixels(0,0,w,h,GL_RGBA,GL_UNSIGNED_BYTE,sz,px); + } +} void SMELT_IMPL::smSetFPS(int fps) { vsync=(fps==FPS_VSYNC); @@ -293,19 +312,19 @@ bool SMELT_IMPL::procGLFWEvent() } return true; } -void glfwErrorHandler(int err,const char* desc) +void glfwHandlers::glfwErrorHandler(int err,const char* desc) { strcpy(lasterr,desc); } -void glfwFocChangeHandler(GLFWwindow*,int foc) +void glfwHandlers::glfwFocChangeHandler(GLFWwindow*,int foc) { pSM->focusChange(foc); } -void glfwCursorEnterHandler(GLFWwindow*,int ent) +void glfwHandlers::glfwCursorEnterHandler(GLFWwindow*,int ent) { pSM->mouseOver=ent; } -void glfwKBEventHandler(GLFWwindow* window,int key,int scancode,int action,int mods) +void glfwHandlers::glfwKBEventHandler(GLFWwindow* window,int key,int scancode,int action,int mods) { if(action==GLFW_RELEASE) { @@ -320,7 +339,7 @@ void glfwKBEventHandler(GLFWwindow* window,int key,int scancode,int action,int m pSM->buildEvent(INPUT_KEYDOWN,key,0,0,-1,-1); } } -void glfwMouseButtonHandler(GLFWwindow* w,int btn,int action,int mods) +void glfwHandlers::glfwMouseButtonHandler(GLFWwindow* w,int btn,int action,int mods) { double x,y;glfwGetCursorPos(w,&x,&y); if(action==GLFW_PRESS) @@ -342,11 +361,11 @@ void glfwMouseButtonHandler(GLFWwindow* w,int btn,int action,int mods) pSM->buildEvent(INPUT_MBUTTONUP,SMK_MBUTTON,0,0,x,y); } } -void glfwMouseMotionHandler(GLFWwindow*,double x,double y) +void glfwHandlers::glfwMouseMotionHandler(GLFWwindow*,double x,double y) { pSM->buildEvent(INPUT_MOUSEMOVE,0,0,0,x,y); } -void glfwMouseWheelHandler(GLFWwindow* w,double x,double y) +void glfwHandlers::glfwMouseWheelHandler(GLFWwindow* w,double x,double y) { double cx,cy;glfwGetCursorPos(w,&cx,&cy); if(y>0)pSM->buildEvent(INPUT_MOUSEWHEEL,1,0,0,cx,cy); -- cgit v1.2.3