From 8a9cda8cfb25d1dc41ed3864ee0b9ee637495b24 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Mon, 3 Nov 2008 15:31:30 -0500 Subject: Add the gears from glxgears. --- Makefile | 12 +++- gears.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gears.h | 10 +++ window.c | 78 ++++++++++++++++++++++-- 4 files changed, 298 insertions(+), 9 deletions(-) create mode 100644 gears.c create mode 100644 gears.h diff --git a/Makefile b/Makefile index a335cb1..a533f61 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,16 @@ CFLAGS += -Wall -g $(shell pkg-config --cflags libffi libdrm) LDLIBS += $(shell pkg-config --libs libffi libdrm) +EAGLE_CFLAGS = -I../eagle +EAGLE_LDLIBS = -L../eagle -leagle + clients = flower pointer background window all : wayland $(clients) wayland_objs = wayland.o event-loop.o connection.o hash.o input.o egl-compositor.o -wayland : CFLAGS += -I../eagle -wayland : LDLIBS += -L../eagle -leagle -ldl +wayland : CFLAGS += $(EAGLE_CFLAGS) +wayland : LDLIBS += $(EAGLE_LDLIBS) wayland : $(wayland_objs) gcc -o $@ $(LDLIBS) $(wayland_objs) @@ -20,7 +23,7 @@ libwayland.so : $(libwayland_objs) flower_objs = flower.o pointer_objs = pointer.o background_objs = background.o -window_objs = window.o +window_objs = window.o gears.o $(clients) : CFLAGS += $(shell pkg-config --cflags cairo) $(clients) : LDLIBS += $(shell pkg-config --libs cairo gdk-pixbuf-2.0) -lrt @@ -28,6 +31,9 @@ $(clients) : LDLIBS += $(shell pkg-config --libs cairo gdk-pixbuf-2.0) -lrt background : CFLAGS += $(shell pkg-config --cflags gdk-pixbuf-2.0) background : LDLIBS += $(shell pkg-config --libs gdk-pixbuf-2.0) +window : CFLAGS += $(EAGLE_CFLAGS) +window : LDLIBS += $(EAGLE_LDLIBS) + define client_template $(1): $$($(1)_objs) libwayland.so endef diff --git a/gears.c b/gears.c new file mode 100644 index 0000000..db79d4d --- /dev/null +++ b/gears.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include "gears.h" + +struct gears { + GLint gear1, gear2, gear3; +}; + +static void +gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, + GLint teeth, GLfloat tooth_depth) +{ + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + da = 2.0 * M_PI / teeth / 4.0; + + glShadeModel(GL_FLAT); + + glNormal3f(0.0, 0.0, 1.0); + + /* draw front face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + if (i < teeth) { + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); + } + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * M_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); + } + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + + /* draw back face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + if (i < teeth) { + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + } + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * M_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + u = r2 * cos(angle + da) - r1 * cos(angle); + v = r2 * sin(angle + da) - r1 * sin(angle); + len = sqrt(u * u + v * v); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); + u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); + v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); + glNormal3f(v, -u, 0.0); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + } + + glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5); + glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5); + + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glNormal3f(-cos(angle), -sin(angle), 0.0); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + } + glEnd(); +} + +struct gears * +gears_create(void) +{ + static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0}; + static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0}; + static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0}; + struct gears *gears; + + gears = malloc(sizeof *gears); + /* make the gears */ + gears->gear1 = glGenLists(1); + glNewList(gears->gear1, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear(1.0, 4.0, 1.0, 20, 0.7); + glEndList(); + + gears->gear2 = glGenLists(1); + glNewList(gears->gear2, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear(0.5, 2.0, 2.0, 10, 0.7); + glEndList(); + + gears->gear3 = glGenLists(1); + glNewList(gears->gear3, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear(1.3, 2.0, 0.5, 10, 0.7); + glEndList(); + + glEnable(GL_NORMALIZE); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 200.0); + glMatrixMode(GL_MODELVIEW); + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + return gears; +} + +void +gears_draw(struct gears *gears, GLfloat angle) +{ + GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; + + glPushMatrix(); + + glTranslatef(0.0, 0.0, -50); + + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + glCallList(gears->gear1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1, -2.0, 0.0); + glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); + glCallList(gears->gear2); + glPopMatrix(); + + + glPushMatrix(); + glTranslatef(-3.1, 4.2, 0.0); + glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); + glCallList(gears->gear3); + glPopMatrix(); + + glPopMatrix(); + + glFlush(); +} diff --git a/gears.h b/gears.h new file mode 100644 index 0000000..76b8d63 --- /dev/null +++ b/gears.h @@ -0,0 +1,10 @@ +#ifndef _GEARS_H_ +#define _GEARS_H_ + +struct gears; + +struct gears *gears_create(void); + +void gears_draw(struct gears *gears, GLfloat angle); + +#endif diff --git a/window.c b/window.c index 0067488..7db8c2c 100644 --- a/window.c +++ b/window.c @@ -11,11 +11,21 @@ #include #include +#include +#include + #include "wayland-client.h" +#include "gears.h" static const char gem_device[] = "/dev/dri/card0"; static const char socket_name[] = "\0wayland"; +static void die(const char *msg) +{ + fprintf(stderr, "%s", msg); + exit(EXIT_FAILURE); +} + static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface) { struct drm_i915_gem_create create; @@ -75,6 +85,11 @@ struct window { uint32_t name; int fd; int need_redraw; + + EGLDisplay display; + EGLContext context; + EGLConfig config; + EGLSurface egl_surface; }; static void * @@ -82,7 +97,7 @@ draw_window(struct window *window) { cairo_surface_t *surface; cairo_t *cr; - int border = 2, radius = 5; + int border = 2, radius = 5, h; int margin = (border + 1) / 2; cairo_text_extents_t extents; const static char title[] = "Wayland First Post"; @@ -108,8 +123,9 @@ draw_window(struct window *window) cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_font_size(cr, 14); cairo_text_extents(cr, title, &extents); - cairo_move_to(cr, margin, margin + radius + extents.height + 10); - cairo_line_to(cr, margin + window->width, margin + radius + extents.height + 10); + h = margin + radius + extents.height + 10; + cairo_move_to(cr, margin, h); + cairo_line_to(cr, margin + window->width, h); cairo_stroke(cr); cairo_move_to(cr, (window->width - extents.width) / 2, 10 - extents.y_bearing); @@ -129,6 +145,24 @@ draw_window(struct window *window) window->x, window->y, window->width, window->height); + if (window->egl_surface != EGL_NO_SURFACE) + eglDestroySurface(window->display, window->egl_surface); + + /* FIXME: We need to get the stride right here in a chipset + * independent way. Maybe do it in name_cairo_surface(). */ + window->egl_surface = eglCreatePixmapForName(window->display, + window->config, window->name, + window->width, window->height, + window->stride, NULL); + if (surface == NULL) + die("failed to create surface\n"); + + if (!eglMakeCurrent(window->display, + window->egl_surface, window->egl_surface, window->context)) + die("failed to make context current\n"); + + glViewport(border, window->height - h - margin - 300, 300, 300); + return surface; } @@ -226,6 +260,30 @@ void event_handler(struct wl_display *display, } } +static void +init_egl(struct window *window) +{ + EGLint major, minor, count; + EGLConfig configs[64]; + + window->display = eglCreateDisplayNative("/dev/dri/card0", "i965"); + if (window->display == NULL) + die("failed to create display\n"); + + if (!eglInitialize(window->display, &major, &minor)) + die("failed to initialize display\n"); + + if (!eglGetConfigs(window->display, configs, 64, &count)) + die("failed to get configs\n"); + + window->config = configs[24]; + window->context = eglCreateContext(window->display, window->config, NULL, NULL); + if (window->context == NULL) + die("failed to create context\n"); + + window->egl_surface = EGL_NO_SURFACE; +} + int main(int argc, char *argv[]) { struct wl_display *display; @@ -234,6 +292,8 @@ int main(int argc, char *argv[]) cairo_surface_t *s; struct pollfd p[1]; struct window window; + struct gears *gears; + GLfloat angle = 0.0; fd = open(gem_device, O_RDWR); if (fd < 0) { @@ -252,17 +312,23 @@ int main(int argc, char *argv[]) window.surface = wl_display_create_surface(display); window.x = 200; window.y = 200; - window.width = 350; - window.height = 200; + window.width = 450; + window.height = 500; window.state = WINDOW_STABLE; window.fd = fd; + init_egl(&window); + s = draw_window(&window); wl_display_set_event_handler(display, event_handler, &window); - while (ret = poll(p, 1, -1), ret >= 0) { + gears = gears_create(); + + while (ret = poll(p, 1, 20), ret >= 0) { mask = 0; + gears_draw(gears, angle); + angle += 1; if (p[0].revents & POLLIN) mask |= WL_CONNECTION_READABLE; if (p[0].revents & POLLOUT) -- cgit