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;

/**
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.
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
{
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
{
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
{
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);
}

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

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

if (view == nullptr)
return;
@@ -744,6 +749,14 @@ void Window::PrivateData::onPuglExpose()
widget->pData->display();
}
#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()


+ 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. */
bool ignoreIdleCallbacks;

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

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

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

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


Loading…
Cancel
Save