Skip to content

Commit

Permalink
OpenGL: add WebGL support for ReadPixels.
Browse files Browse the repository at this point in the history
  • Loading branch information
prideout committed Jun 13, 2022
1 parent 3476429 commit 7294e7f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ A new header is inserted each time a *tag* is created.
- engine: Documentation improvements regarding SkinningBuffer and fix an off-by-one assert when setting a SkinningBuffer.
- picking is now exposed to JavaScript
- gltf_viewer: Exercise picking functionality.
- OpenGL: add WebGL support for ReadPixels

## v1.23.2

Expand Down
16 changes: 13 additions & 3 deletions filament/backend/src/opengl/OpenGLDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,7 @@ void OpenGLDriver::updateBuffer(GLBufferObject* buffer, BufferDescriptor const&
// If MapBufferRange is supported, then attempt to use that instead of BufferSubData, which
// can be quite inefficient on some platforms. Note that WebGL does not support
// MapBufferRange, but we still allow STREAM semantics for the web platform.
if (HAS_MAPBUFFERS) {
if constexpr (HAS_MAPBUFFERS) {
uint32_t offset = buffer->base + buffer->size;
offset = (offset + (alignment - 1u)) & ~(alignment - 1u);

Expand Down Expand Up @@ -2622,7 +2622,15 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
PixelBufferDescriptor& p = *pUserBuffer;
auto& gl = mContext;
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
void* vaddr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, p.size, GL_MAP_READ_BIT);
void* vaddr = nullptr;
std::unique_ptr<uint8_t> clientBuffer;
#if defined(__EMSCRIPTEN__)
clientBuffer.reset(new uint8_t(p.size));
glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, p.size, clientBuffer.get());
vaddr = clientBuffer.get();
#else
vaddr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, p.size, GL_MAP_READ_BIT);
#endif
if (vaddr) {
// now we need to flip the buffer vertically to match our API
size_t stride = p.stride ? p.stride : width;
Expand All @@ -2637,7 +2645,9 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
head += bpr;
tail -= bpr;
}
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
if (HAS_MAPBUFFERS) {
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
}
}
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glDeleteBuffers(1, &pbo);
Expand Down
7 changes: 7 additions & 0 deletions filament/backend/src/opengl/gl_headers.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@

#endif

// This is an odd duck function that exists in WebGL 2.0 but not in OpenGL ES.
#if defined(__EMSCRIPTEN__)
extern "C" {
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data);
}
#endif

#if (!defined(GL_ES_VERSION_2_0) && !defined(GL_VERSION_4_1))
#error "Minimum header version must be OpenGL ES 2.0 or OpenGL 4.1"
#endif
Expand Down

0 comments on commit 7294e7f

Please sign in to comment.