Demos (master): Add a new example rendering a bezier curve using a geometry shader

Zack Rusin zack at kemper.freedesktop.org
Sat Jul 10 22:20:07 UTC 2010


Module: Demos
Branch: master
Commit: f2f123f880ec4a6abaddfe0a1906aea2f954fd90
URL:    http://cgit.freedesktop.org/mesa/demos/commit/?id=f2f123f880ec4a6abaddfe0a1906aea2f954fd90

Author: Zack Rusin <zack at kde.org>
Date:   Sat Jul 10 18:23:22 2010 -0400

Add a new example rendering a bezier curve using a geometry shader

---

 src/glsl/Makefile.am |    3 +
 src/glsl/SConscript  |    1 +
 src/glsl/bezier.c    |  224 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/glsl/bezier.geom |   29 +++++++
 src/gs/basic.glsl    |    3 -
 5 files changed, 257 insertions(+), 3 deletions(-)

diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am
index 90ce691..154189a 100644
--- a/src/glsl/Makefile.am
+++ b/src/glsl/Makefile.am
@@ -33,6 +33,7 @@ AM_LDFLAGS = \
 if HAVE_GLUT
 bin_PROGRAMS = \
 	array \
+        bezier \
 	bitmap \
 	brick \
 	bump \
@@ -69,6 +70,7 @@ samplers_array_CFLAGS = $(AM_CFLAGS) -DSAMPLERS_ARRAY
 
 array_LDADD = ../util/libutil.la
 bitmap_LDADD = ../util/libutil.la
+bezier_LDADD = ../util/libutil.la
 brick_LDADD = ../util/libutil.la
 bump_LDADD = ../util/libutil.la
 convolutions_LDADD = ../util/libutil.la
@@ -103,6 +105,7 @@ EXTRA_DIST = \
 	CH11-toyball.vert \
 	CH18-mandel.frag \
 	CH18-mandel.vert \
+        bezier.geom \
 	brick.shtest \
 	convolution.vert \
 	cubemap.frag \
