Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
option('gl_backend',
type: 'combo',
choices: ['gl', 'gles'],
value: 'gl',
description: 'Select GL backend for examples (gl, gles)')
22 changes: 20 additions & 2 deletions src/Example.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include <thorvg-1/thorvg.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>
#ifdef TVGEXAMPLE_GLES_SUPPORTED
#include <EGL/egl.h>
#endif
#ifdef _WIN32
#include <windows.h>
#ifndef PATH_MAX
Expand Down Expand Up @@ -395,8 +398,23 @@ struct GlWindow : Window

void resize() override
{
//Set the canvas target and draw on it.
verify(static_cast<tvg::GlCanvas*>(canvas)->target(context, 0, width, height, tvg::ColorSpace::ABGR8888S));
// Set the canvas target and draw on it.
SDL_GL_MakeCurrent(window, context);

#if defined(TVGEXAMPLE_GLES_SUPPORTED)
// OpenGL ES via EGL
auto eglDisplay = eglGetCurrentDisplay();
auto eglSurface = eglGetCurrentSurface(EGL_DRAW);
verify(static_cast<tvg::GlCanvas*>(canvas)->target(eglDisplay, eglSurface, context, 0, width, height, tvg::ColorSpace::ABGR8888S));
#elif defined(_WIN32)
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
auto hdc = GetDC(wmInfo.info.win.window);
verify(static_cast<tvg::GlCanvas*>(canvas)->target(hdc, wmInfo.info.win.window, context, 0, width, height, tvg::ColorSpace::ABGR8888S));
#else
verify(static_cast<tvg::GlCanvas*>(canvas)->target(nullptr, nullptr, context, 0, width, height, tvg::ColorSpace::ABGR8888S));
#endif
}

void refresh() override
Expand Down
20 changes: 17 additions & 3 deletions src/MultiCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ void runGl()
{
#ifdef THORVG_GL_RASTER_SUPPORT

#ifdef THORVG_GL_TARGET_GLES
#ifdef TVGEXAMPLE_GLES_SUPPORTED
SDL_SetHint(SDL_HINT_OPENGL_ES_DRIVER, "1");
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
Expand All @@ -187,6 +188,7 @@ void runGl()

auto window = SDL_CreateWindow("ThorVG Example (OpenGL)", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
auto context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, context);

fglBindTexture = (PFNGLBINDTEXTUREEXTPROC)SDL_GL_GetProcAddress("glBindTexture");
fglDeleteTextures = (PFNGLDELETETEXTURESEXTPROC)SDL_GL_GetProcAddress("glDeleteTextures");
Expand All @@ -208,7 +210,19 @@ void runGl()
auto canvas = unique_ptr<tvg::GlCanvas>(tvg::GlCanvas::gen());

// Pass the framebuffer id to the GlCanvas
tvgexam::verify(canvas->target(context, glFbo.fbo, SIZE, SIZE, tvg::ColorSpace::ABGR8888S));
#if defined(TVGEXAMPLE_GLES_SUPPORTED)
auto eglDisplay = eglGetCurrentDisplay();
auto eglSurface = eglGetCurrentSurface(EGL_DRAW);
tvgexam::verify(canvas->target(eglDisplay, eglSurface, context, glFbo.fbo, SIZE, SIZE, tvg::ColorSpace::ABGR8888S));
#elif defined(_WIN32)
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
auto hdc = GetDC(wmInfo.info.win.window);
tvgexam::verify(canvas->target(hdc, wmInfo.info.win.window, context, glFbo.fbo, SIZE, SIZE, tvg::ColorSpace::ABGR8888S));
#else
tvgexam::verify(canvas->target(nullptr, nullptr, context, glFbo.fbo, SIZE, SIZE, tvg::ColorSpace::ABGR8888S));
#endif

content(canvas.get());
if (tvgexam::verify(canvas->draw())) {
Expand Down Expand Up @@ -416,4 +430,4 @@ int main(int argc, char **argv)
}

return 0;
}
}
130 changes: 130 additions & 0 deletions src/context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include "Example.h"
#ifdef TVGEXAMPLE_GLES_SUPPORTED
#include <SDL2/SDL_opengles2.h>
#else
#include <SDL2/SDL_opengl.h>
#endif
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#include <windows.h>
static HDC gHdc = nullptr;
#endif

static SDL_GLContext getCurrentContext() {
#if defined(TVGEXAMPLE_GLES_SUPPORTED)
auto fn = (SDL_GLContext(*)())SDL_GL_GetProcAddress("eglGetCurrentContext");
return fn ? fn() : SDL_GL_GetCurrentContext();
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
return (SDL_GLContext)wglGetCurrentContext();
#else
return SDL_GL_GetCurrentContext();
#endif
}

static bool makeCurrent(SDL_Window* win, SDL_GLContext ctx) {
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) && !defined(TVGEXAMPLE_GLES_SUPPORTED)
if (!gHdc) {
SDL_SysWMinfo info; SDL_VERSION(&info.version);
if (SDL_GetWindowWMInfo(win, &info)) gHdc = GetDC(info.info.win.window);
}
return wglMakeCurrent(gHdc, (HGLRC)ctx);
#else
return SDL_GL_MakeCurrent(win, ctx) == 0;
#endif
}

