sokol: add screenshot function to OpenGL based backends (#12169)
parent
97e999768a
commit
5bfa3d5530
|
@ -4657,7 +4657,9 @@ _SOKOL_PRIVATE void _sg_dummy_update_image(_sg_image_t* img, const sg_image_data
|
||||||
#if defined(_SOKOL_USE_WIN32_GL_LOADER)
|
#if defined(_SOKOL_USE_WIN32_GL_LOADER)
|
||||||
|
|
||||||
// X Macro list of GL function names and signatures
|
// X Macro list of GL function names and signatures
|
||||||
|
// __v_ start
|
||||||
#define _SG_GL_FUNCS \
|
#define _SG_GL_FUNCS \
|
||||||
|
_SG_XMACRO(glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * data)) \
|
||||||
_SG_XMACRO(glBindVertexArray, void, (GLuint array)) \
|
_SG_XMACRO(glBindVertexArray, void, (GLuint array)) \
|
||||||
_SG_XMACRO(glFramebufferTextureLayer, void, (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)) \
|
_SG_XMACRO(glFramebufferTextureLayer, void, (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)) \
|
||||||
_SG_XMACRO(glGenFramebuffers, void, (GLsizei n, GLuint * framebuffers)) \
|
_SG_XMACRO(glGenFramebuffers, void, (GLsizei n, GLuint * framebuffers)) \
|
||||||
|
@ -4754,6 +4756,7 @@ _SOKOL_PRIVATE void _sg_dummy_update_image(_sg_image_t* img, const sg_image_data
|
||||||
_SG_XMACRO(glGenVertexArrays, void, (GLsizei n, GLuint * arrays)) \
|
_SG_XMACRO(glGenVertexArrays, void, (GLsizei n, GLuint * arrays)) \
|
||||||
_SG_XMACRO(glFrontFace, void, (GLenum mode)) \
|
_SG_XMACRO(glFrontFace, void, (GLenum mode)) \
|
||||||
_SG_XMACRO(glCullFace, void, (GLenum mode))
|
_SG_XMACRO(glCullFace, void, (GLenum mode))
|
||||||
|
// __v_ end
|
||||||
|
|
||||||
// generate GL function pointer typedefs
|
// generate GL function pointer typedefs
|
||||||
#define _SG_XMACRO(name, ret, args) typedef ret (GL_APIENTRY* PFN_ ## name) args;
|
#define _SG_XMACRO(name, ret, args) typedef ret (GL_APIENTRY* PFN_ ## name) args;
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES2) || defined(SOKOL_GLES3)
|
||||||
|
void v_sapp_gl_read_rgba_pixels(int x, int y, int width, int height, unsigned char* pixels) {
|
||||||
|
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void v_sapp_gl_read_rgba_pixels(int x, int y, int width, int height, unsigned char* pixels) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -17,4 +17,3 @@
|
||||||
#define printf(...) __android_log_print(ANDROID_LOG_INFO, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
|
#define printf(...) __android_log_print(ANDROID_LOG_INFO, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
|
||||||
#define fprintf(a, ...) __android_log_print(ANDROID_LOG_ERROR, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
|
#define fprintf(a, ...) __android_log_print(ANDROID_LOG_ERROR, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,10 +49,11 @@ $if gcboehm ? {
|
||||||
#define SOKOL_FREE GC_FREE
|
#define SOKOL_FREE GC_FREE
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "sokol_v.h"
|
#include "sokol_v.pre.h"
|
||||||
#include "sokol_app.h"
|
#include "sokol_app.h"
|
||||||
#define SOKOL_IMPL
|
#define SOKOL_IMPL
|
||||||
#define SOKOL_NO_DEPRECATED
|
#define SOKOL_NO_DEPRECATED
|
||||||
#include "sokol_gfx.h"
|
#include "sokol_gfx.h"
|
||||||
#define SOKOL_GL_IMPL
|
#define SOKOL_GL_IMPL
|
||||||
#include "util/sokol_gl.h"
|
#include "util/sokol_gl.h"
|
||||||
|
#include "sokol_v.post.h"
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
module sapp
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
// v_sapp_gl_read_rgba_pixels reads pixles from the OpenGL buffer into `pixels`.
|
||||||
|
fn C.v_sapp_gl_read_rgba_pixels(x int, y int, width int, height int, pixels charptr)
|
||||||
|
|
||||||
|
// screenshot takes a screenshot of the current window.
|
||||||
|
[inline]
|
||||||
|
pub fn screenshot(path string) ? {
|
||||||
|
if !path.ends_with('.ppm') {
|
||||||
|
return error(@MOD + '.' + @FN + ' currently only supports .ppm files.')
|
||||||
|
}
|
||||||
|
|
||||||
|
w := width()
|
||||||
|
h := height()
|
||||||
|
|
||||||
|
size := w * h * 4 //
|
||||||
|
mut pixels := []byte{len: size, init: 0}
|
||||||
|
|
||||||
|
C.v_sapp_gl_read_rgba_pixels(0, 0, w, h, pixels.data)
|
||||||
|
|
||||||
|
// TODO use separate thread for writing the data
|
||||||
|
// TODO use stbi to support more formats
|
||||||
|
// stbi.write_png(path, w, h, components, pixels.data, 3 * w)
|
||||||
|
// stbi.write_tga(path, w, h, components, pixels.data)
|
||||||
|
write_rgba_to_ppm(path, w, h, 4, pixels) ?
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pixels.free()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write_rgba_to_ppm writes `pixels` data in RGBA format to PPM3 format.
|
||||||
|
fn write_rgba_to_ppm(path string, w int, h int, components int, pixels []byte) ? {
|
||||||
|
mut f_out := os.create(path) ?
|
||||||
|
f_out.writeln('P3') ?
|
||||||
|
f_out.writeln('$w $h') ?
|
||||||
|
f_out.writeln('255') ?
|
||||||
|
for i := h - 1; i >= 0; i-- {
|
||||||
|
for j := 0; j < w; j++ {
|
||||||
|
idx := i * w * components + j * components
|
||||||
|
r := int(pixels[idx])
|
||||||
|
g := int(pixels[idx + 1])
|
||||||
|
b := int(pixels[idx + 2])
|
||||||
|
f_out.write_string('$r $g $b ') ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_out.close()
|
||||||
|
}
|
Loading…
Reference in New Issue