2 * GL_ARB_shading_language_100 test application.
4 * Tests correctness of emited code. Runs multiple well-formed shaders and checks if
5 * they produce valid results.
7 * Requires specific support on the GL implementation side. A special function printMESA()
8 * must be supported in the language that prints current values of generic type
9 * to the appropriate shader's info log, and optionally to the screen.
14 #include "framework.h"
16 #define EPSILON 0.0001f
18 static GLhandleARB vert
= 0;
19 static GLhandleARB prog
= 0;
21 static int get_line (FILE *f
, char *line
, int size
)
23 if (fgets (line
, size
, f
) == NULL
)
25 if (line
[strlen (line
) - 1] == '\n')
26 line
[strlen (line
) - 1] = '\0';
39 struct ATTRIB attrib
[32];
50 enum SHADER_LOAD_STATE
61 struct ATTRIBS attribs
;
65 enum PROGRAM_LOAD_STATE
72 static struct PROGRAM
*program
= NULL
;
74 static void load_test_file (const char *filename
, struct PROGRAM
**program
)
76 struct PROGRAM
**currprog
= program
;
79 enum PROGRAM_LOAD_STATE pls
= PLS_NONE
;
80 enum SHADER_LOAD_STATE sls
= SLS_NONE
;
82 f
= fopen (filename
, "r");
86 while (get_line (f
, line
, sizeof (line
))) {
88 if (strncmp (line
+ 1, "program", 7) == 0) {
89 if (*currprog
!= NULL
)
90 currprog
= &(**currprog
).next
;
91 *currprog
= (struct PROGRAM
*) (malloc (sizeof (struct PROGRAM
)));
92 if (*currprog
== NULL
)
94 (**currprog
).next
= NULL
;
95 strcpy ((**currprog
).name
, line
+ 9);
96 (**currprog
).attribs
.count
= 0;
97 (**currprog
).vertex
.code
[0] = '\0';
98 (**currprog
).vertex
.count
= 0;
101 else if (strncmp (line
+ 1, "attrib", 6) == 0) {
102 if (*currprog
== NULL
)
104 strcpy ((**currprog
).attribs
.attrib
[(**currprog
).attribs
.count
].name
, line
+ 8);
105 (**currprog
).attribs
.attrib
[(**currprog
).attribs
.count
].count
= 0;
106 (**currprog
).attribs
.count
++;
109 else if (strcmp (line
+ 1, "vertex") == 0) {
110 if (*currprog
== NULL
)
115 else if (strcmp (line
+ 1, "code") == 0) {
116 if (*currprog
== NULL
|| pls
!= PLS_VERTEX
)
120 else if (strcmp (line
+ 1, "output") == 0) {
121 if (*currprog
== NULL
|| pls
!= PLS_VERTEX
)
127 if ((*currprog
== NULL
|| pls
== PLS_NONE
|| sls
== SLS_NONE
) && line
[0] != '\0')
129 if (*currprog
!= NULL
&& pls
== PLS_VERTEX
) {
130 if (sls
== SLS_CODE
) {
131 strcat ((**currprog
).vertex
.code
, line
);
132 strcat ((**currprog
).vertex
.code
, "\n");
134 else if (sls
== SLS_OUTPUT
&& line
[0] != '\0') {
135 if (strcmp (line
, "true") == 0)
136 (**currprog
).vertex
.output
[(**currprog
).vertex
.count
] = 1.0f
;
137 else if (strcmp (line
, "false") == 0)
138 (**currprog
).vertex
.output
[(**currprog
).vertex
.count
] = 0.0f
;
140 sscanf (line
, "%f", &(**currprog
).vertex
.output
[(**currprog
).vertex
.count
]);
141 (**currprog
).vertex
.count
++;
144 else if (*currprog
!= NULL
&& pls
== PLS_ATTRIB
&& line
[0] != '\0') {
145 struct ATTRIB
*att
= &(**currprog
).attribs
.attrib
[(**currprog
).attribs
.count
- 1];
146 GLfloat
*vec
= att
->value
[att
->count
];
147 sscanf (line
, "%f %f %f %f", &vec
[0], &vec
[1], &vec
[2], &vec
[3]);
156 void InitScene (void)
158 prog
= glCreateProgramObjectARB ();
159 vert
= glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB
);
160 glAttachObjectARB (prog
, vert
);
161 glDeleteObjectARB (vert
);
162 load_test_file ("cltest.txt", &program
);
165 void RenderScene (void)
167 struct PROGRAM
*nextprogram
;
169 GLint info_length
, length
;
170 char output
[65000], *p
;
176 code
= program
->vertex
.code
;
177 glShaderSourceARB (vert
, 1, (const GLcharARB
**) (&code
), NULL
);
178 glCompileShaderARB (vert
);
179 CheckObjectStatus (vert
);
181 for (i
= 0; i
< program
->attribs
.count
; i
++) {
182 const char *name
= program
->attribs
.attrib
[i
].name
;
183 if (strcmp (name
, "gl_Vertex") != 0)
184 glBindAttribLocationARB (prog
, i
, name
);
187 glLinkProgramARB (prog
);
188 CheckObjectStatus (prog
);
189 glUseProgramObjectARB (prog
);
191 printf ("\n--- %s\n", program
->name
);
193 glGetObjectParameterivARB (vert
, GL_OBJECT_INFO_LOG_LENGTH_ARB
, &info_length
);
196 if (program
->attribs
.count
== 0) {
197 glVertex2f (0.0f
, 0.0f
);
200 for (i
= 0; i
< program
->attribs
.attrib
[0].count
; i
++) {
202 for (j
= 0; j
< program
->attribs
.count
; j
++) {
203 GLuint n
= (j
+ 1) % program
->attribs
.count
;
204 GLfloat
*vec
= program
->attribs
.attrib
[n
].value
[i
];
205 const char *name
= program
->attribs
.attrib
[n
].name
;
206 if (strcmp (name
, "gl_Vertex") == 0)
209 glVertexAttrib4fvARB (n
, vec
);
216 glGetInfoLogARB (vert
, sizeof (output
), &length
, output
);
217 p
= output
+ info_length
- 1;
218 for (i
= 0; i
< program
->vertex
.count
; i
++) {
221 printf ("*** %s\n", "I/O error");
224 if (strncmp (p
, "true", 4) == 0)
226 else if (strncmp (p
, "false", 5) == 0)
228 else if (sscanf (p
, "%f", &value
) != 1) {
229 printf ("*** %s\n", "I/O error");
232 if (fabs (value
- program
->vertex
.output
[i
]) > EPSILON
) {
233 printf ("*** Values are different, is %f, should be %f\n", value
,
234 program
->vertex
.output
[i
]);
236 p
= strchr (p
, '\n');
241 printf ("*** %s\n", "I/O error");
243 nextprogram
= program
->next
;
245 program
= nextprogram
;
248 int main (int argc
, char *argv
[])
250 InitFramework (&argc
, argv
);