summaryrefslogtreecommitdiff
path: root/progs/demos/fslight.c
diff options
context:
space:
mode:
Diffstat (limited to 'progs/demos/fslight.c')
-rw-r--r--progs/demos/fslight.c385
1 files changed, 333 insertions, 52 deletions
diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c
index 1c016cc75e..b03ba2315a 100644
--- a/progs/demos/fslight.c
+++ b/progs/demos/fslight.c
@@ -20,46 +20,37 @@
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
+#include "extfuncs.h"
+
+
+static GLint CoordAttrib = 0;
+
+static char *FragProgFile = NULL;
+static char *VertProgFile = NULL;
static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
-static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f };
+static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f };
static GLfloat delta = 1.0f;
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
-static GLint uLightPos;
static GLint uDiffuse;
static GLint uSpecular;
+static GLint uTexture;
+static GLuint SphereList, RectList, CurList;
static GLint win = 0;
-static GLboolean anim = GL_TRUE;
+static GLboolean anim = GL_FALSE;
static GLboolean wire = GL_FALSE;
static GLboolean pixelLight = GL_TRUE;
static GLint t0 = 0;
static GLint frames = 0;
-static GLfloat xRot = 0.0f, yRot = 0.0f;
-
-static PFNGLCREATESHADERPROC glCreateShader_func = NULL;
-static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL;
-static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL;
-static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL;
-static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL;
-static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL;
-static PFNGLDELETESHADERPROC glDeleteShader_func = NULL;
-static PFNGLATTACHSHADERPROC glAttachShader_func = NULL;
-static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL;
-static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL;
-static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL;
-static PFNGLISPROGRAMPROC glIsProgram_func = NULL;
-static PFNGLISSHADERPROC glIsShader_func = NULL;
-static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL;
-static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL;
-
+static GLfloat xRot = 90.0f, yRot = 0.0f;
static void
@@ -69,31 +60,37 @@ normalize(GLfloat *dst, const GLfloat *src)
dst[0] = src[0] / len;
dst[1] = src[1] / len;
dst[2] = src[2] / len;
+ dst[3] = src[3];
}
static void
Redisplay(void)
{
+ GLfloat vec[4];
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /* update light position */
+ normalize(vec, lightPos);
+ glLightfv(GL_LIGHT0, GL_POSITION, vec);
if (pixelLight) {
- GLfloat vec[3];
glUseProgram_func(program);
- normalize(vec, lightPos);
- glUniform3fv_func(uLightPos, 1, vec);
glDisable(GL_LIGHTING);
}
else {
glUseProgram_func(0);
- glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_LIGHTING);
}
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
+ /*
glutSolidSphere(2.0, 10, 5);
+ */
+ glCallList(CurList);
glPopMatrix();
glutSwapBuffers();
@@ -174,6 +171,12 @@ Key(unsigned char key, int x, int y)
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
+ case 'o':
+ if (CurList == SphereList)
+ CurList = RectList;
+ else
+ CurList = SphereList;
+ break;
case 'p':
pixelLight = !pixelLight;
if (pixelLight)
@@ -217,16 +220,246 @@ SpecialKey(int key, int x, int y)
static void
+TestFunctions(void)
+{
+ printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
+ {
+ GLfloat pos[3];
+ printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
+ printf("Light pos %g %g %g\n", pos[0], pos[1], pos[2]);
+ }
+
+
+ {
+ GLfloat m[16], result[16];
+ GLint mPos;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ m[i] = (float) i;
+
+ mPos = glGetUniformLocation_func(program, "m");
+ printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
+ glUniformMatrix4fv_func(mPos, 1, GL_FALSE, m);
+ printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
+
+ glGetUniformfv_func(program, mPos, result);
+ printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
+
+ for (i = 0; i < 16; i++) {
+ printf("%8g %8g\n", m[i], result[i]);
+ }
+ }
+
+ assert(glIsProgram_func(program));
+ assert(glIsShader_func(fragShader));
+ assert(glIsShader_func(vertShader));
+
+ /* attached shaders */
+ {
+ GLuint shaders[20];
+ GLsizei count;
+ int i;
+ glGetAttachedShaders_func(program, 20, &count, shaders);
+ for (i = 0; i < count; i++) {
+ printf("Attached: %u\n", shaders[i]);
+ assert(shaders[i] == fragShader ||
+ shaders[i] == vertShader);
+ }
+ }
+
+ {
+ GLchar log[1000];
+ GLsizei len;
+ glGetShaderInfoLog_func(vertShader, 1000, &len, log);
+ printf("Vert Shader Info Log: %s\n", log);
+ glGetShaderInfoLog_func(fragShader, 1000, &len, log);
+ printf("Frag Shader Info Log: %s\n", log);
+ glGetProgramInfoLog_func(program, 1000, &len, log);
+ printf("Program Info Log: %s\n", log);
+ }
+}
+
+
+static void
+MakeTexture(void)
+{
+#define SZ0 128
+#define SZ1 64
+ GLubyte image0[SZ0][SZ0][SZ0][4];
+ GLubyte image1[SZ1][SZ1][SZ1][4];
+ GLuint i, j, k;
+
+ /* level 0: two-tone gray checkboard */
+ for (i = 0; i < SZ0; i++) {
+ for (j = 0; j < SZ0; j++) {
+ for (k = 0; k < SZ0; k++) {
+ if ((i/8 + j/8 + k/8) & 1) {
+ image0[i][j][k][0] =
+ image0[i][j][k][1] =
+ image0[i][j][k][2] = 200;
+ }
+ else {
+ image0[i][j][k][0] =
+ image0[i][j][k][1] =
+ image0[i][j][k][2] = 100;
+ }
+ image0[i][j][k][3] = 255;
+ }
+ }
+ }
+
+ /* level 1: two-tone green checkboard */
+ for (i = 0; i < SZ1; i++) {
+ for (j = 0; j < SZ1; j++) {
+ for (k = 0; k < SZ1; k++) {
+ if ((i/8 + j/8 + k/8) & 1) {
+ image1[i][j][k][0] = 0;
+ image1[i][j][k][1] = 250;
+ image1[i][j][k][2] = 0;
+ }
+ else {
+ image1[i][j][k][0] = 0;
+ image1[i][j][k][1] = 200;
+ image1[i][j][k][2] = 0;
+ }
+ image1[i][j][k][3] = 255;
+ }
+ }
+ }
+
+ glActiveTexture(GL_TEXTURE2); /* unit 2 */
+ glBindTexture(GL_TEXTURE_2D, 42);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ0, SZ0, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image0);
+ glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, SZ1, SZ1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glActiveTexture(GL_TEXTURE4); /* unit 4 */
+ glBindTexture(GL_TEXTURE_3D, 43);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, SZ0, SZ0, SZ0, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image0);
+ glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, SZ1, SZ1, SZ1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image1);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+}
+
+
+static void
+MakeSphere(void)
+{
+ GLUquadricObj *obj = gluNewQuadric();
+ SphereList = glGenLists(1);
+ gluQuadricTexture(obj, GL_TRUE);
+ glNewList(SphereList, GL_COMPILE);
+ gluSphere(obj, 2.0f, 10, 5);
+ glEndList();
+}
+
+static void
+VertAttrib(GLint index, float x, float y)
+{
+#if 1
+ glVertexAttrib2f_func(index, x, y);
+#else
+ glTexCoord2f(x, y);
+#endif
+}
+
+static void
+MakeRect(void)
+{
+ RectList = glGenLists(1);
+ glNewList(RectList, GL_COMPILE);
+ glNormal3f(0, 0, 1);
+ glBegin(GL_POLYGON);
+ VertAttrib(CoordAttrib, 0, 0); glVertex2f(-2, -2);
+ VertAttrib(CoordAttrib, 1, 0); glVertex2f( 2, -2);
+ VertAttrib(CoordAttrib, 1, 1); glVertex2f( 2, 2);
+ VertAttrib(CoordAttrib, 0, 1); glVertex2f(-2, 2);
+ glEnd(); /* XXX omit this and crash! */
+ glEndList();
+}
+
+
+
+static void
+LoadAndCompileShader(GLuint shader, const char *text)
+{
+ GLint stat;
+
+ glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
+
+ glCompileShader_func(shader);
+
+ glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetShaderInfoLog_func(shader, 1000, &len, log);
+ fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
+ exit(1);
+ }
+}
+
+
+/**
+ * Read a shader from a file.
+ */
+static void
+ReadShader(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, "fslight: Unable to open shader file %s\n", filename);
+ exit(1);
+ }
+
+ n = fread(buffer, 1, max, f);
+ printf("fslight: read %d bytes from shader file %s\n", n, filename);
+ if (n > 0) {
+ buffer[n] = 0;
+ LoadAndCompileShader(shader, buffer);
+ }
+
+ fclose(f);
+ free(buffer);
+}
+
+
+static void
+CheckLink(GLuint prog)
+{
+ GLint stat;
+ glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetProgramInfoLog_func(prog, 1000, &len, log);
+ fprintf(stderr, "Linker error:\n%s\n", log);
+ }
+}
+
+
+static void
Init(void)
{
static const char *fragShaderText =
- "uniform vec3 lightPos;\n"
"uniform vec4 diffuse;\n"
"uniform vec4 specular;\n"
"varying vec3 normal;\n"
"void main() {\n"
" // Compute dot product of light direction and normal vector\n"
- " float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n"
+ " float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
+ " normalize(normal)), 0.0);\n"
" // Compute diffuse and specular contributions\n"
" gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n"
"}\n";
@@ -236,8 +469,6 @@ Init(void)
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" normal = gl_NormalMatrix * gl_Normal;\n"
"}\n";
-
-
const char *version;
version = (const char *) glGetString(GL_VERSION);
@@ -246,43 +477,55 @@ Init(void)
/*exit(1);*/
}
-
- glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader");
- glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader");
- glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram");
- glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource");
- glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource");
- glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader");
- glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram");
- glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader");
- glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram");
- glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram");
- glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation");
- glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram");
- glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader");
- glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv");
- glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv");
+ GetExtensionFuncs();
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- glShaderSource_func(fragShader, 1, &fragShaderText, NULL);
- glCompileShader_func(fragShader);
+ if (FragProgFile)
+ ReadShader(fragShader, FragProgFile);
+ else
+ LoadAndCompileShader(fragShader, fragShaderText);
+
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- glShaderSource_func(vertShader, 1, &vertShaderText, NULL);
- glCompileShader_func(vertShader);
+ if (VertProgFile)
+ ReadShader(vertShader, VertProgFile);
+ else
+ LoadAndCompileShader(vertShader, vertShaderText);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
+ CheckLink(program);
glUseProgram_func(program);
- uLightPos = glGetUniformLocation_func(program, "lightPos");
uDiffuse = glGetUniformLocation_func(program, "diffuse");
uSpecular = glGetUniformLocation_func(program, "specular");
+ uTexture = glGetUniformLocation_func(program, "texture");
+ printf("DiffusePos %d SpecularPos %d TexturePos %d\n",
+ uDiffuse, uSpecular, uTexture);
glUniform4fv_func(uDiffuse, 1, diffuse);
glUniform4fv_func(uSpecular, 1, specular);
+ /* assert(glGetError() == 0);*/
+ glUniform1i_func(uTexture, 2); /* use texture unit 2 */
+ /*assert(glGetError() == 0);*/
+
+ if (CoordAttrib) {
+ int i;
+ glBindAttribLocation_func(program, CoordAttrib, "coord");
+ i = glGetAttribLocation_func(program, "coord");
+ assert(i >= 0);
+ if (i != CoordAttrib) {
+ printf("Hmmm, NVIDIA bug?\n");
+ CoordAttrib = i;
+ }
+ else {
+ printf("Mesa bind attrib: coord = %d\n", i);
+ }
+ }
+
+ /*assert(glGetError() == 0);*/
glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
glEnable(GL_DEPTH_TEST);
@@ -292,11 +535,18 @@ Init(void)
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
+ MakeSphere();
+ MakeRect();
+
+ CurList = SphereList;
+
+ MakeTexture();
+
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
printf("Press p to toggle between per-pixel and per-vertex lighting\n");
/* test glGetShaderSource() */
- {
+ if (0) {
GLsizei len = strlen(fragShaderText) + 1;
GLsizei lenOut;
GLchar *src =(GLchar *) malloc(len * sizeof(GLchar));
@@ -310,6 +560,35 @@ Init(void)
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
+
+ glColor3f(1, 0, 0);
+
+ /* for testing state vars */
+ {
+ static GLfloat fc[4] = { 1, 1, 0, 0 };
+ static GLfloat amb[4] = { 1, 0, 1, 0 };
+ glFogfv(GL_FOG_COLOR, fc);
+ glLightfv(GL_LIGHT1, GL_AMBIENT, amb);
+ }
+
+#if 0
+ TestFunctions();
+#endif
+}
+
+
+static void
+ParseOptions(int argc, char *argv[])
+{
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-fs") == 0) {
+ FragProgFile = argv[i+1];
+ }
+ else if (strcmp(argv[i], "-vs") == 0) {
+ VertProgFile = argv[i+1];
+ }
+ }
}
@@ -318,7 +597,7 @@ main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
- glutInitWindowSize(200, 200);
+ glutInitWindowSize(100, 100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
@@ -327,8 +606,10 @@ main(int argc, char *argv[])
glutDisplayFunc(Redisplay);
if (anim)
glutIdleFunc(Idle);
+ ParseOptions(argc, argv);
Init();
glutMainLoop();
return 0;
}
+