int main(int argc, char** argv) {
(void)argc; (void)argv;
if (!tvgexam::verify(tvg::Initializer::init(0))) return 0;
if (SDL_Init(SDL_INIT_VIDEO) != 0) { tvg::Initializer::term(); return 0; }

uint32_t w = 800, h = 800;
#ifdef TVGEXAMPLE_GLES_SUPPORTED
SDL_SetHint(SDL_HINT_OPENGL_ES_DRIVER, "1");
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
#endif
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

auto window = SDL_CreateWindow("Context", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
auto tvgCtx = window ? SDL_GL_CreateContext(window) : nullptr;
auto otherCtx = tvgCtx ? SDL_GL_CreateContext(window) : nullptr;
if (!otherCtx || !makeCurrent(window, tvgCtx)) {
if (otherCtx) SDL_GL_DeleteContext(otherCtx);
if (tvgCtx) SDL_GL_DeleteContext(tvgCtx);
if (window) SDL_DestroyWindow(window);
SDL_Quit(); tvg::Initializer::term();
return 0;
}

#if defined(TVGEXAMPLE_GLES_SUPPORTED)
auto targetCtx = getCurrentContext();
void* display = eglGetCurrentDisplay();
void* surface = eglGetCurrentSurface(EGL_DRAW);
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
auto targetCtx = getCurrentContext();
void* display = nullptr;
void* surface = gHdc;
#else
auto targetCtx = getCurrentContext();
void* display = nullptr;
void* surface = nullptr;
#endif
auto canvas = tvg::GlCanvas::gen();
if (!canvas || !tvgexam::verify(canvas->target(display, surface, targetCtx, 0, w, h, tvg::ColorSpace::ABGR8888S))) {
delete canvas;
SDL_GL_DeleteContext(otherCtx); SDL_GL_DeleteContext(tvgCtx);
SDL_DestroyWindow(window); SDL_Quit(); tvg::Initializer::term();
return 0;
}

auto ring = tvg::Shape::gen();
ring->appendCircle(0, 0, 260, 260);
ring->fill(0, 0, 0, 0);
ring->strokeFill(255, 255, 255, 255);
ring->strokeWidth(8);
ring->translate(w * 0.5f, h * 0.5f);
canvas->push(ring);

auto needle = tvg::Shape::gen();
needle->appendRect(-8, -200, 16, 140);
needle->fill(255, 140, 0, 220);
needle->translate(w * 0.5f, h * 0.5f);
canvas->push(needle);

canvas->draw(); canvas->sync();
SDL_GL_SwapWindow(window);
makeCurrent(window, otherCtx);

SDL_Event ev;
bool running = true;
auto t0 = SDL_GetTicks();
while (running) {
while (SDL_PollEvent(&ev)) {
if (ev.type == SDL_QUIT) running = false;
if (ev.type == SDL_KEYUP && ev.key.keysym.sym == SDLK_ESCAPE) running = false;
}
makeCurrent(window, otherCtx);
float t = (SDL_GetTicks() - t0) * 0.001f;
glViewport(0, 0, w, h);
glDisable(GL_SCISSOR_TEST);
glClearColor(0.15f + 0.1f*sinf(t*0.9f), 0.18f + 0.1f*sinf(t*1.1f+2), 0.22f + 0.1f*sinf(t*1.3f+4), 1);
glClear(GL_COLOR_BUFFER_BIT);

needle->rotate(t * 90);
canvas->update(); canvas->draw(false); canvas->sync();

if (getCurrentContext() != targetCtx) break;
SDL_GL_SwapWindow(window);
}

delete canvas;
SDL_GL_DeleteContext(otherCtx); SDL_GL_DeleteContext(tvgCtx);
SDL_DestroyWindow(window); SDL_Quit(); tvg::Initializer::term();
return 0;
}
25 changes: 18 additions & 7 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@ examples_dep = [thorvg_dep, dependency('sdl2', required: true)]
compiler_flags = ['-DSDL_MAIN_HANDLED']

# GL or GLES
gl_backend = get_option('gl_backend')
gl_dep = dependency('gl', required: false)
gles_dep = dependency('glesv2', required: false)
egl_dep = dependency('egl', required: false)

if gl_dep.found()
examples_dep += gl_dep
elif gles_dep.found()
examples_dep += gles_dep
compiler_flags += ['-DTVGEXAMPLE_GLES_SUPPORTED']
else
message('Neither OpenGL nor OpenGL ES was found. Skipping GL examples.')
if gl_backend == 'gl'
if gl_dep.found()
examples_dep += gl_dep
compiler_flags += ['-DTHORVG_GL_RASTER_SUPPORT']
else
message('Requested OpenGL but it was not found. Skipping GL examples.')
endif
elif gl_backend == 'gles'
if gles_dep.found() and egl_dep.found()
examples_dep += [gles_dep, egl_dep]
compiler_flags += ['-DTHORVG_GL_RASTER_SUPPORT']
compiler_flags += ['-DTVGEXAMPLE_GLES_SUPPORTED']
else
message('Requested OpenGL ES but it was not found. Skipping GL examples.')
endif
endif

# WebGPU
Expand All @@ -37,6 +47,7 @@ source_file = [
'Blending.cpp',
'BoundingBox.cpp',
'Clipping.cpp',
'context.cpp',
'CustomTransform.cpp',
'DataLoad.cpp',
'DirectUpdate.cpp',
Expand Down