123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /*
- * GL_ARB_shading_language_100 test application.
- *
- * Tests correctness of emited code. Runs multiple well-formed shaders and checks if
- * they produce valid results.
- *
- * Requires specific support on the GL implementation side. A special function printMESA()
- * must be supported in the language that prints current values of generic type
- * to the appropriate shader's info log, and optionally to the screen.
- *
- * Author: Michal Krol
- */
-
- #include "framework.h"
-
- #define EPSILON 0.0001f
-
- static GLhandleARB vert = 0;
- static GLhandleARB prog = 0;
-
- static int get_line (FILE *f, char *line, int size)
- {
- if (fgets (line, size, f) == NULL)
- return 0;
- if (line[strlen (line) - 1] == '\n')
- line[strlen (line) - 1] = '\0';
- return 1;
- }
-
- struct ATTRIB
- {
- char name[32];
- GLfloat value[64][4];
- GLuint count;
- };
-
- struct ATTRIBS
- {
- struct ATTRIB attrib[32];
- GLuint count;
- };
-
- struct SHADER
- {
- char code[16000];
- GLfloat output[1000];
- GLuint count;
- };
-
- enum SHADER_LOAD_STATE
- {
- SLS_NONE,
- SLS_CODE,
- SLS_OUTPUT
- };
-
- struct PROGRAM
- {
- struct PROGRAM *next;
- char name[256];
- struct ATTRIBS attribs;
- struct SHADER vertex;
- };
-
- enum PROGRAM_LOAD_STATE
- {
- PLS_NONE,
- PLS_ATTRIB,
- PLS_VERTEX
- };
-
- static struct PROGRAM *program = NULL;
-
- static void load_test_file (const char *filename, struct PROGRAM **program)
- {
- struct PROGRAM **currprog = program;
- FILE *f;
- char line[256];
- enum PROGRAM_LOAD_STATE pls = PLS_NONE;
- enum SHADER_LOAD_STATE sls = SLS_NONE;
-
- f = fopen (filename, "r");
- if (f == NULL)
- return;
-
- while (get_line (f, line, sizeof (line))) {
- if (line[0] == '$') {
- if (strncmp (line + 1, "program", 7) == 0) {
- if (*currprog != NULL)
- currprog = &(**currprog).next;
- *currprog = (struct PROGRAM *) (malloc (sizeof (struct PROGRAM)));
- if (*currprog == NULL)
- break;
- (**currprog).next = NULL;
- strcpy ((**currprog).name, line + 9);
- (**currprog).attribs.count = 0;
- (**currprog).vertex.code[0] = '\0';
- (**currprog).vertex.count = 0;
- pls = PLS_NONE;
- }
- else if (strncmp (line + 1, "attrib", 6) == 0) {
- if (*currprog == NULL)
- break;
- strcpy ((**currprog).attribs.attrib[(**currprog).attribs.count].name, line + 8);
- (**currprog).attribs.attrib[(**currprog).attribs.count].count = 0;
- (**currprog).attribs.count++;
- pls = PLS_ATTRIB;
- }
- else if (strcmp (line + 1, "vertex") == 0) {
- if (*currprog == NULL)
- break;
- pls = PLS_VERTEX;
- sls = SLS_NONE;
- }
- else if (strcmp (line + 1, "code") == 0) {
- if (*currprog == NULL || pls != PLS_VERTEX)
- break;
- sls = SLS_CODE;
- }
- else if (strcmp (line + 1, "output") == 0) {
- if (*currprog == NULL || pls != PLS_VERTEX)
- break;
- sls = SLS_OUTPUT;
- }
- }
- else {
- if ((*currprog == NULL || pls == PLS_NONE || sls == SLS_NONE) && line[0] != '\0')
- break;
- if (*currprog != NULL && pls == PLS_VERTEX) {
- if (sls == SLS_CODE) {
- strcat ((**currprog).vertex.code, line);
- strcat ((**currprog).vertex.code, "\n");
- }
- else if (sls == SLS_OUTPUT && line[0] != '\0') {
- if (strcmp (line, "true") == 0)
- (**currprog).vertex.output[(**currprog).vertex.count] = 1.0f;
- else if (strcmp (line, "false") == 0)
- (**currprog).vertex.output[(**currprog).vertex.count] = 0.0f;
- else
- sscanf (line, "%f", &(**currprog).vertex.output[(**currprog).vertex.count]);
- (**currprog).vertex.count++;
- }
- }
- else if (*currprog != NULL && pls == PLS_ATTRIB && line[0] != '\0') {
- struct ATTRIB *att = &(**currprog).attribs.attrib[(**currprog).attribs.count - 1];
- GLfloat *vec = att->value[att->count];
- sscanf (line, "%f %f %f %f", &vec[0], &vec[1], &vec[2], &vec[3]);
- att->count++;
- }
- }
- }
-
- fclose (f);
- }
-
- void InitScene (void)
- {
- prog = glCreateProgramObjectARB ();
- vert = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
- glAttachObjectARB (prog, vert);
- glDeleteObjectARB (vert);
- load_test_file ("cltest.txt", &program);
- }
-
- void RenderScene (void)
- {
- struct PROGRAM *nextprogram;
- char *code;
- GLint info_length, length;
- char output[65000], *p;
- GLuint i;
-
- if (program == NULL)
- exit (0);
-
- code = program->vertex.code;
- glShaderSourceARB (vert, 1, (const GLcharARB **) (&code), NULL);
- glCompileShaderARB (vert);
- CheckObjectStatus (vert);
-
- for (i = 0; i < program->attribs.count; i++) {
- const char *name = program->attribs.attrib[i].name;
- if (strcmp (name, "gl_Vertex") != 0)
- glBindAttribLocationARB (prog, i, name);
- }
-
- glLinkProgramARB (prog);
- CheckObjectStatus (prog);
- glUseProgramObjectARB (prog);
-
- printf ("\n--- %s\n", program->name);
-
- glGetObjectParameterivARB (vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_length);
-
- glBegin (GL_POINTS);
- if (program->attribs.count == 0) {
- glVertex2f (0.0f, 0.0f);
- }
- else {
- for (i = 0; i < program->attribs.attrib[0].count; i++) {
- GLuint j;
- for (j = 0; j < program->attribs.count; j++) {
- GLuint n = (j + 1) % program->attribs.count;
- GLfloat *vec = program->attribs.attrib[n].value[i];
- const char *name = program->attribs.attrib[n].name;
- if (strcmp (name, "gl_Vertex") == 0)
- glVertex4fv (vec);
- else
- glVertexAttrib4fvARB (n, vec);
- }
- }
- }
- glEnd ();
- glFlush ();
-
- glGetInfoLogARB (vert, sizeof (output), &length, output);
- p = output + info_length - 1;
- for (i = 0; i < program->vertex.count; i++) {
- GLfloat value;
- if (p == NULL) {
- printf ("*** %s\n", "I/O error");
- break;
- }
- if (strncmp (p, "true", 4) == 0)
- value = 1.0f;
- else if (strncmp (p, "false", 5) == 0)
- value = 0.0f;
- else if (sscanf (p, "%f", &value) != 1) {
- printf ("*** %s\n", "I/O error");
- break;
- }
- if (fabs (value - program->vertex.output[i]) > EPSILON) {
- printf ("*** Values are different, is %f, should be %f\n", value,
- program->vertex.output[i]);
- }
- p = strchr (p, '\n');
- if (p != NULL)
- p++;
- }
- if (p && *p != '\0')
- printf ("*** %s\n", "I/O error");
-
- nextprogram = program->next;
- free (program);
- program = nextprogram;
- }
-
- int main (int argc, char *argv[])
- {
- InitFramework (&argc, argv);
- return 0;
- }
|