blob: fe5d1564e07dbd00e0b8b260ab86a740eee6776e [file] [log] [blame]
Brian Paulf8304bf2009-04-01 19:53:40 -06001/**
2 * Test linking of multiple compilation units.
3 * Brian Paul
4 * 28 March 2009
5 */
6
7#include <assert.h>
8#include <string.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
Keith Whitwellb799af92009-06-29 14:13:58 +010012#include <GL/glew.h>
Brian Paulf8304bf2009-04-01 19:53:40 -060013#include <GL/gl.h>
14#include <GL/glut.h>
15#include <GL/glext.h>
16#include "extfuncs.h"
17#include "shaderutil.h"
18
19
20static GLfloat diffuse[4] = { 0.5f, 1.0f, 0.5f, 1.0f };
21static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
22static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f };
23static GLfloat delta = 1.0f;
24
25static GLuint VertShader1;
26static GLuint VertShader2;
27static GLuint FragShader1;
28static GLuint FragShader2;
29static GLuint Program;
30
31static GLint uDiffuse;
32static GLint uSpecular;
33static GLint uTexture;
34
35static GLint Win = 0;
36static GLboolean anim = GL_TRUE;
37
38
39
40static const char *FragShaderSource1 =
41 "float compute_dotprod(const vec3 normal) \n"
42 "{ \n"
43 " float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
44 " normalize(normal)), 0.0); \n"
45 " return dotProd; \n"
46 "} \n";
47
48static const char *FragShaderSource2 =
49 "uniform vec4 diffuse;\n"
50 "uniform vec4 specular;\n"
51 "varying vec3 normal;\n"
52 "\n"
53 "// external function \n"
54 "float compute_dotprod(const vec3 normal); \n"
55 "\n"
56 "void main() \n"
57 "{ \n"
58 " float dotProd = compute_dotprod(normal); \n"
59 " gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0); \n"
60 "} \n";
61
62
63static const char *VertShaderSource1 =
64 "vec3 compute_normal() \n"
65 "{ \n"
66 " return gl_NormalMatrix * gl_Normal; \n"
67 "} \n";
68
69static const char *VertShaderSource2 =
70 "varying vec3 normal;\n"
71 "\n"
72 "// external function \n"
73 "vec3 compute_normal(); \n"
74 "\n"
75 "void main() \n"
76 "{ \n"
77 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
78 " normal = compute_normal(); \n"
79 "} \n";
80
81
82static void
83normalize(GLfloat *dst, const GLfloat *src)
84{
85 GLfloat len = sqrt(src[0] * src[0] + src[1] * src[1] + src[2] * src[2]);
86 dst[0] = src[0] / len;
87 dst[1] = src[1] / len;
88 dst[2] = src[2] / len;
89 dst[3] = src[3];
90}
91
92
93static void
94Redisplay(void)
95{
96 GLfloat vec[4];
97
98 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
99
100 /* update light position */
101 normalize(vec, lightPos);
102 glLightfv(GL_LIGHT0, GL_POSITION, vec);
103
104 glutSolidSphere(2.0, 10, 5);
105
106 glutSwapBuffers();
107}
108
109
110static void
111Idle(void)
112{
113 lightPos[0] += delta;
114 if (lightPos[0] > 25.0f || lightPos[0] < -25.0f)
115 delta = -delta;
116 glutPostRedisplay();
117}
118
119
120static void
121Reshape(int width, int height)
122{
123 glViewport(0, 0, width, height);
124 glMatrixMode(GL_PROJECTION);
125 glLoadIdentity();
126 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
127 glMatrixMode(GL_MODELVIEW);
128 glLoadIdentity();
129 glTranslatef(0.0f, 0.0f, -15.0f);
130}
131
132
133static void
134CleanUp(void)
135{
136 glDeleteShader_func(VertShader1);
137 glDeleteShader_func(VertShader2);
138 glDeleteShader_func(FragShader1);
139 glDeleteShader_func(FragShader2);
140 glDeleteProgram_func(Program);
141 glutDestroyWindow(Win);
142}
143
144
145static void
146Key(unsigned char key, int x, int y)
147{
148 (void) x;
149 (void) y;
150
151 switch(key) {
152 case ' ':
153 case 'a':
154 anim = !anim;
155 if (anim)
156 glutIdleFunc(Idle);
157 else
158 glutIdleFunc(NULL);
159 break;
160 case 'x':
161 lightPos[0] -= 1.0f;
162 break;
163 case 'X':
164 lightPos[0] += 1.0f;
165 break;
166 case 27:
167 CleanUp();
168 exit(0);
169 break;
170 }
171 glutPostRedisplay();
172}
173
174
175static void
176CheckLink(GLuint prog)
177{
178 GLint stat;
179 glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
180 if (!stat) {
181 GLchar log[1000];
182 GLsizei len;
183 glGetProgramInfoLog_func(prog, 1000, &len, log);
184 fprintf(stderr, "Linker error:\n%s\n", log);
185 }
186}
187
188
189static void
190Init(void)
191{
192 if (!ShadersSupported())
193 exit(1);
194
195 GetExtensionFuncs();
196
197 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
198
199 VertShader1 = CompileShaderText(GL_VERTEX_SHADER, VertShaderSource1);
200 VertShader2 = CompileShaderText(GL_VERTEX_SHADER, VertShaderSource2);
201 FragShader1 = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderSource1);
202 FragShader2 = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderSource2);
203
204 Program = glCreateProgram_func();
205 glAttachShader_func(Program, VertShader1);
206 glAttachShader_func(Program, VertShader2);
207 glAttachShader_func(Program, FragShader1);
208 glAttachShader_func(Program, FragShader2);
209
210 glLinkProgram_func(Program);
211
212 CheckLink(Program);
213
214 glUseProgram_func(Program);
215
216 uDiffuse = glGetUniformLocation_func(Program, "diffuse");
217 uSpecular = glGetUniformLocation_func(Program, "specular");
218 uTexture = glGetUniformLocation_func(Program, "texture");
219 printf("DiffusePos %d SpecularPos %d TexturePos %d\n",
220 uDiffuse, uSpecular, uTexture);
221
222 glUniform4fv_func(uDiffuse, 1, diffuse);
223 glUniform4fv_func(uSpecular, 1, specular);
224
225 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
226 glEnable(GL_DEPTH_TEST);
227
228 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
229 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
230 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10.0f);
231
232 assert(glIsProgram_func(Program));
233 assert(glIsShader_func(VertShader1));
234 assert(glIsShader_func(VertShader2));
235 assert(glIsShader_func(FragShader1));
236 assert(glIsShader_func(FragShader2));
237
238 glColor3f(1, 0, 0);
239}
240
241
242int
243main(int argc, char *argv[])
244{
245 glutInit(&argc, argv);
Brian Paul189db322009-04-16 10:28:27 -0600246 glutInitWindowSize(300, 300);
Brian Paulf8304bf2009-04-01 19:53:40 -0600247 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
248 Win = glutCreateWindow(argv[0]);
Keith Whitwellb799af92009-06-29 14:13:58 +0100249 glewInit();
Brian Paulf8304bf2009-04-01 19:53:40 -0600250 glutReshapeFunc(Reshape);
251 glutKeyboardFunc(Key);
252 glutDisplayFunc(Redisplay);
253 if (anim)
254 glutIdleFunc(Idle);
255 Init();
256 glutMainLoop();
257 return 0;
258}
259
260