summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamed Waheed <mohamedwaheedmohamed@gmail.com>2014-06-24 01:35:05 +0300
committerMohamed Waheed <mohamedwaheedmohamed@gmail.com>2014-06-24 01:35:05 +0300
commit613e1d74c47cf3a756af9aff75575c7567699381 (patch)
treec0cd765cf6983c9be95b81e2aeefeadece9d2b27
parent99cd015dd89f0928246d1178c5641ebe325fe997 (diff)
downloadcolobot-613e1d74c47cf3a756af9aff75575c7567699381.tar.gz
colobot-613e1d74c47cf3a756af9aff75575c7567699381.tar.bz2
colobot-613e1d74c47cf3a756af9aff75575c7567699381.zip
implemented savefile screenshot feature
-rw-r--r--src/common/image.cpp40
-rw-r--r--src/common/image.h6
-rw-r--r--src/graphics/core/device.h3
-rw-r--r--src/graphics/engine/engine.cpp17
-rw-r--r--src/graphics/opengl/gldevice.cpp17
-rw-r--r--src/graphics/opengl/gldevice.h2
-rw-r--r--src/ui/maindialog.cpp7
7 files changed, 86 insertions, 6 deletions
diff --git a/src/common/image.cpp b/src/common/image.cpp
index 8a876e3..ff5e42c 100644
--- a/src/common/image.cpp
+++ b/src/common/image.cpp
@@ -418,3 +418,43 @@ bool CImage::SavePNG(const std::string& fileName)
return true;
}
+void CImage::SetDataPixels(void *pixels){
+
+ if (m_data != nullptr){
+
+ if (m_data->surface != nullptr)
+ {
+ if ( m_data->surface->pixels != nullptr ){
+ unsigned int* pixels = static_cast<unsigned int*>(m_data->surface->pixels);
+ delete [] pixels;
+ m_data->surface->pixels = nullptr;
+ }
+ }
+ }
+
+ m_data->surface->pixels = pixels;
+}
+
+void CImage::flipVertical(){
+
+ SDL_Surface* result = SDL_CreateRGBSurface(m_data->surface->flags, m_data->surface->w, m_data->surface->h,
+ m_data->surface->format->BytesPerPixel * 8, m_data->surface->format->Rmask, m_data->surface->format->Gmask,
+ m_data->surface->format->Bmask, m_data->surface->format->Amask);
+
+ assert(result != nullptr);
+
+ Uint8* srcPixels = static_cast<Uint8*> (m_data->surface->pixels);
+ Uint8* resultPixels = static_cast<Uint8*> (result->pixels);
+
+ Uint32 pitch = m_data->surface->pitch;
+ Uint32 pxLength = pitch*m_data->surface->h;
+
+ for(int line = 0; line < m_data->surface->h; ++line) {
+ Uint32 pos = line * pitch;
+ memcpy(&resultPixels[pos], &srcPixels[(pxLength-pos)-pitch], pitch);
+ }
+
+ SDL_FreeSurface(m_data->surface);
+
+ m_data->surface = result;
+} \ No newline at end of file
diff --git a/src/common/image.h b/src/common/image.h
index 31dab2d..afbebc2 100644
--- a/src/common/image.h
+++ b/src/common/image.h
@@ -109,6 +109,12 @@ public:
//! Returns the last error
std::string GetError();
+ //! Flips the image vertically
+ void flipVertical();
+
+ //! sets/replaces the pixels from the surface
+ void SetDataPixels(void *pixels);
+
private:
//! Blit to new RGBA surface with given size
void BlitToNewRGBASurface(int width, int height);
diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h
index 4c1189c..a896104 100644
--- a/src/graphics/core/device.h
+++ b/src/graphics/core/device.h
@@ -400,6 +400,9 @@ public:
virtual void SetFillMode(FillMode mode) = 0;
//! Returns the current fill mode
virtual FillMode GetFillMode() = 0;
+
+ //! Returns the pixels of the entire screen
+ virtual void* GetFrameBufferPixels()const = 0;
};
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index d6e4415..9216fb0 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -424,9 +424,20 @@ void CEngine::FrameUpdate()
bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height)
{
- // TODO write screenshot: not very important for now
- GetLogger()->Debug("CEngine::WriteSceenShot(): stub!\n");
- return true;
+ void *pixels = m_device->GetFrameBufferPixels();
+ CImage img({width,height});
+
+ img.SetDataPixels(pixels);
+ img.flipVertical();
+
+ if ( img.SavePNG(fileName.c_str()) ){
+ GetLogger()->Info("Save SceenShot Saved Successfully!\n");
+ return true;
+ }
+ else{
+ GetLogger()->Error("%s!\n",img.GetError().c_str());
+ return false;
+ }
}
bool CEngine::GetPause()
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 9f64fab..57738a6 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -1791,6 +1791,23 @@ FillMode CGLDevice::GetFillMode()
return FILL_POINT;
}
+void* CGLDevice::GetFrameBufferPixels()const{
+
+ SDL_Surface* surface = SDL_GetVideoSurface();
+
+ assert(surface != nullptr);
+
+ GLubyte* pixels = new GLubyte [4 * surface->h * surface->w];
+
+ glReadPixels(0,0,surface->w,surface->h,GL_RGBA,GL_UNSIGNED_BYTE,pixels);
+
+ unsigned int* p = static_cast<unsigned int*> ( static_cast<void*>(pixels) );
+
+ for (int i = 0; i < surface->h * surface->w; ++i)
+ p[i] |= 0xFF000000;
+
+ return static_cast<void*>(p);
+}
} // namespace Gfx
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index c648161..267ee73 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -188,6 +188,8 @@ public:
virtual void SetFillMode(FillMode mode) ;
virtual FillMode GetFillMode();
+ virtual void* GetFrameBufferPixels()const;
+
private:
//! Updates internal modelview matrix
void UpdateModelviewMatrix();
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
index 1964531..784cd59 100644
--- a/src/ui/maindialog.cpp
+++ b/src/ui/maindialog.cpp
@@ -2075,9 +2075,10 @@ bool CMainDialog::EventProcess(const Event &event)
{
m_shotDelay --;
if ( m_shotDelay == 0 )
- {
- m_engine->WriteScreenShot(m_shotName, 320, 240);
- //? m_engine->WriteScreenShot(m_shotName, 160, 120);
+ {
+ Math::IntPoint screenSize = m_app->GetVideoConfig().size;
+
+ m_engine->WriteScreenShot(m_shotName, screenSize.x, screenSize.y);
}
}