Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mesa/demos
  • skirk/demos
  • inequation/demos
  • kusma/mesa-demos
  • ajax/demos
  • ofourdan/demos
  • austriancoder/demos
  • eric/demos
  • jakogut/demos
  • frohlich/demos
  • dbaker/demos
  • challenzhou/demos
  • jrfonseca/demos
  • orbea/demos
  • mupuf/demos
  • xantares/demos
  • kevinoid/demos
  • theozzhh79/demos
  • EthanHsieh/demos
  • tantan/demos
  • baryluk/demos
  • siyueyinghua/demos
  • hch12907/mesa-demos
  • jljusten/mesa-demos
  • ydirson/demos
  • birdspider/demos
  • alex.kanavin/demos
  • airlied/demos
  • alanc/demos
  • lygstate/demos
  • vsyrjala/mesa-demos
  • stolk/demos
  • qyliss/demos
  • antonino/demos
  • ccawley2011/mesa-demos
  • psykose1/demos
  • dh/demos
  • robertfoss/demos
  • yselkowitz1/mesa-demos
  • Robin329/demos
  • blaztinn/demos
  • ella/demos
  • sima/mesa-demos
  • mstoeckl/demos
  • mildsunrise/mesa-demos
  • duncan.hopkins/demos
  • lucmann/demos
  • pleasurefish/demos
  • mattst88/demos
  • emendoz/mesa-demos
  • LDVSOFT/demos
  • zmike/demos
  • DDoSQc/demos
  • jadahl/mesa-demos
  • wujiansun/demos
