Browse Source

Add method to render window contents to picture file (opengl)

pull/327/head
falkTX 3 years ago
parent
commit
07e8cee925
7 changed files with 72 additions and 0 deletions
  1. +7
    -0
      dgl/Window.hpp
  2. +7
    -0
      dgl/src/Cairo.cpp
  3. +28
    -0
      dgl/src/OpenGL.cpp
  4. +7
    -0
      dgl/src/Vulkan.cpp
  5. +5
    -0
      dgl/src/Window.cpp
  6. +13
    -0
      dgl/src/WindowPrivateData.cpp
  7. +5
    -0
      dgl/src/WindowPrivateData.hpp

+ 7
- 0
dgl/Window.hpp View File

@@ -382,6 +382,13 @@ public:
*/ */
void repaint(const Rectangle<uint>& rect) noexcept; void repaint(const Rectangle<uint>& rect) noexcept;


/**
Render this window's content into a picture file, specified by @a filename.
Window must be visible and on screen.
Written picture format is PPM.
*/
void renderToPicture(const char* filename);

/** /**
Run this window as a modal, blocking input events from the parent. Run this window as a modal, blocking input events from the parent.
Only valid for windows that have been created with another window as parent (as passed in the constructor). Only valid for windows that have been created with another window as parent (as passed in the constructor).


+ 7
- 0
dgl/src/Cairo.cpp View File

@@ -808,6 +808,13 @@ void TopLevelWidget::PrivateData::display()


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


void Window::PrivateData::renderToPicture(const char*, const GraphicsContext&, uint, uint)
{
notImplemented("Window::PrivateData::renderToPicture");
}

// -----------------------------------------------------------------------

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{ {
GraphicsContext& context((GraphicsContext&)graphicsContext); GraphicsContext& context((GraphicsContext&)graphicsContext);


+ 28
- 0
dgl/src/OpenGL.cpp View File

@@ -667,6 +667,34 @@ void TopLevelWidget::PrivateData::display()


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


void Window::PrivateData::renderToPicture(const char* const filename,
const GraphicsContext&,
const uint width,
const uint height)
{
FILE* const f = fopen(filename, "w");
DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,);

GLubyte* const pixels = new GLubyte[width * height * 3 * sizeof(GLubyte)];

glFlush();
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

fprintf(f, "P3\n%d %d\n255\n", width, height);
for (uint y = 0; y < height; y++) {
for (uint i, x = 0; x < width; x++) {
i = 3 * ((height - y - 1) * width + x);
fprintf(f, "%3d %3d %3d ", pixels[i], pixels[i+1], pixels[i+2]);
}
fprintf(f, "\n");
}

delete[] pixels;
fclose(f);
}

// -----------------------------------------------------------------------

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{ {
return (const GraphicsContext&)graphicsContext; return (const GraphicsContext&)graphicsContext;


+ 7
- 0
dgl/src/Vulkan.cpp View File

@@ -231,6 +231,13 @@ void TopLevelWidget::PrivateData::display()


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


void Window::PrivateData::renderToPicture(const char*, const GraphicsContext&, uint, uint)
{
notImplemented("Window::PrivateData::renderToPicture");
}

// -----------------------------------------------------------------------

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{ {
return (const GraphicsContext&)graphicsContext; return (const GraphicsContext&)graphicsContext;


+ 5
- 0
dgl/src/Window.cpp View File

@@ -336,6 +336,11 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept
puglPostRedisplayRect(pData->view, prect); puglPostRedisplayRect(pData->view, prect);
} }


void Window::renderToPicture(const char* const filename)
{
pData->filenameToRenderInto = strdup(filename);
}

void Window::runAsModal(bool blockWait) void Window::runAsModal(bool blockWait)
{ {
pData->runAsModal(blockWait); pData->runAsModal(blockWait);


+ 13
- 0
dgl/src/WindowPrivateData.cpp View File

@@ -95,6 +95,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s)
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -120,6 +121,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -149,6 +151,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -180,6 +183,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -195,6 +199,7 @@ Window::PrivateData::~PrivateData()
{ {
appData->idleCallbacks.remove(this); appData->idleCallbacks.remove(this);
appData->windows.remove(self); appData->windows.remove(self);
std::free(filenameToRenderInto);


if (view == nullptr) if (view == nullptr)
return; return;
@@ -744,6 +749,14 @@ void Window::PrivateData::onPuglExpose()
widget->pData->display(); widget->pData->display();
} }
#endif #endif

if (char* const filename = filenameToRenderInto)
{
const PuglRect rect = puglGetFrame(view);
filenameToRenderInto = nullptr;
renderToPicture(filename, getGraphicsContext(), static_cast<uint>(rect.width), static_cast<uint>(rect.height));
std::free(filename);
}
} }


void Window::PrivateData::onPuglClose() void Window::PrivateData::onPuglClose()


+ 5
- 0
dgl/src/WindowPrivateData.hpp View File

@@ -77,6 +77,9 @@ struct Window::PrivateData : IdleCallback {
/** Whether to ignore idle callback requests, useful for temporary windows. */ /** Whether to ignore idle callback requests, useful for temporary windows. */
bool ignoreIdleCallbacks; bool ignoreIdleCallbacks;


/** Render to a picture file when non-null, automatically free+unset after saving. */
char* filenameToRenderInto;

#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
/** Selected file for openFileBrowser on windows, stored for fake async operation. */ /** Selected file for openFileBrowser on windows, stored for fake async operation. */
const char* win32SelectedFile; const char* win32SelectedFile;
@@ -162,6 +165,8 @@ struct Window::PrivateData : IdleCallback {
# endif # endif
#endif #endif


static void renderToPicture(const char* filename, const GraphicsContext& context, uint width, uint height);

// modal handling // modal handling
void startModal(); void startModal();
void stopModal(); void stopModal();


Loading…
Cancel
Save