diff --git a/src/glsl/SConscript b/src/glsl/SConscript
index 02884e5..dff9f93 100644
--- a/src/glsl/SConscript
+++ b/src/glsl/SConscript
@@ -3,6 +3,7 @@ Import('*')
 progs = [
       'array',
       'bitmap',
+      'bezier',
       'brick',
       'bump',
       'convolutions',
diff --git a/src/glsl/bezier.c b/src/glsl/bezier.c
new file mode 100644
index 0000000..1e2c7b8
--- /dev/null
+++ b/src/glsl/bezier.c
@@ -0,0 +1,224 @@
+/*
+ * Simple example for testing basic features of
+ * geometry shaders
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GL/glut.h>
+#include <GL/glext.h>
+
+static const char *filename = "bezier.geom";
+
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint geoShader;
+static GLuint program;
+
+GLfloat vertices[][3] =
+   { {  -0.9, -0.9, 0.0 },
+     {  -0.5,  0.9, 0.0 },
+     {   0.5,  0.9, 0.0 },
+     {   0.9, -0.9, 0.0 } };
+
+GLfloat color[][4] = 
+{ { 1, 1, 1, 1 },
+  { 1, 1, 1, 1 },
+  { 1, 1, 1, 1 },
+  { 1, 1, 1, 1 } };
+
+
+static void usage( char *name )
+{
+   fprintf(stderr, "usage: %s\n", name);
+   fprintf(stderr, "\n" );
+}
+
+
+static void load_and_compile_shader(GLuint shader, const char *text)
+{
+   GLint stat;
+
+   glShaderSource(shader, 1, (const GLchar **) &text, NULL);
+   glCompileShader(shader);
+   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetShaderInfoLog(shader, 1000, &len, log);
+      fprintf(stderr, "bezier: problem compiling shader:\n%s\n", log);
+      exit(1);
+   }
+}
+
+static void read_shader(GLuint shader, const char *filename)
+{
+   const int max = 100*1000;
+   int n;
+   char *buffer = (char*) malloc(max);
+   FILE *f = fopen(filename, "r");
+   if (!f) {
+      fprintf(stderr, "bezier: Unable to open shader file %s\n", filename);
+      exit(1);
+   }
+
+   n = fread(buffer, 1, max, f);
+   printf("bezier: read %d bytes from shader file %s\n", n, filename);
+   if (n > 0) {
+      buffer[n] = 0;
+      load_and_compile_shader(shader, buffer);
+   }
+
+   fclose(f);
+   free(buffer);
+}
+
+static void check_link(GLuint prog)
+{
+   GLint stat;
+   glGetProgramiv(prog, GL_LINK_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetProgramInfoLog(prog, 1000, &len, log);
+      fprintf(stderr, "Linker error:\n%s\n", log);
+   }
+}
+
+static void prepare_shaders(void)
+{
+   static const char *fragShaderText =
+      "void main() {\n"
+      "    gl_FragColor = gl_Color;\n"
+      "}\n";
+   static const char *vertShaderText =
+      "void main() {\n"
+      "   gl_FrontColor = gl_Color;\n"
+      "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+      "}\n";
+   static const char *geoShaderText =
+      "#version 120\n"
+      "#extension GL_ARB_geometry_shader4 : enable\n"
+      "void main()\n"
+      "{\n"
+      "  for(int i = 0; i < gl_VerticesIn; ++i)\n"
+      "  {\n"
+      "    gl_FrontColor = gl_FrontColorIn[i];\n"
+      "    gl_Position = gl_PositionIn[i];\n"
+      "    EmitVertex();\n"
+      "  }\n"
+      "}\n";
+   fragShader = glCreateShader(GL_FRAGMENT_SHADER);
+   load_and_compile_shader(fragShader, fragShaderText);
+
+   vertShader = glCreateShader(GL_VERTEX_SHADER);
+   load_and_compile_shader(vertShader, vertShaderText);
+
+   geoShader = glCreateShader(GL_GEOMETRY_SHADER_ARB);
+   if (filename)
+      read_shader(geoShader, filename);
+   else
+      load_and_compile_shader(geoShader,
+                              geoShaderText);
+
+   program = glCreateProgram();
+   glAttachShader(program, vertShader);
+   glAttachShader(program, geoShader);
+   glAttachShader(program, fragShader);
+
+   glProgramParameteriARB(program, GL_GEOMETRY_INPUT_TYPE_ARB,
+                          GL_LINES_ADJACENCY_ARB);
+   glProgramParameteriARB(program, GL_GEOMETRY_OUTPUT_TYPE_ARB,
+                          GL_LINE_STRIP);
+
+   {
+      int temp;
+      glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB,&temp);
+      glProgramParameteriARB(program,GL_GEOMETRY_VERTICES_OUT_ARB,temp);
+   }
+
+   glLinkProgram(program);
+   check_link(program);
+   glUseProgram(program);
+
+   glEnableClientState( GL_VERTEX_ARRAY );
+   glEnableClientState( GL_COLOR_ARRAY );
+
+   glVertexPointer( 3, GL_FLOAT, sizeof(vertices[0]), vertices );
+   glColorPointer( 4, GL_FLOAT, sizeof(color[0]), color );
+}
+
+static void args(int argc, char *argv[])
+{
+   if (argc != 1) {
+      usage(argv[0]);
+      exit(1);
+   }
+}
+
+static void Display( void )
+{
+   glClearColor(0, 0, 0, 1);
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glUseProgram(program);
+
+   glEnable(GL_VERTEX_PROGRAM_ARB);
+
+   glDrawArrays(GL_LINES_ADJACENCY_ARB, 0, 4);
+
+   glFlush();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   /*glTranslatef( 0.0, 0.0, -15.0 );*/
+}
+
+
+static void CleanUp(void)
+{
+   glDeleteShader(fragShader);
+   glDeleteShader(vertShader);
+   glDeleteProgram(program);
+}
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         CleanUp();
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize( 250, 250 );
+   glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
+   glutCreateWindow(argv[0]);
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutDisplayFunc( Display );
+   args( argc, argv );
+   prepare_shaders();
+   glutMainLoop();
+   return 0;
+}
diff --git a/src/glsl/bezier.geom b/src/glsl/bezier.geom
new file mode 100644
index 0000000..4ef75f4
--- /dev/null
+++ b/src/glsl/bezier.geom
@@ -0,0 +1,29 @@
+#version 120
+#extension GL_EXT_geometry_shader4: enable
+
+void main()
+{
+   /* num is the number of subdivisions
+    * can be anything between 1 and infinity
+    */
+   const int num = 3;
+
+   float dt = 1. / float(num);
+   float t = 0.;
+   for (int i = 0; i <= num; i++) {
+      float omt = 1. - t;
+      float omt2 = omt * omt;
+      float omt3 = omt * omt2;
+      float t2 = t * t;
+      float t3 = t * t2;
+      vec4 xyzw =
+         omt3 * gl_PositionIn[0].xyzw +
+         3. * t * omt2 * gl_PositionIn[1].xyzw +
+         3. * t2 * omt * gl_PositionIn[2].xyzw +
+         t3 * gl_PositionIn[3].xyzw;
+      gl_Position = xyzw;
+      gl_FrontColor = vec4(1, 1, 1, 1);
+      EmitVertex();
+      t += dt;
+   }
+}
diff --git a/src/gs/basic.glsl b/src/gs/basic.glsl
index 256a1e6..3f5ac78 100644
--- a/src/gs/basic.glsl
+++ b/src/gs/basic.glsl
@@ -1,14 +1,11 @@
 #version 120
 #extension GL_ARB_geometry_shader4 : enable
 
-const int KernelSize = 9;
-
 void main()
 {
   for(int i = 0; i < gl_VerticesIn; ++i)
   {
     gl_FrontColor = gl_FrontColorIn[i];
-    gl_BackColor = gl_BackColorIn[i];
     gl_Position = gl_PositionIn[i];
     EmitVertex();
   }




More information about the mesa-commit mailing list