55 results
Show changes
Showing
with 53 additions and 4037 deletions
include_directories(
${EGL_INCLUDE_DIRS}
${GLESV1_INCLUDE_DIRS}
${VG_INCLUDE_DIRS}
)
set (subdir egl/oes_vg)
set (targets
tex2vgimage
vgimage2tex
)
if (X11_FOUND)
foreach (target ${targets})
add_executable (${target} ${target}.c)
target_link_libraries (${target} ${VG_LIBRARIES} ${GLESV1_LIBRARIES} ${EGL_LIBRARIES} ${X11_X11_LIB})
install (TARGETS ${target} DESTINATION ${subdir})
endforeach (target)
endif ()
# Copyright © 2011 Cooper Yuan
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Cooper Yuan <cooperyuan@gmail.com>
AM_CFLAGS = \
$(GLESV1_CFLAGS) \
$(EGL_CFLAGS) \
$(VG_CFLAGS) \
$(X11_CFLAGS)
AM_LDFLAGS = \
$(GLESV1_LIBS) \
$(EGL_LIBS) \
$(VG_LIBS) \
-lm
if HAVE_EGL
if HAVE_X11
if HAVE_VG
bin_PROGRAMS = \
vgimage2tex \
tex2vgimage
endif
endif
endif
vgimage2tex_LDADD = $(X11_LIBS)
tex2vgimage_LDADD = $(X11_LIBS)
/*
* KHR_gl_texture_2D_image extension test
*
* This test aims to validate KHR_gl_texture_2D_image extension which provide
* a mechanism for creating EGLImage objects from OpenGL ES API resources,
*
* such as two- and three- dimensional textures, cube maps and render buffers.
*
* Texture->EGLImage->VGImage
*
* Cooper Yuan <cooperyuan@gmail.com>
* 20 Aug 2011
*/
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <VG/openvg.h>
#include <GL/glu.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <VG/vgext.h>
#define WINDOW_WIDTH 300
#define WINDOW_HEIGHT 300
#define TEXTURE_WIDTH 128
#define TEXTURE_HEIGHT 128
static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = NULL;
static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = NULL;
static PFNVGCREATEEGLIMAGETARGETKHRPROC vgCreateEGLImageTargetKHR_func = NULL;
typedef struct _egl_manager_t
{
EGLNativeDisplayType xdpy;
EGLNativeWindowType xwin;
EGLDisplay dpy;
EGLConfig conf;
// Rendering contexts
EGLContext vg_ctx;
EGLContext es_ctx;
// Surfaces
EGLSurface win_surface;
EGLSurface pbuf_surface;
VGImage vg_image;
EGLImageKHR egl_image;
GLuint texture;
EGLint major_ver, minor_ver;
}EGLmanager;
static EGLBoolean check_ext(EGLmanager *eglman)
{
const char* egl_ext_str = NULL;
egl_ext_str = eglQueryString(eglman->dpy, EGL_EXTENSIONS);
// check extension KHR_vg_parent_image
if (eglCreateImageKHR == NULL)
{
if (!strstr(egl_ext_str, "EGL_KHR_image"))
{
return EGL_FALSE;
}
else
{
eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
if ((!eglCreateImageKHR) || (!eglDestroyImageKHR))
{
return EGL_FALSE;
}
}
}
// check extension VG_KHR_EGL_image
if (vgCreateEGLImageTargetKHR_func == NULL)
{
if (!strstr(egl_ext_str, "VG_KHR_EGL_image") )
{
return EGL_FALSE;
}
else
{
vgCreateEGLImageTargetKHR_func = (PFNVGCREATEEGLIMAGETARGETKHRPROC)eglGetProcAddress("vgCreateEGLImageTargetKHR");
if (!vgCreateEGLImageTargetKHR_func)
{
return EGL_FALSE;
}
}
}
return EGL_TRUE;
}
static EGLBoolean create_x_window(EGLmanager *eglman, const char *name)
{
EGLint scrnum, num_conf, num_visuals;
Window root;
EGLint vid;
XVisualInfo *visInfo, visTemplate;
XSetWindowAttributes attr;
unsigned long mask;
EGLint config_attrib[] =
{
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT | EGL_OPENGL_BIT,
EGL_NONE
};
scrnum = DefaultScreen(eglman->xdpy);
root = RootWindow(eglman->xdpy, scrnum);
if (!eglChooseConfig(eglman->dpy, config_attrib, &eglman->conf, 1, &num_conf) ||
num_conf == 0 ||
eglGetError() != EGL_SUCCESS)
{
printf("Error: couldn't get an EGL visual config\n");
return EGL_FALSE;
}
if (!eglGetConfigAttrib(eglman->dpy, eglman->conf, EGL_NATIVE_VISUAL_ID, &vid) ||
eglGetError() != EGL_SUCCESS)
{
printf("Error: eglGetConfigAttrib() failed\n");
return EGL_FALSE;
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(eglman->xdpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo)
{
printf("Error: couldn't get X visual\n");
return EGL_FALSE;
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(eglman->xdpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
eglman->xwin = XCreateWindow(eglman->xdpy, root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr);
if (!eglman->xwin)
{
printf("Error: couldn't create X Window\n");
return EGL_FALSE;
}
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = 0;
sizehints.y = 0;
sizehints.width = WINDOW_WIDTH;
sizehints.height = WINDOW_HEIGHT;
sizehints.flags = USSize | USPosition;
XSetNormalHints(eglman->xdpy, eglman->xwin, &sizehints);
XSetStandardProperties(eglman->xdpy, eglman->xwin, name, name,
None, (char **)NULL, 0, &sizehints);
}
XFree(visInfo);
return EGL_TRUE;
}
static EGLBoolean egl_init(EGLmanager *eglman)
{
EGLint pbuffer_attrib[] =
{
EGL_WIDTH, 128,
EGL_HEIGHT, 128,
EGL_NONE
};
// Check extension support
if (check_ext(eglman) != EGL_TRUE)
{
return EGL_FALSE;
}
// Create GL context
eglBindAPI(EGL_OPENGL_ES_API);
eglman->es_ctx = eglCreateContext(eglman->dpy, eglman->conf, NULL, NULL);
if (eglman->es_ctx == EGL_NO_CONTEXT ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
// Create VG context
eglBindAPI(EGL_OPENVG_API);
eglman->vg_ctx = eglCreateContext(eglman->dpy, eglman->conf, NULL, NULL);
if (eglman->vg_ctx == EGL_NO_CONTEXT ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
// Create window surface
eglman->win_surface = eglCreateWindowSurface(eglman->dpy, eglman->conf, eglman->xwin, NULL);
if (eglman->win_surface == EGL_NO_SURFACE ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
// Create pbuffer surface
eglman->pbuf_surface = eglCreatePbufferSurface(eglman->dpy, eglman->conf, pbuffer_attrib);
if (eglman->pbuf_surface == EGL_NO_SURFACE ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
return EGL_TRUE;
}
static void egl_deinit(EGLmanager *eglman)
{
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(eglman->dpy, eglman->win_surface);
eglDestroySurface(eglman->dpy, eglman->pbuf_surface);
eglDestroyContext(eglman->dpy, eglman->es_ctx);
eglDestroyContext(eglman->dpy, eglman->vg_ctx);
}
static EGLBoolean vg_es_init(EGLmanager *eglman)
{
unsigned char* textureData = NULL;
int tsize = 0;
// Initialize GL
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, eglman->pbuf_surface, eglman->pbuf_surface, eglman->es_ctx);
// Create Texture Target from EGLImage
glGenTextures(1, &eglman->texture);
glBindTexture(GL_TEXTURE_2D, eglman->texture);
tsize = TEXTURE_WIDTH * TEXTURE_HEIGHT * 4;
textureData = (GLubyte*) malloc (tsize);
memset(textureData, 0, tsize);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
free (textureData);
// Create EGLImage from Texture
eglman->egl_image = (EGLImageKHR)eglCreateImageKHR(eglman->dpy, eglman->es_ctx, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)eglman->texture, NULL);
// Initialize VG
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, eglman->win_surface, eglman->win_surface, eglman->vg_ctx);
// Create VGImage from EGLImage
eglman->vg_image = vgCreateEGLImageTargetKHR_func((VGeglImageKHR)eglman->egl_image);
return EGL_TRUE;
}
static void vg_es_deinit(EGLmanager *eglman)
{
// Destroy GL
eglDestroyImageKHR(eglman->dpy, eglman->egl_image);
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, eglman->pbuf_surface, eglman->pbuf_surface, eglman->es_ctx);
glDeleteTextures(1, &eglman->texture);
glBindTexture(GL_TEXTURE_2D, 0);
// Destroy VG
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, eglman->win_surface, eglman->win_surface, eglman->vg_ctx);
vgDestroyImage(eglman->vg_image);
}
static void draw(EGLmanager *eglman)
{
VGfloat black[] = {0.f, 0.f, 0.f, 1.f};
// Render 3D scene by GL
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, eglman->pbuf_surface, eglman->pbuf_surface, eglman->es_ctx);
// Modify GL texture source
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TEXTURE_WIDTH/2, TEXTURE_HEIGHT/2);
glClearColor(0.0, 1.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, TEXTURE_WIDTH/2, 0, 0, 0, TEXTURE_WIDTH/2, TEXTURE_HEIGHT/2);
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, TEXTURE_HEIGHT/2, 0, 0, TEXTURE_WIDTH/2, TEXTURE_HEIGHT/2);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, TEXTURE_WIDTH/2, TEXTURE_HEIGHT/2, 0, 0, TEXTURE_WIDTH/2, TEXTURE_HEIGHT/2);
// Make current to VG content
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, eglman->win_surface, eglman->win_surface, eglman->vg_ctx);
// Draw VGImage target
vgSetfv(VG_CLEAR_COLOR, 4, black);
vgClear(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
vgLoadIdentity();
vgTranslate(WINDOW_WIDTH/2.0f, WINDOW_HEIGHT/2.0f);
vgScale((VGfloat)WINDOW_WIDTH/(VGfloat)TEXTURE_WIDTH * 0.8f, (VGfloat)WINDOW_HEIGHT/(VGfloat)TEXTURE_HEIGHT * 0.8f);
vgTranslate(-TEXTURE_WIDTH/2.0f, -TEXTURE_HEIGHT/2.0f);
vgDrawImage(eglman->vg_image);
// Swap buffer
eglSwapBuffers(eglman->dpy, eglman->win_surface);
return;
}
int main(int argc, char **argv)
{
const char *s;
EGLmanager *eglman = calloc(1, sizeof(*eglman));
// Open X Display
Display *x_dpy = XOpenDisplay(NULL);
if (!x_dpy)
{
printf("error: can't open default display\n");
goto exit0;
}
eglman->xdpy = (EGLNativeDisplayType)x_dpy;
// Get EGL Display
eglman->dpy = eglGetDisplay(eglman->xdpy);
if (!eglman->dpy || eglGetError() != EGL_SUCCESS)
{
printf("error: can't get EGL display\n");
goto exit1;
}
// Initialize EGL
eglInitialize(eglman->dpy, &eglman->major_ver, &eglman->minor_ver);
if (eglGetError() != EGL_SUCCESS)
{
goto exit1;
}
// Query and print out information
s = eglQueryString(eglman->dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(eglman->dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(eglman->dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(eglman->dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
// Create an RGB, double-buffered X window
if (create_x_window(eglman, "vgimage to texture") != EGL_TRUE)
{
goto exit2;
}
XMapWindow(eglman->xdpy, eglman->xwin);
// Initialize EGL
if (egl_init(eglman) != EGL_TRUE)
{
goto exit3;
}
// Initialize rendering API: OpenGL ES and OpenVG
if (vg_es_init(eglman) != EGL_TRUE)
{
goto exit3;
}
// Rendering
draw(eglman);
// Deinitialize rendering API
vg_es_deinit(eglman);
// Deinitialize EGL
egl_deinit(eglman);
exit3:
XDestroyWindow(eglman->xdpy, eglman->xwin);
exit2:
eglTerminate(eglman->dpy);
exit1:
XCloseDisplay(eglman->xdpy);
exit0:
free(eglman);
return 0;
}
/*
* KHR_vg_parent_image extension test
*
* This test aims to validate KHR_vg_parent_image extension which provides
* a mechanism for creating EGLImage objects from OpenVG VGImage resources,
* and then bind EGLImage with texture which will be used by OpenGL API.
*
* VGImage->EGLImage->Texture
*
* Cooper Yuan <cooperyuan@gmail.com>
* 20 Aug 2011
*/
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <VG/openvg.h>
#include <GL/glu.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#define WINDOW_WIDTH 300
#define WINDOW_HEIGHT 300
static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = NULL;
static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = NULL;
static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = NULL;
typedef struct _egl_manager_t
{
EGLNativeDisplayType xdpy;
EGLNativeWindowType xwin;
EGLDisplay dpy;
EGLConfig conf;
// Rendering contexts
EGLContext vg_ctx;
EGLContext es_ctx;
// Surfaces
EGLSurface win_surface;
EGLSurface pbuf_surface;
VGImage vg_image;
EGLImageKHR egl_image;
GLuint texture;
EGLint major_ver, minor_ver;
}EGLmanager;
static EGLBoolean check_ext(EGLmanager *eglman)
{
const char* egl_ext_str = NULL;
egl_ext_str = eglQueryString(eglman->dpy, EGL_EXTENSIONS);
// check extension KHR_vg_parent_image
if (eglCreateImageKHR == NULL)
{
if (!strstr(egl_ext_str, "EGL_KHR_image"))
{
return EGL_FALSE;
}
else
{
eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
if ((!eglCreateImageKHR) || (!eglDestroyImageKHR))
{
return EGL_FALSE;
}
}
}
// check extension GL_OES_EGL_image
if (glEGLImageTargetTexture2DOES == NULL)
{
glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
if (!glEGLImageTargetTexture2DOES)
{
return EGL_FALSE;
}
}
return EGL_TRUE;
}
static EGLBoolean create_x_window(EGLmanager *eglman, const char *name)
{
EGLint scrnum, num_conf, num_visuals;
Window root;
EGLint vid;
XVisualInfo *visInfo, visTemplate;
XSetWindowAttributes attr;
unsigned long mask;
EGLint config_attrib[] =
{
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT | EGL_OPENGL_BIT,
EGL_NONE
};
scrnum = DefaultScreen(eglman->xdpy);
root = RootWindow(eglman->xdpy, scrnum);
if (!eglChooseConfig(eglman->dpy, config_attrib, &eglman->conf, 1, &num_conf) ||
num_conf == 0 ||
eglGetError() != EGL_SUCCESS)
{
printf("Error: couldn't get an EGL visual config\n");
return EGL_FALSE;
}
if (!eglGetConfigAttrib(eglman->dpy, eglman->conf, EGL_NATIVE_VISUAL_ID, &vid) ||
eglGetError() != EGL_SUCCESS)
{
printf("Error: eglGetConfigAttrib() failed\n");
return EGL_FALSE;
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(eglman->xdpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo)
{
printf("Error: couldn't get X visual\n");
return EGL_FALSE;
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(eglman->xdpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
eglman->xwin = XCreateWindow(eglman->xdpy, root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr);
if (!eglman->xwin)
{
printf("Error: couldn't create X Window\n");
return EGL_FALSE;
}
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = 0;
sizehints.y = 0;
sizehints.width = WINDOW_WIDTH;
sizehints.height = WINDOW_HEIGHT;
sizehints.flags = USSize | USPosition;
XSetNormalHints(eglman->xdpy, eglman->xwin, &sizehints);
XSetStandardProperties(eglman->xdpy, eglman->xwin, name, name,
None, (char **)NULL, 0, &sizehints);
}
XFree(visInfo);
return EGL_TRUE;
}
static EGLBoolean egl_init(EGLmanager *eglman)
{
EGLint pbuffer_attrib[] =
{
EGL_WIDTH, 128,
EGL_HEIGHT, 128,
EGL_NONE
};
// Check extension support
if (check_ext(eglman) != EGL_TRUE)
{
return EGL_FALSE;
}
// Create GL context
eglBindAPI(EGL_OPENGL_ES_API);
eglman->es_ctx = eglCreateContext(eglman->dpy, eglman->conf, NULL, NULL);
if (eglman->es_ctx == EGL_NO_CONTEXT ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
// Create VG context
eglBindAPI(EGL_OPENVG_API);
eglman->vg_ctx = eglCreateContext(eglman->dpy, eglman->conf, NULL, NULL);
if (eglman->vg_ctx == EGL_NO_CONTEXT ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
// Create window surface
eglman->win_surface = eglCreateWindowSurface(eglman->dpy, eglman->conf, eglman->xwin, NULL);
if (eglman->win_surface == EGL_NO_SURFACE ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
// Create pbuffer surface
eglman->pbuf_surface = eglCreatePbufferSurface(eglman->dpy, eglman->conf, pbuffer_attrib);
if (eglman->pbuf_surface == EGL_NO_SURFACE ||
eglGetError() != EGL_SUCCESS)
{
return EGL_FALSE;
}
return EGL_TRUE;
}
static void egl_deinit(EGLmanager *eglman)
{
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(eglman->dpy, eglman->win_surface);
eglDestroySurface(eglman->dpy, eglman->pbuf_surface);
eglDestroyContext(eglman->dpy, eglman->es_ctx);
eglDestroyContext(eglman->dpy, eglman->vg_ctx);
}
static EGLBoolean vg_es_init(EGLmanager *eglman)
{
// Initialize OpenVG
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, eglman->pbuf_surface, eglman->pbuf_surface, eglman->vg_ctx);
// Create VGImage
eglman->vg_image = vgCreateImage(VG_sRGBA_8888, WINDOW_WIDTH, WINDOW_HEIGHT, VG_IMAGE_QUALITY_BETTER);
// Create EGLImage from VGImage
eglman->egl_image = (EGLImageKHR)eglCreateImageKHR(eglman->dpy, eglman->vg_ctx, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)eglman->vg_image, NULL);
// Initialize OpenGL ES
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, eglman->win_surface, eglman->win_surface, eglman->es_ctx);
// Create Texture Target from EGLImage
glGenTextures(1, &eglman->texture);
glBindTexture(GL_TEXTURE_2D, eglman->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)eglman->egl_image);
return EGL_TRUE;
}
static void vg_es_deinit(EGLmanager *eglman)
{
// Destroy VG
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, eglman->pbuf_surface, eglman->pbuf_surface, eglman->vg_ctx);
eglDestroyImageKHR(eglman->dpy, eglman->egl_image);
vgDestroyImage(eglman->vg_image);
// Destroy GL
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, eglman->win_surface, eglman->win_surface, eglman->es_ctx);
glDeleteTextures(1, &eglman->texture);
glBindTexture(GL_TEXTURE_2D, 0);
}
static void draw(EGLmanager *eglman)
{
static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0};
static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
GLfloat pVertex[12] =
{
-1.f, -1.f, 0.f,
1.f, -1.f, 0.f,
-1.f, 1.f, 0.f,
1.f, 1.f, 0.f
};
GLshort pTexCoord[8] =
{
0, 0,
1, 0,
0, 1,
1, 1,
};
// Make current to VG content
eglBindAPI(EGL_OPENVG_API);
eglMakeCurrent(eglman->dpy, eglman->pbuf_surface, eglman->pbuf_surface, eglman->vg_ctx);
vgSetfv(VG_CLEAR_COLOR, 4, red);
vgClearImage(eglman->vg_image, 0, 0, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
vgSetfv(VG_CLEAR_COLOR, 4, blue);
vgClearImage(eglman->vg_image, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
// Make current to GL content
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglman->dpy, eglman->win_surface, eglman->win_surface, eglman->es_ctx);
glViewport(WINDOW_WIDTH / 8, WINDOW_HEIGHT / 8, WINDOW_WIDTH * 3 / 4, WINDOW_HEIGHT * 3 / 4);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, eglman->texture);
glEnable(GL_TEXTURE_2D);
glEnableClientState( GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, pVertex);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_SHORT, 0, pTexCoord);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Swap buffer
eglSwapBuffers(eglman->dpy, eglman->win_surface);
return;
}
int main(int argc, char **argv)
{
const char *s;
EGLmanager *eglman = calloc(1, sizeof(*eglman));
// Open X Display
Display *x_dpy = XOpenDisplay(NULL);
if (!x_dpy)
{
printf("error: can't open default display\n");
goto exit0;
}
eglman->xdpy = (EGLNativeDisplayType)x_dpy;
// Get EGL Display
eglman->dpy = eglGetDisplay(eglman->xdpy);
if (!eglman->dpy || eglGetError() != EGL_SUCCESS)
{
printf("error: can't get EGL display\n");
goto exit1;
}
// Initialize EGL
eglInitialize(eglman->dpy, &eglman->major_ver, &eglman->minor_ver);
if (eglGetError() != EGL_SUCCESS)
{
goto exit1;
}
// Query and print out information
s = eglQueryString(eglman->dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(eglman->dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(eglman->dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(eglman->dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
// Create an RGB, double-buffered X window
if (create_x_window(eglman, "vgimage to texture") != EGL_TRUE)
{
goto exit2;
}
XMapWindow(eglman->xdpy, eglman->xwin);
// Initialize EGL
if (egl_init(eglman) != EGL_TRUE)
{
goto exit3;
}
// Initialize rendering API: OpenGL ES and OpenVG
if (vg_es_init(eglman) != EGL_TRUE)
{
goto exit3;
}
// Rendering
draw(eglman);
// Deinitialize rendering API
vg_es_deinit(eglman);
// Deinitialize EGL
egl_deinit(eglman);
exit3:
XDestroyWindow(eglman->xdpy, eglman->xwin);
exit2:
eglTerminate(eglman->dpy);
exit1:
XCloseDisplay(eglman->xdpy);
exit0:
free(eglman);
return 0;
}
...@@ -12,6 +12,9 @@ link_libraries ( ...@@ -12,6 +12,9 @@ link_libraries (
set (subdir egl) set (subdir egl)
add_executable (eglinfo eglinfo.c)
add_executable (peglgears peglgears.c)
# Targets that can be built both for fullscreen EGL and X11 # Targets that can be built both for fullscreen EGL and X11
set (targets set (targets
...@@ -25,6 +28,12 @@ foreach (target ${targets}) ...@@ -25,6 +28,12 @@ foreach (target ${targets})
target_link_libraries (${target}_x11 eglut_x11) target_link_libraries (${target}_x11 eglut_x11)
install (TARGETS ${target}_x11 DESTINATION ${subdir}) install (TARGETS ${target}_x11 DESTINATION ${subdir})
endif () endif ()
if (BUILD_WAYLAND)
add_executable (${target}_wayland ${target}.c)
target_link_libraries (${target}_wayland eglut_wayland)
install (TARGETS ${target}_wayland DESTINATION ${subdir})
endif (BUILD_WAYLAND)
endforeach (target) endforeach (target)
......
...@@ -68,8 +68,6 @@ endif ...@@ -68,8 +68,6 @@ endif
egltri_x11_SOURCES = egltri.c egltri_x11_SOURCES = egltri.c
eglgears_x11_SOURCES = eglgears.c eglgears_x11_SOURCES = eglgears.c
eglgears_x11_LDFLAGS = $(AM_LDFLAGS) $(X11_LIBS)
egltri_x11_LDFLAGS = $(AM_LDFLAGS) $(X11_LIBS)
xeglgears_LDFLAGS = $(AM_LDFLAGS) $(X11_LIBS) xeglgears_LDFLAGS = $(AM_LDFLAGS) $(X11_LIBS)
xeglthreads_LDFLAGS = $(AM_LDFLAGS) $(X11_LIBS) -pthread xeglthreads_LDFLAGS = $(AM_LDFLAGS) $(X11_LIBS) -pthread
......
...@@ -33,4 +33,10 @@ foreach (target ${targets}) ...@@ -33,4 +33,10 @@ foreach (target ${targets})
target_link_libraries (${target}_x11 eglut_x11 ${GLESV2_LIBRARIES}) target_link_libraries (${target}_x11 eglut_x11 ${GLESV2_LIBRARIES})
install (TARGETS ${target}_x11 DESTINATION ${subdir}) install (TARGETS ${target}_x11 DESTINATION ${subdir})
endif () endif ()
if (BUILD_WAYLAND)
add_executable (${target}_wayland ${target}.c)
target_link_libraries (${target}_wayland eglut_wayland ${GLESV2_LIBRARIES})
install (TARGETS ${target}_wayland DESTINATION ${subdir})
endif (BUILD_WAYLAND)
endforeach (target) endforeach (target)
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <assert.h>
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
...@@ -52,19 +53,9 @@ ...@@ -52,19 +53,9 @@
#include "eglut.h" #include "eglut.h"
#define STRIPS_PER_TOOTH 7 #define STRIPS_PER_TOOTH 7
#define VERTICES_PER_TOOTH 34 #define VERTICES_PER_TOOTH 46
#define GEAR_VERTEX_STRIDE 6 #define GEAR_VERTEX_STRIDE 6
/**
* Struct describing the vertices in triangle strip
*/
struct vertex_strip {
/** The first vertex in the strip */
GLint first;
/** The number of consecutive vertices in the strip after the first */
GLint count;
};
/* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */ /* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */
typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE]; typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE];
...@@ -76,10 +67,6 @@ struct gear { ...@@ -76,10 +67,6 @@ struct gear {
GearVertex *vertices; GearVertex *vertices;
/** The number of vertices comprising the gear */ /** The number of vertices comprising the gear */
int nvertices; int nvertices;
/** The array of triangle strips comprising the gear */
struct vertex_strip *strips;
/** The number of triangle strips comprising the gear */
int nstrips;
/** The Vertex Buffer Object holding the vertices in the graphics card */ /** The Vertex Buffer Object holding the vertices in the graphics card */
GLuint vbo; GLuint vbo;
}; };
...@@ -145,7 +132,7 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, ...@@ -145,7 +132,7 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
struct gear *gear; struct gear *gear;
double s[5], c[5]; double s[5], c[5];
GLfloat normal[3]; GLfloat normal[3];
int cur_strip = 0; int cur_strip_start = 0;
int i; int i;
/* Allocate memory for the gear */ /* Allocate memory for the gear */
...@@ -160,12 +147,13 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, ...@@ -160,12 +147,13 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
da = 2.0 * M_PI / teeth / 4.0; da = 2.0 * M_PI / teeth / 4.0;
/* Allocate memory for the triangle strip information */ /* the first tooth doesn't need the first strip-restart sequence */
gear->nstrips = STRIPS_PER_TOOTH * teeth; assert(teeth > 0);
gear->strips = calloc(gear->nstrips, sizeof (*gear->strips)); gear->nvertices = VERTICES_PER_TOOTH +
(VERTICES_PER_TOOTH + 2) * (teeth - 1);
/* Allocate memory for the vertices */ /* Allocate memory for the vertices */
gear->vertices = calloc(VERTICES_PER_TOOTH * teeth, sizeof(*gear->vertices)); gear->vertices = calloc(gear->nvertices, sizeof(*gear->vertices));
v = gear->vertices; v = gear->vertices;
for (i = 0; i < teeth; i++) { for (i = 0; i < teeth; i++) {
...@@ -185,13 +173,20 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, ...@@ -185,13 +173,20 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
#define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal) #define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal)
#define START_STRIP do { \ #define START_STRIP do { \
gear->strips[cur_strip].first = v - gear->vertices; \ cur_strip_start = (v - gear->vertices); \
if (cur_strip_start) \
v += 2; \
} while(0); } while(0);
/* emit prev last vertex
emit first vertex */
#define END_STRIP do { \ #define END_STRIP do { \
int _tmp = (v - gear->vertices); \ if (cur_strip_start) { \
gear->strips[cur_strip].count = _tmp - gear->strips[cur_strip].first; \ memcpy(gear->vertices + cur_strip_start, \
cur_strip++; \ gear->vertices + (cur_strip_start - 1), sizeof(GearVertex)); \
memcpy(gear->vertices + cur_strip_start + 1, \
gear->vertices + (cur_strip_start + 2), sizeof(GearVertex)); \
} \
} while (0) } while (0)
#define QUAD_WITH_NORMAL(p1, p2) do { \ #define QUAD_WITH_NORMAL(p1, p2) do { \
...@@ -230,26 +225,16 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, ...@@ -230,26 +225,16 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
v = GEAR_VERT(v, 6, +1); v = GEAR_VERT(v, 6, +1);
END_STRIP; END_STRIP;
/* Inner face */
START_STRIP;
SET_NORMAL(-c[0], -s[0], 0);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 4, 1);
SET_NORMAL(-c[4], -s[4], 0);
v = GEAR_VERT(v, 6, -1);
v = GEAR_VERT(v, 6, 1);
END_STRIP;
/* Back face */ /* Back face */
START_STRIP; START_STRIP;
SET_NORMAL(0, 0, -1.0); SET_NORMAL(0, 0, -1.0);
v = GEAR_VERT(v, 6, -1);
v = GEAR_VERT(v, 5, -1);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 3, -1);
v = GEAR_VERT(v, 2, -1);
v = GEAR_VERT(v, 1, -1);
v = GEAR_VERT(v, 0, -1); v = GEAR_VERT(v, 0, -1);
v = GEAR_VERT(v, 1, -1);
v = GEAR_VERT(v, 2, -1);
v = GEAR_VERT(v, 3, -1);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 5, -1);
v = GEAR_VERT(v, 6, -1);
END_STRIP; END_STRIP;
/* Outer face */ /* Outer face */
...@@ -268,9 +253,19 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, ...@@ -268,9 +253,19 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
START_STRIP; START_STRIP;
QUAD_WITH_NORMAL(5, 3); QUAD_WITH_NORMAL(5, 3);
END_STRIP; END_STRIP;
/* Inner face */
START_STRIP;
SET_NORMAL(-c[0], -s[0], 0);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 4, 1);
SET_NORMAL(-c[4], -s[4], 0);
v = GEAR_VERT(v, 6, -1);
v = GEAR_VERT(v, 6, 1);
END_STRIP;
} }
gear->nvertices = (v - gear->vertices); assert(gear->nvertices == (v - gear->vertices));
/* Store the vertices in a vertex buffer object (VBO) */ /* Store the vertices in a vertex buffer object (VBO) */
glGenBuffers(1, &gear->vbo); glGenBuffers(1, &gear->vbo);
...@@ -501,9 +496,7 @@ draw_gear(struct gear *gear, GLfloat *transform, ...@@ -501,9 +496,7 @@ draw_gear(struct gear *gear, GLfloat *transform,
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
/* Draw the triangle strips that comprise the gear */ /* Draw the triangle strips that comprise the gear */
int n; glDrawArrays(GL_TRIANGLE_STRIP, 0, gear->nvertices);
for (n = 0; n < gear->nstrips; n++)
glDrawArrays(GL_TRIANGLE_STRIP, gear->strips[n].first, gear->strips[n].count);
/* Disable the attributes */ /* Disable the attributes */
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
...@@ -634,7 +627,7 @@ static const char vertex_shader[] = ...@@ -634,7 +627,7 @@ static const char vertex_shader[] =
"\n" "\n"
" // Multiply the diffuse value by the vertex color (which is fixed in this case)\n" " // Multiply the diffuse value by the vertex color (which is fixed in this case)\n"
" // to get the actual color that we will use to draw this vertex with\n" " // to get the actual color that we will use to draw this vertex with\n"
" Color = (ambient + diffuse) * MaterialColor;\n" " Color = vec4((ambient + diffuse) * MaterialColor.xyz, MaterialColor.a);\n"
"\n" "\n"
" // Transform the position to clip coordinates\n" " // Transform the position to clip coordinates\n"
" gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);\n" " gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);\n"
......
...@@ -215,11 +215,6 @@ init(void) ...@@ -215,11 +215,6 @@ init(void)
{ {
typedef void (*proc)(); typedef void (*proc)();
#if 1 /* test code */
proc p = eglGetProcAddress("glMapBufferOES");
assert(p);
#endif
glClearColor(0.4, 0.4, 0.4, 0.0); glClearColor(0.4, 0.4, 0.4, 0.0);
create_shaders(); create_shaders();
......
lion_x11
sp_x11
text
trivial/arc
trivial/blend
trivial/cap
trivial/clear
trivial/color_transform
trivial/coord
trivial/dash
trivial/ellipse
trivial/filter
trivial/gradorigin
trivial/image
trivial/layer
trivial/lineto
trivial/lingrad
trivial/lookup
trivial/mask4
trivial/mask
trivial/mask_render
trivial/paint
trivial/path3
trivial/radialgrad
trivial/readpixels
trivial/roundedrect
trivial/star-nonzero
trivial/star-oddeven
trivial/stroke2
trivial/stroke
trivial/vguarc
include_directories(
${CMAKE_SOURCE_DIR}/src/egl/eglut
${CMAKE_SOURCE_DIR}/src/util
${EGL_INCLUDE_DIRS}
${VG_INCLUDE_DIRS}
)
set (subdir egl/openvg)
if (X11_FOUND)
foreach (target ${targets})
add_executable (text text.c)
target_link_libraries (text ${EGL_LIBRARIES} ${VG_LIBRARIES} ${X11_X11_LIB})
install (TARGETS text DESTINATION ${subdir})
endforeach (target)
endif ()
# Targets that can be built both for fullscreen EGL and X11
set (targets
lion
sp
)
foreach (target ${targets})
set (sources ${target}.c)
if (${target} STREQUAL lion)
set (sources ${sources} lion-render.c)
endif ()
if (X11_FOUND)
add_executable (${target}_x11 ${sources})
target_link_libraries (${target}_x11 eglut_x11 ${VG_LIBRARIES})
install (TARGETS ${target}_x11 DESTINATION ${subdir})
endif ()
endforeach (target)
add_subdirectory (trivial)
# Copyright © 2010 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Eric Anholt <eric@anholt.net>
# These programs aren't intended to be included with the normal distro.
# They're not too interesting but they're good for testing.
AM_CFLAGS = \
$(VG_CFLAGS) \
$(EGL_CFLAGS) \
$(X11_CFLAGS) \
-I$(top_srcdir)/src/egl/eglut
AM_LDFLAGS = \
$(VG_LIBS) \
$(EGL_LIBS) \
-lm
if HAVE_X11
EGL_X11_DEMOS = \
lion_x11 \
sp_x11
if HAVE_FREETYPE2
EGL_X11_DEMOS += \
text
endif
endif
if HAVE_EGL
if HAVE_VG
noinst_PROGRAMS = \
$(EGL_X11_DEMOS)
endif
endif
lion_x11_SOURCES = lion.c lion-render.c lion-render.h
sp_x11_SOURCES = sp.c
lion_x11_LDADD = ../eglut/libeglut_x11.la
sp_x11_LDADD = ../eglut/libeglut_x11.la
text_SOURCES = text.c
text_CFLAGS = $(AM_CFLAGS) @FREETYPE2_CFLAGS@
text_LDADD = @FREETYPE2_LIBS@ ../eglut/libeglut_x11.la
SUBDIRS = \
trivial
This diff is collapsed.
#ifndef LION_RENDER_H
#define LION_RENDER_H
#include <VG/openvg.h>
#define LION_SIZE 132
struct lion {
VGPath paths[LION_SIZE];
VGPaint fills[LION_SIZE];
};
struct lion *lion_create(void);
void lion_render(struct lion *l);
void lion_destroy(struct lion *l);
#endif
#include <stdio.h>
#include <VG/openvg.h>
#include <EGL/egl.h>
#include "lion-render.h"
#include "eglut.h"
static VGint width, height;
struct lion *lion = 0;
VGfloat angle = 0;
static void
draw(void)
{
static double t0 = -1.0;
static int num_frames;
double now;
vgClear(0, 0, width, height);
vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
vgLoadIdentity();
vgTranslate(width/2, height/2);
vgRotate(angle);
vgTranslate(-width/2, -height/2);
lion_render(lion);
vgFlush();
num_frames++;
if (t0 < 0.0) {
t0 = eglutGet(EGLUT_ELAPSED_TIME) / 1000.0;
num_frames = 0;
}
now = eglutGet(EGLUT_ELAPSED_TIME) / 1000.0;
if (now - t0 > 5.0) {
/* just a rough estimate */
printf("%d frames in %3.1f seconds = %6.3f FPS\n",
num_frames, now - t0, num_frames / (now - t0));
t0 = now;
num_frames = 0;
}
++angle;
eglutPostRedisplay();
}
/* new window size or exposure */
static void
reshape(int w, int h)
{
width = w;
height = h;
}
static void
init(void)
{
float clear_color[4] = {1.0, 1.0, 1.0, 1.0};
vgSetfv(VG_CLEAR_COLOR, 4, clear_color);
lion = lion_create();
}
int
main(int argc, char *argv[])
{
eglutInitWindowSize(350, 450);
eglutInitAPIMask(EGLUT_OPENVG_BIT);
eglutInit(argc, argv);
eglutCreateWindow("Lion Example");
eglutReshapeFunc(reshape);
eglutDisplayFunc(draw);
init();
eglutMainLoop();
return 0;
}
#include <VG/openvg.h>
#include <VG/vgu.h>
#include <math.h>
#include <string.h>
#include "eglut.h"
#define ELEMENTS(x) (sizeof(x)/sizeof((x)[0]))
struct object {
VGPath path;
VGPaint fill;
VGPaint stroke;
VGint draw_mode;
VGfloat matrix[9];
VGfloat stroke_width;
};
struct character {
struct object objects[32];
VGint num_objects;
};
VGfloat identity_matrix[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
struct character cartman;
static void add_object_fill(const VGubyte *segments, VGint num_segments,
const VGfloat *coords,
VGuint color)
{
struct object object;
object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
vgAppendPathData(object.path, num_segments, segments, coords);
object.fill = vgCreatePaint();
vgSetColor(object.fill, color);
memcpy(object.matrix, identity_matrix, 9 * sizeof(VGfloat));
object.draw_mode = VG_FILL_PATH;
cartman.objects[cartman.num_objects] = object;
++cartman.num_objects;
}
static void add_object_stroke(const VGubyte *segments, VGint num_segments,
const VGfloat *coords,
VGuint color, VGfloat width)
{
struct object object;
object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
vgAppendPathData(object.path, num_segments, segments, coords);
object.stroke = vgCreatePaint();
vgSetColor(object.stroke, color);
memcpy(object.matrix, identity_matrix, 9 * sizeof(VGfloat));
object.draw_mode = VG_STROKE_PATH;
object.stroke_width = width;
cartman.objects[cartman.num_objects] = object;
++cartman.num_objects;
}
static void add_object_fillm(const VGubyte *segments, VGint num_segments,
const VGfloat *coords,
VGuint color,
VGfloat *matrix)
{
struct object object;
object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
vgAppendPathData(object.path, num_segments, segments, coords);
object.fill = vgCreatePaint();
vgSetColor(object.fill, color);
memcpy(object.matrix, matrix, 9 * sizeof(VGfloat));
object.draw_mode = VG_FILL_PATH;
cartman.objects[cartman.num_objects] = object;
++cartman.num_objects;
}
static void add_object_m(const VGubyte *segments, VGint num_segments,
const VGfloat *coords,
VGuint fill_color,
VGuint stroke_color, VGfloat stroke_width,
VGfloat *matrix)
{
struct object object;
object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
vgAppendPathData(object.path, num_segments, segments, coords);
memcpy(object.matrix, matrix, 9 * sizeof(VGfloat));
object.fill = vgCreatePaint();
vgSetColor(object.fill, fill_color);
object.draw_mode = VG_FILL_PATH | VG_STROKE_PATH;
object.stroke = vgCreatePaint();
vgSetColor(object.stroke, stroke_color);
object.stroke_width = stroke_width;
cartman.objects[cartman.num_objects] = object;
++cartman.num_objects;
}
static void init_character()
{
{
const VGubyte segments[] = {VG_MOVE_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CLOSE_PATH};
const VGfloat coords[] = {181.83267, 102.60408,
181.83267,102.60408, 185.53793,114.5749, 186.5355,115.00243,
187.53306,115.42996, 286.0073,115.00243, 286.0073,115.00243,
286.0073,115.00243, 292.70526,103.45914, 290.85263,101.03648,
289.00001,98.61381, 181.54765,102.31906, 181.83267,102.60408
};
VGuint color = 0x7c4e32ff;
add_object_fill(segments, ELEMENTS(segments),
coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_LINE_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CLOSE_PATH
};
const VGfloat coords[] = {188.62208,50.604156,
188.62208,50.604156, 176.73127,60.479579, 170.68509,69.548844,
164.63892,78.618109, 175.11895,79.827344, 175.11895,79.827344,
176.52973,98.368952,
176.52973,98.368952, 189.83131,110.05823, 208.97754,110.25976,
228.12377,110.46131, 244.24691,111.67054, 247.06846,110.25976,
249.89,108.849, 258.95927,106.8336, 260.16851,105.01975,
261.37774,103.2059, 296.84865,106.43053, 297.05019,91.919698,
297.25172,77.408874, 306.11945,64.308824, 282.13628,51.611853,
258.15311,38.914882, 189.2267,49.999539, 188.62208,50.604156
};
VGuint color = 0xe30000ff;
add_object_fill(segments, ELEMENTS(segments),
coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS,
VG_CLOSE_PATH
};
const VGfloat coords[] = {
68.25, 78.875,
68.25,93.296, 54.642,105, 37.875,105,
21.108,105, 7.5,93.296, 7.5,78.875,
7.5,64.454, 21.108,52.75, 37.875,52.75,
54.642,52.75, 68.25,64.454, 68.25,78.875
};
VGuint color = 0xffe1c4ff;
VGfloat matrix[] = {
1.6529, 0, 0,
0, 1.582037, 0,
172.9649,-90.0116, 1
};
add_object_fillm(segments, ELEMENTS(segments),
coords, color, matrix);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
170.14687,71.536958,
173.53626,68.814326, 176.70232,68.971782, 180.55009,71.679467,
184.39785,74.387153, 199.19294,80.036105, 191.52334,86.500482,
189.02942,88.6025, 183.97032,85.787933, 180.26507,86.928011,
178.8737,87.356121, 174.71827,89.783259, 171.8028,87.494856,
166.95426,83.689139, 163.51779,76.861986, 170.14687,71.536958
};
VGuint color = 0xfff200ff;
add_object_fill(segments, ELEMENTS(segments),
coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
299.83075,66.834136,
299.83075,66.834136, 287.85993,64.69649, 284.15467,72.962055,
280.44942,81.227621, 280.1644,78.234916, 280.1644,79.374994,
280.1644,80.515072, 278.16927,84.077816, 284.86722,83.792796,
291.56518,83.507777, 291.99271,86.785501, 294.84291,86.642991,
297.6931,86.500482, 303.536,85.645423, 303.67851,80.657582,
303.82102,75.66974, 302.68094,65.551548, 299.83075,66.834136
};
VGuint color = 0xfff200ff;
add_object_fill(segments, ELEMENTS(segments),
coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS
};
const VGfloat coords[] = {
240.83171,75.81225,
240.83171,75.81225, 241.54426,88.495618, 242.25681,91.488323,
242.96936,94.481028, 240.6892,108.01945, 240.83171,110.01459,
240.97422,112.00973, 240.97422,111.01216, 240.97422,111.01216
};
VGuint color = 0x000000ff;
VGfloat swidth = 1.14007807;
add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
83.375, 95.5,
83.375,96.121, 83.067,96.625, 82.6875,96.625,
82.308,96.625, 82,96.121, 82,95.5,
82,94.879, 82.308,94.375, 82.6875,94.375,
83.066677,94.375, 83.374492,94.878024, 83.374999,95.498494,
82.6875,95.5,
83.375,95.5
};
VGuint fill_color = 0x000000ff;
VGuint stroke_color = 0x000000ff;
VGfloat swidth = 0.60000002;
VGfloat matrix1[] = {
1.140078, 0, 0,
0, 1.140078, 0,
145.4927, -15.10897, 1
};
VGfloat matrix2[] = {
1.140078,0, 0,
0,1.140078, 0,
144.2814,-27.93485, 1
};
VGfloat matrix3[] = {
1.140078,0, 0,
0,1.140078, 0,
144.1388,-3.70819, 1
};
add_object_m(segments, ELEMENTS(segments), coords,
fill_color, stroke_color, swidth, matrix1);
add_object_m(segments, ELEMENTS(segments), coords,
fill_color, stroke_color, swidth, matrix2);
add_object_m(segments, ELEMENTS(segments), coords,
fill_color, stroke_color, swidth, matrix3);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_LINE_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
179.41001,115.28745,
179.41001,115.28745, 207.48443,109.30204, 236.84144,115.14494,
236.84144,115.14494, 274.74903,109.87208, 291.8502,115.42996,
179.41001,115.28745
};
VGuint color = 0x000000ff;
add_object_fill(segments, ELEMENTS(segments),
coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
83.792156,68.157364,
83.792156,69.669865, 82.72301,70.897403, 81.40567,70.897403,
80.08833,70.897403, 79.019185,69.669865, 79.019185,68.157364,
79.019185,66.644862, 80.08833,65.417325, 81.40567,65.417325,
82.721887,65.417325, 83.790391,66.642485, 83.792153,68.153696,
81.40567,68.157364,
83.792156,68.157364
};
VGuint fill_color = 0x000000ff;
VGuint stroke_color = 0x000000ff;
VGfloat swidth = 0.52891117;
VGfloat matrix1[] = {
1.140078,0, 0,
0,1.140078, 0,
145.2489,-15.58714, 1
};
add_object_m(segments, ELEMENTS(segments), coords,
fill_color, stroke_color, swidth, matrix1);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS
};
const VGfloat coords[] = {
232.28113,66.976646,
232.28113,66.976646, 237.98152,70.539389, 245.39202,66.549116
};
VGuint color = 0x000000ff;
VGfloat swidth = 0.60299999;
add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
185.96908,30.061986,
185.96908,30.061986, 187.76995,14.508377, 203.23909,3.7427917,
209.95028,-0.92779696, 219.37764,-4.9841866, 232.1078,-6.00046,
246.13578,-7.1203411, 256.92106,-2.8560739, 264.81774,1.9451947,
280.60485,11.543934, 284.31582,25.937274, 284.08015,26.526452,
283.7266,27.410336, 240.83461,1.9346323, 185.96908,30.061986
};
VGuint color = 0x8ed8f8ff;
add_object_fill(segments, ELEMENTS(segments), coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_CUBIC_TO_ABS,
VG_LINE_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
185.39542,32.061757,
185.82295,29.211562,
185.82295,29.211562, 234.70379,2.277219, 284.01217,25.078779,
284.86722,27.643954,
284.86722,27.643954, 236.69893,4.5573746, 185.39542,32.061757
};
VGuint color = 0xfff200ff;
add_object_fill(segments, ELEMENTS(segments), coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
219.74027,-5.917093,
220.49206,-8.44929, 225.15564,-10.904934, 230.21473,-11.189954,
235.27383,-11.474973, 243.27521,-13.287236, 249.21385,-5.724198,
249.89961,-4.850868, 249.28247,-4.332166, 248.62298,-3.971398,
247.79117,-3.516361, 247.13703,-3.392737, 246.16222,-3.408047,
243.63973,-3.447664, 242.54183,-3.850701, 242.54183,-3.850701,
242.54183,-3.850701, 238.78367,-1.737343, 236.20014,-3.565682,
233.88436,-5.204544, 234.27626,-4.56325, 234.27626,-4.56325,
234.27626,-4.56325, 232.33303,-2.975658, 230.85603,-2.995643,
228.59433,-3.025282, 227.73672,-4.501857, 227.21966,-4.93027,
226.76318,-4.932008, 226.50948,-4.491995, 226.50948,-4.491995,
226.50948,-4.491995, 224.53199,-2.085883, 222.51431,-2.467064,
221.48814,-2.66093, 218.91968,-3.15318, 219.74027,-5.917093
};
VGuint color = 0xfff200ff;
add_object_fill(segments, ELEMENTS(segments), coords, color);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
178.97347,166.06432,
178.97347,181.2154, 168.0245,193.51193, 154.53381,193.51193,
141.04312,193.51193, 130.09416,181.2154, 130.09416,166.06432,
130.09416,150.91323, 141.04312,138.6167, 154.53381,138.6167,
168.0245,138.6167, 178.97347,150.91323, 178.97347,166.06432
};
VGuint color = 0xffffffff;
VGfloat matrix1[] = {
0.466614,-0.23492, 0,
0.108683,0.436638, 0,
134.5504,-0.901632, 1
};
VGfloat matrix2[] = {
-0.466614,-0.23492, 0,
-0.108683,0.436638, 0,
338.4496,-0.512182, 1
};
add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix1);
add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix2);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS,
VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH
};
const VGfloat coords[] = {
123.82758,165.06168,
123.82758,166.79125, 122.59232,168.19497, 121.07029,168.19497,
119.54826,168.19497, 118.313,166.79125, 118.313,165.06168,
118.313,163.3321, 119.54826,161.92839, 121.07029,161.92839,
122.59232,161.92839, 123.82758,163.3321, 123.82758,165.06168
};
VGuint color = 0x000000ff;
VGfloat matrix1[] = {
0.525719,0, 0,
0,0.479931, 0,
178.9702,-43.3532, 1
};
VGfloat matrix2[] = {
0.525719,0, 0,
0,0.479931, 0,
165.258,-43.46162, 1
};
add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix1);
add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix2);
}
{
const VGubyte segments[] = {
VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS
};
const VGfloat coords[] = {
197.25,54.5,
197.25,54.5, 211.75,71.5, 229.25,71.5,
246.75,71.5, 261.74147,71.132714, 277.75,50.75
};
VGuint color = 0x000000ff;
VGfloat swidth = 0.60299999;
add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth);
}
}
static void
init(void)
{
float clear_color[4] = {1.0, 1.0, 1.0, 1.0};
vgSetfv(VG_CLEAR_COLOR, 4, clear_color);
init_character();
}
/* new window size or exposure */
static void
reshape(int w, int h)
{
}
static void
draw(void)
{
VGint i;
VGfloat save_matrix[9];
vgClear(0, 0, eglutGetWindowWidth(), eglutGetWindowHeight());
vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
vgLoadIdentity();
vgScale(2, 2);
vgTranslate(160, 60);
vgRotate(180);
vgTranslate(-160, -100);
vgGetMatrix(save_matrix);
for (i = 0; i < cartman.num_objects; ++i) {
struct object object = cartman.objects[i];
if ((object.draw_mode & VG_STROKE_PATH)) {
vgSetf(VG_STROKE_LINE_WIDTH, object.stroke_width);
vgSetPaint(object.stroke, VG_STROKE_PATH);
}
if ((object.draw_mode & VG_FILL_PATH))
vgSetPaint(object.fill, VG_FILL_PATH);
vgMultMatrix(object.matrix);
vgDrawPath(object.path, object.draw_mode);
vgLoadMatrix(save_matrix);
}
vgFlush();
}
int main(int argc, char **argv)
{
eglutInitWindowSize(400, 400);
eglutInitAPIMask(EGLUT_OPENVG_BIT);
eglutInit(argc, argv);
eglutCreateWindow("sp");
eglutReshapeFunc(reshape);
eglutDisplayFunc(draw);
init();
eglutMainLoop();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <VG/openvg.h>
#include "eglut.h"
#define MAX_GLYPHS 256
static struct glyph {
VGboolean is_path;
VGHandle handle;
VGfloat origin[2];
VGfloat escapement[2];
} glyph_string[MAX_GLYPHS];
static int glyph_string_len;
static VGHandle glyph_string_font = VG_INVALID_HANDLE;
static VGint width, height;
static VGint
glyph_string_add_path(VGPath path, const VGfloat origin[2], VGfloat escapement[2])
{
struct glyph *g;
if (glyph_string_len >= MAX_GLYPHS)
return -1;
#ifdef OPENVG_VERSION_1_1
if (glyph_string_font != VG_INVALID_HANDLE) {
vgSetGlyphToPath(glyph_string_font, glyph_string_len,
path, VG_TRUE, origin, escapement);
return glyph_string_len++;
}
#endif
g = &glyph_string[glyph_string_len];
g->is_path = VG_TRUE;
g->handle = (VGHandle) path;
g->origin[0] = origin[0];
g->origin[1] = origin[1];
g->escapement[0] = escapement[0];
g->escapement[1] = escapement[1];
return glyph_string_len++;
}
static VGint
glyph_string_add_image(VGImage image, const VGfloat origin[2], VGfloat escapement[2])
{
struct glyph *g;
if (glyph_string_len >= MAX_GLYPHS)
return -1;
#ifdef OPENVG_VERSION_1_1
if (glyph_string_font != VG_INVALID_HANDLE) {
vgSetGlyphToImage(glyph_string_font, glyph_string_len,
image, origin, escapement);
return glyph_string_len++;
}
#endif
g = &glyph_string[glyph_string_len];
g->is_path = VG_FALSE;
g->handle = (VGHandle) image;
g->origin[0] = origin[0];
g->origin[1] = origin[1];
g->escapement[0] = escapement[0];
g->escapement[1] = escapement[1];
return glyph_string_len++;
}
static void
glyph_string_draw(VGfloat x, VGfloat y)
{
VGfloat pen[2];
int i;
#ifdef OPENVG_VERSION_1_1
if (glyph_string_font != VG_INVALID_HANDLE) {
VGuint indices[MAX_GLYPHS];
for (i = 0; i < glyph_string_len; i++)
indices[i] = i;
pen[0] = x;
pen[1] = y;
vgSetfv(VG_GLYPH_ORIGIN, 2, pen);
vgDrawGlyphs(glyph_string_font, glyph_string_len, indices,
NULL, NULL, VG_FILL_PATH, VG_TRUE);
return;
}
#endif
pen[0] = (VGint) (x + 0.5f);
pen[1] = (VGint) (y + 0.5f);
for (i = 0; i < glyph_string_len; i++) {
const struct glyph *g = &glyph_string[i];
if (g->handle == VG_INVALID_HANDLE)
continue;
vgSeti(VG_MATRIX_MODE, (glyph_string[i].is_path) ?
VG_MATRIX_PATH_USER_TO_SURFACE : VG_MATRIX_IMAGE_USER_TO_SURFACE);
vgLoadIdentity();
vgTranslate(pen[0] - (VGint) g->origin[0], pen[1] - (VGint) g->origin[1]);
if (glyph_string[i].is_path)
vgDrawPath((VGPath) glyph_string[i].handle, VG_FILL_PATH);
else
vgDrawImage((VGImage) glyph_string[i].handle);
pen[0] += (VGint) (g->escapement[0] + 0.5f);
pen[1] += (VGint) (g->escapement[1] + 0.5f);
}
}
static int
path_append(VGPath path, VGubyte segment, const FT_Vector **vectors)
{
VGfloat coords[6];
int i, num_vectors;
switch (segment) {
case VG_MOVE_TO:
case VG_LINE_TO:
num_vectors = 1;
break;
case VG_QUAD_TO:
num_vectors = 2;
break;
case VG_CUBIC_TO:
num_vectors = 3;
break;
default:
return -1;
break;
}
for (i = 0; i < num_vectors; i++) {
coords[2 * i + 0] = (float) vectors[i]->x / 64.0f;
coords[2 * i + 1] = (float) vectors[i]->y / 64.0f;
}
vgAppendPathData(path, 1, &segment, (const void *) coords);
return 0;
}
static int
decompose_move_to(const FT_Vector *to, void *user)
{
VGPath path = (VGPath) (long) user;
return path_append(path, VG_MOVE_TO, &to);
}
static int
decompose_line_to(const FT_Vector *to, void *user)
{
VGPath path = (VGPath) (long) user;
return path_append(path, VG_LINE_TO, &to);
}
static int
decompose_conic_to(const FT_Vector *control, const FT_Vector *to, void *user)
{
VGPath path = (VGPath) (long) user;
const FT_Vector *vectors[2] = { control, to };
return path_append(path, VG_QUAD_TO, vectors);
}
static int
decompose_cubic_to(const FT_Vector *control1, const FT_Vector *control2,
const FT_Vector *to, void *user)
{
VGPath path = (VGPath) (long) user;
const FT_Vector *vectors[3] = { control1, control2, to };
return path_append(path, VG_CUBIC_TO, vectors);
}
static VGHandle
convert_outline_glyph(FT_GlyphSlot glyph)
{
FT_Outline_Funcs funcs = {
decompose_move_to,
decompose_line_to,
decompose_conic_to,
decompose_cubic_to,
0, 0
};
VGPath path;
path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, glyph->outline.n_points,
VG_PATH_CAPABILITY_ALL);
if (FT_Outline_Decompose(&glyph->outline, &funcs, (void *) (long) path)) {
vgDestroyPath(path);
path = VG_INVALID_HANDLE;
}
return (VGHandle) path;
}
static VGHandle
convert_bitmap_glyph(FT_GlyphSlot glyph)
{
VGImage image;
VGint width, height, stride;
unsigned char *data;
int i, j;
switch (glyph->bitmap.pixel_mode) {
case FT_PIXEL_MODE_MONO:
case FT_PIXEL_MODE_GRAY:
break;
default:
return VG_INVALID_HANDLE;
break;
}
data = glyph->bitmap.buffer;
width = glyph->bitmap.width;
height = glyph->bitmap.rows;
stride = glyph->bitmap.pitch;
/* mono to gray, and flip if needed */
if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
data = malloc(width * height);
if (!data)
return VG_INVALID_HANDLE;
for (i = 0; i < height; i++) {
char *dst = &data[width * i];
const unsigned char *src;
if (stride > 0)
src = glyph->bitmap.buffer + stride * (height - i - 1);
else
src = glyph->bitmap.buffer - stride * i;
for (j = 0; j < width; j++) {
if (src[j / 8] & (1 << (7 - (j % 8))))
dst[j] = 0xff;
else
dst[j] = 0x0;
}
}
stride = -width;
}
image = vgCreateImage(VG_A_8, width, height,
VG_IMAGE_QUALITY_NONANTIALIASED);
if (stride < 0) {
stride = -stride;
vgImageSubData(image, data, stride, VG_A_8,
0, 0, width, height);
}
else {
/* flip vertically */
for (i = 0; i < height; i++) {
const char *row = data + stride * i;
vgImageSubData(image, row, stride, VG_A_8,
0, height - i - 1, width, 1);
}
}
if (data != glyph->bitmap.buffer)
free(data);
return (VGHandle) image;
}
static void
glyph_string_init(const char *font, int size, const char *str)
{
FT_Library lib = NULL;
FT_Face face = NULL;
int i;
if (FT_Init_FreeType(&lib)) {
printf("failed to initialize freetype\n");
goto fail;
}
if (FT_New_Face(lib, font, 0, &face)) {
printf("failed to load %s\n", glyph_string);
goto fail;
}
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE)) {
printf("failed to select an unicode charmap\n");
goto fail;
}
if (FT_Set_Pixel_Sizes(face, size, size))
printf("failed to set pixel sizes\n");
for (i = 0; str[i]; i++) {
VGfloat origin[2], escapement[2];
VGHandle handle;
/*
* if a character appears more than once, it will be loaded and converted
* again...
*/
if (FT_Load_Char(face, str[i], FT_LOAD_DEFAULT)) {
printf("failed to load glyph '%c'\n", str[i]);
goto fail;
}
escapement[0] = (VGfloat) face->glyph->advance.x / 64.0f;
escapement[1] = (VGfloat) face->glyph->advance.y / 64.0f;
switch (face->glyph->format) {
case FT_GLYPH_FORMAT_OUTLINE:
handle = convert_outline_glyph(face->glyph);
origin[0] = 0.0f;
origin[1] = 0.0f;
glyph_string_add_path((VGPath) handle, origin, escapement);
break;
case FT_GLYPH_FORMAT_BITMAP:
handle = convert_bitmap_glyph(face->glyph);
origin[0] = (VGfloat) (-face->glyph->bitmap_left);
origin[1] = (VGfloat)
(face->glyph->bitmap.rows - face->glyph->bitmap_top);
glyph_string_add_image((VGImage) handle, origin, escapement);
break;
default:
printf("unsupported format for glyph '%c'\n", str[i]);
break;
}
if (handle == VG_INVALID_HANDLE)
printf("failed to add glyph '%c'\n", str[i]);
}
fail:
if (face)
FT_Done_Face(face);
if (lib)
FT_Done_FreeType(lib);
}
static void
display(void)
{
vgClear(0, 0, width, height);
glyph_string_draw(10.0, 10.0);
}
/* new window size or exposure */
static void
reshape(int w, int h)
{
width = w;
height = h;
}
static void
init(void)
{
VGPaint paint;
float clear_color[4] = { 0.9, 0.9, 0.9, 1.0 };
vgSetfv(VG_CLEAR_COLOR, 4, clear_color);
vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL);
paint = vgCreatePaint();
vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
vgSetColor(paint, 0x660000ff);
vgSetPaint(paint, VG_FILL_PATH);
#ifdef OPENVG_VERSION_1_1
{
const char *ver = (const char *) vgGetString(VG_VERSION);
if (!strcmp(ver, "1.1"))
glyph_string_font = vgCreateFont(0);
}
#endif
if (glyph_string_font != VG_INVALID_HANDLE)
printf("using OpenVG text support\n");
}
int
main(int argc, char *argv[])
{
const char *font, *str;
if (argc < 2) {
printf("Usage: %s <path-to-font> [<string>]\n", argv[0]);
return 1;
}
font = argv[1];
str = (argc > 2) ? argv[2] : "Hello World";
eglutInitWindowSize(480, 80);
eglutInitAPIMask(EGLUT_OPENVG_BIT);
eglutInit(argc, argv);
eglutCreateWindow("Text Example");
eglutReshapeFunc(reshape);
eglutDisplayFunc(display);
init();
glyph_string_init(font, 64, str);
eglutMainLoop();
return 0;
}
include_directories(
${EGL_INCLUDE_DIRS}
${VG_INCLUDE_DIRS}
)
set (subdir egl/openvg/trivial)
add_library (common STATIC eglcommon)
set (targets
arc
cap
blend
clear
color_transform
coord
dash
ellipse
filter
gradorigin
image
layer
lineto
lingrad
lookup
mask4
mask
mask_render
paint
path3
radialgrad
readpixels
roundedrect
star-nonzero
star-oddeven
stroke2
stroke
# VGU is broken on current mesa master
# vguarc
)
foreach (target ${targets})
if (X11_FOUND)
add_executable (openvg_${target} ${target}.c)
target_link_libraries (openvg_${target} common ${VG_LIBRARIES} ${EGL_LIBRARIES} ${X11_X11_LIB})
set_target_properties (openvg_${target} PROPERTIES OUTPUT_NAME ${target})
install (TARGETS openvg_${target} DESTINATION ${subdir})
endif ()
endforeach (target)
This diff is collapsed.
This diff is collapsed.