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