implemented savefile screenshot feature

dev-mp
Mohamed Waheed 2014-06-24 01:35:05 +03:00
parent 99cd015dd8
commit 613e1d74c4
7 changed files with 86 additions and 6 deletions

View File

@ -418,3 +418,43 @@ bool CImage::SavePNG(const std::string& fileName)
return true; 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;
}

View File

@ -109,6 +109,12 @@ public:
//! Returns the last error //! Returns the last error
std::string GetError(); std::string GetError();
//! Flips the image vertically
void flipVertical();
//! sets/replaces the pixels from the surface
void SetDataPixels(void *pixels);
private: private:
//! Blit to new RGBA surface with given size //! Blit to new RGBA surface with given size
void BlitToNewRGBASurface(int width, int height); void BlitToNewRGBASurface(int width, int height);

View File

@ -400,6 +400,9 @@ public:
virtual void SetFillMode(FillMode mode) = 0; virtual void SetFillMode(FillMode mode) = 0;
//! Returns the current fill mode //! Returns the current fill mode
virtual FillMode GetFillMode() = 0; virtual FillMode GetFillMode() = 0;
//! Returns the pixels of the entire screen
virtual void* GetFrameBufferPixels()const = 0;
}; };

View File

@ -424,9 +424,20 @@ void CEngine::FrameUpdate()
bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height) bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height)
{ {
// TODO write screenshot: not very important for now void *pixels = m_device->GetFrameBufferPixels();
GetLogger()->Debug("CEngine::WriteSceenShot(): stub!\n"); CImage img({width,height});
img.SetDataPixels(pixels);
img.flipVertical();
if ( img.SavePNG(fileName.c_str()) ){
GetLogger()->Info("Save SceenShot Saved Successfully!\n");
return true; return true;
}
else{
GetLogger()->Error("%s!\n",img.GetError().c_str());
return false;
}
} }
bool CEngine::GetPause() bool CEngine::GetPause()

View File

@ -1791,6 +1791,23 @@ FillMode CGLDevice::GetFillMode()
return FILL_POINT; 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 } // namespace Gfx

View File

@ -188,6 +188,8 @@ public:
virtual void SetFillMode(FillMode mode) ; virtual void SetFillMode(FillMode mode) ;
virtual FillMode GetFillMode(); virtual FillMode GetFillMode();
virtual void* GetFrameBufferPixels()const;
private: private:
//! Updates internal modelview matrix //! Updates internal modelview matrix
void UpdateModelviewMatrix(); void UpdateModelviewMatrix();

View File

@ -2076,8 +2076,9 @@ bool CMainDialog::EventProcess(const Event &event)
m_shotDelay --; m_shotDelay --;
if ( m_shotDelay == 0 ) if ( m_shotDelay == 0 )
{ {
m_engine->WriteScreenShot(m_shotName, 320, 240); Math::IntPoint screenSize = m_app->GetVideoConfig().size;
//? m_engine->WriteScreenShot(m_shotName, 160, 120);
m_engine->WriteScreenShot(m_shotName, screenSize.x, screenSize.y);
} }
} }