X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=examples%2Fsorting%2Fsort.c;h=839c7c55170d48a5a46f4a97618ab93563474bb7;hb=c0075ba789491de3bb30fd37c6c382685f73bf75;hp=9ad01fa376dd9df830d0c32bdc0f6f8453161214;hpb=d1004540ed1e61b03752a9aba8a641b9fbc406f6;p=grits diff --git a/examples/sorting/sort.c b/examples/sorting/sort.c index 9ad01fa..839c7c5 100644 --- a/examples/sorting/sort.c +++ b/examples/sorting/sort.c @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2009-2010 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define GL_GLEXT_PROTOTYPES #include #include #include @@ -5,9 +23,14 @@ #include #include +gdouble pos[3]; +gdouble rot[3]; +guint tex; + typedef struct { - gfloat xyz[3]; + gfloat xyz[4]; gfloat color[4]; + gfloat texture[4]; } __attribute__ ((packed)) vert_t; static int sort_cmp(const void *a, const void *b) @@ -24,7 +47,7 @@ static gfloat *sort_start() { int size = 1000000; gfloat *data = g_new0(gfloat, size); - glFeedbackBuffer(size, GL_3D_COLOR, data); + glFeedbackBuffer(size, GL_4D_COLOR_TEXTURE, data); glRenderMode(GL_FEEDBACK); g_print("1st = %f\n", data[0]); return data; @@ -40,13 +63,26 @@ static void sort_end(gfloat *data) glGetIntegerv(GL_VIEWPORT, view); glMatrixMode(GL_PROJECTION); + glPushMatrix(); glLoadIdentity(); - glOrtho(view[0],view[2], view[1],view[3], -10,10); + glOrtho(view[0],view[2], view[1],view[3], -100,100); glMatrixMode(GL_MODELVIEW); + glPushMatrix(); glLoadIdentity(); glDisable(GL_LIGHTING); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + + //glTranslatef(pos[0], pos[1], pos[2]); + //glTranslatef(0.05, 0.1, -2); + //glRotatef(0.03, 1, 1, 0); + + //gluPerspective(90, 0.8, 0.1, 10); + + /* Sort the vertexes (this only works with all-triangles */ int trisize = 2*sizeof(gfloat) + 3*sizeof(vert_t); int ntris = nvals*sizeof(gfloat) / trisize; @@ -65,25 +101,52 @@ static void sort_end(gfloat *data) /* Draw triangle */ glBegin(GL_TRIANGLES); for (int j = 0; j < n; j++) { - //g_print("\t%f, %f, %f\n", - // verts[j].xyz[0], - // verts[j].xyz[1], - // verts[j].xyz[2]); - glColor4fv(verts[j].color); - glVertex3fv(verts[j].xyz); + g_print("\t%7.2f, %6.2f, %6.2f %6.2f - " + "%5.2f, %5.2f, %5.2f, %5.2f\n", + verts[j].xyz[0], + verts[j].xyz[1], + verts[j].xyz[2], + verts[j].xyz[3], + verts[j].texture[0], + verts[j].texture[1], + verts[j].texture[2], + verts[j].texture[3]); + glTexCoord4f( + verts[j].texture[0], + verts[j].texture[1], + verts[j].texture[2], + verts[j].texture[3]); + glColor4f( + verts[j].color[0], + verts[j].color[1], + verts[j].color[2], + verts[j].color[3]); + if (j == 2) + verts[j].xyz[2] = -100; + glVertex3f( + verts[j].xyz[0], + verts[j].xyz[1], + verts[j].xyz[2]); } glEnd(); /* Draw line */ - glColor4f(1,1,1,1); - glBegin(GL_LINE_LOOP); - for (int j = 0; j < n; j++) - glVertex3fv(verts[j].xyz); - glEnd(); + //glDisable(GL_TEXTURE_2D); + //glBegin(GL_LINE_LOOP); + //glColor4f(1,1,1,1); + //for (int j = 0; j < n; j++) + // glVertex3fv(verts[j].xyz); + //glEnd(); } else { g_error("Unknown token: %f\n", token); } } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); g_free(data); } @@ -114,26 +177,45 @@ static gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _) glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); - /* Set up projection */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(1,-1, -0.7,0.7, -10,10); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); /* Draw teapots */ + g_print("%f,%f,%f\n", pos[0], pos[1], pos[2]); + g_print("%f,%f,%f\n", rot[0], rot[1], rot[2]); + glMatrixMode(GL_MODELVIEW); gfloat *data = sort_start(); glLoadIdentity(); - glTranslatef(0.05, 0.05, -2); - glRotatef(30, 1, -1, -0.2); - glColor4f(1.0, 0.2, 0.2, 0.6); - gdk_gl_draw_teapot(TRUE, 0.5); + glTranslatef(pos[0], pos[1], pos[2]); + glTranslatef(0.05, 0.1, -2); + glRotatef(60, 1, -1, -0.2); + glColor4f(1,1,1,1); + glDisable(GL_COLOR_MATERIAL); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-0.8, 0.5, 0.0); + glTexCoord2f(0, 1); glVertex3f(-0.8, -0.5, 0.0); + glTexCoord2f(1, 1); glVertex3f( 0.8, -0.5, 0.0); + glTexCoord2f(1, 0); glVertex3f( 0.8, 0.5, 0.0); + glEnd(); - glLoadIdentity(); - glTranslatef(-0.2, -0.05, -2); - glRotatef(30, 1, -1, -0.2); - glColor4f(0.2, 0.2, 1.0, 0.6); - gdk_gl_draw_teapot(TRUE, 0.5); + //glLoadIdentity(); + //glTranslatef(pos[0], pos[1], pos[2]); + //glTranslatef(0.05, 0.1, -2); + //glRotatef(30, 1, -1, -0.2); + //glColor4f(1.0, 0.2, 0.2, 0.5); + ////gdk_gl_draw_teapot(TRUE, 0.5); + //gdk_gl_draw_cube(TRUE, 0.5); + + //glLoadIdentity(); + //glTranslatef(pos[0], pos[1], pos[2]); + //glTranslatef(-0.2, 0, -2); + //glRotatef(30, 1, -1, -0.2); + //glColor4f(0.2, 0.2, 1.0, 0.5); + ////gdk_gl_draw_teapot(TRUE, 0.5); + //gdk_gl_draw_cube(TRUE, 0.5); sort_end(data); /* Flush */ @@ -147,19 +229,108 @@ static gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _) static gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _) { - glViewport(0, 0, - drawing->allocation.width, - drawing->allocation.height); + gdouble width = drawing->allocation.width; + gdouble height = drawing->allocation.height; + glViewport(0, 0, width, height); + + /* Set up projection */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + //gluPerspective(90, width/height, 0.1, 10); + gluPerspective(90, 0.8, 0.1, 10); + //glOrtho(1,-1, -0.7,0.7, -10,10); return FALSE; } static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _) { - if (event->keyval == GDK_q) - gtk_main_quit(); + guint kv = event->keyval; + if (kv == GDK_q) gtk_main_quit(); + else if (kv == GDK_h) pos[0] -= 0.02; + else if (kv == GDK_j) pos[1] += 0.02; + else if (kv == GDK_k) pos[1] -= 0.02; + else if (kv == GDK_l) pos[0] += 0.02; + else if (kv == GDK_o) pos[2] -= 0.02; + else if (kv == GDK_i) pos[2] += 0.02; + else if (kv == GDK_H) rot[2] -= 2.0; + else if (kv == GDK_J) rot[0] += 2.0; + else if (kv == GDK_K) rot[0] -= 2.0; + else if (kv == GDK_L) rot[2] += 2.0; + gtk_widget_queue_draw(widget); return FALSE; } +static guint load_tex(gchar *filename) +{ + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, NULL); + guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); + int width = gdk_pixbuf_get_width(pixbuf); + int height = gdk_pixbuf_get_height(pixbuf); + int alpha = gdk_pixbuf_get_has_alpha(pixbuf); + guint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, + (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, pixels); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + g_object_unref(pixbuf); + return tex; +} + +gchar *gl_program_log(guint program, int *_len) +{ + gchar *buf = NULL; + int len = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); + if (len > 0) { + buf = g_malloc(len); + glGetProgramInfoLog(program, len, &len, buf); + } + if (_len) + *_len = len; + return buf; +} + +static void load_shader(gchar *filename) +{ + gchar *source; + gboolean status = g_file_get_contents(filename, &source, NULL, NULL); + if (!status) + g_error("Failed to load shader"); + + guint program = glCreateProgram(); + if (!program) + g_error("Error creating program"); + + guint shader = glCreateShader(GL_VERTEX_SHADER_ARB); + if (!shader) + g_error("Error creating shader"); + + glShaderSource(shader, 1, (const gchar**)&source, NULL); + if (glGetError()) + g_error("Error setting shader source"); + + glCompileShader(shader); + if (glGetError()) + g_error("Error compiling shader"); + + glAttachShader(program, shader); + if (glGetError()) + g_error("Error attaching shader"); + + glLinkProgram(program); + if (glGetError()) + g_error("Error linking program"); + + glUseProgram(program); + if (glGetError()) + g_error("Error using program:\n%s", gl_program_log(program, NULL)); +} + int main(int argc, char **argv) { gtk_init(&argc, &argv); @@ -182,6 +353,12 @@ int main(int argc, char **argv) GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing)); gdk_gl_drawable_gl_begin(gldrawable, glcontext); + /* Load texture */ + tex = load_tex("flag.png"); + + /* Load shader */ + load_shader("sort.glsl"); + gtk_main(); gdk_gl_drawable_gl_end(gldrawable);