tutorial: teapot.c

File teapot.c, 4.7 KB (added by leon, 6 years ago)

Extended teapot example

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <GL/glew.h>
6#include <GL/glut.h>
7#include "trackball.h"
8
9GLuint program;
10
11static const GLchar * vertex_shader[] ={"\
12varying vec3 normal, lightDir;\
13uniform mat4 RotationMatrix;  \
14uniform float Zoom;\
15void main()\
16{          \
17  lightDir=normalize(vec3(gl_LightSource[0].position)); \
18  vec4 n = RotationMatrix*vec4(gl_NormalMatrix*gl_Normal, 1);\
19  normal=normalize(n.xyz);         \
20  gl_Position = gl_ProjectionMatrix * RotationMatrix \
21   * gl_ModelViewMatrix*vec4(Zoom*gl_Vertex.xyz, 1.0); \
22}"};
23
24static const GLchar * fragment_shader[] ={"\
25/* simple toon fragment shader */\
26/* www.lighthouse3d.com        */\
27\
28varying vec3 normal, lightDir;\
29\
30void main()\
31{\
32        float intensity;\
33        vec3 n;\
34        vec4 color;\
35\
36        n = normalize(normal);\
37        intensity = max(dot(lightDir,n),0.0);\
38        if (intensity > 0.98)\
39                color = vec4(0.8,0.8,0.8,1.0);\
40        else if (intensity > 0.5)\
41                color = vec4(0.4,0.4,0.8,1.0);\
42        else if (intensity > 0.25)\
43                color = vec4(0.2,0.2,0.4,1.0);\
44        else\
45                color = vec4(0.1,0.1,0.1,1.0);\
46        gl_FragColor = color;\
47}"};
48
49void create_shaders()
50{
51  GLuint v, f;
52
53  v = glCreateShader(GL_VERTEX_SHADER);
54  f = glCreateShader(GL_FRAGMENT_SHADER);
55  glShaderSource(v, 1, vertex_shader, NULL);
56  glShaderSource(f, 1, fragment_shader, NULL);
57  glCompileShader(v);
58  GLint compiled;
59  glGetShaderiv(v, GL_COMPILE_STATUS, &compiled );
60  if ( !compiled ) {
61    GLsizei  maxLength, length;
62    glGetShaderiv( v, GL_INFO_LOG_LENGTH, &maxLength );
63    GLchar* log = malloc(sizeof(GLchar)*(maxLength+1));
64    glGetShaderInfoLog(v,  maxLength, &length, log);
65    printf("Vertex Shader compilation failed: %s\n", log);
66    free(log);
67  }
68  glCompileShader(f);
69  glGetShaderiv(f, GL_COMPILE_STATUS, &compiled );
70  if ( !compiled ) {
71    GLsizei  maxLength, length;
72    glGetShaderiv( f, GL_INFO_LOG_LENGTH, &maxLength );
73    GLchar* log = malloc(sizeof(GLchar)*(maxLength+1));
74    glGetShaderInfoLog(f,  maxLength, &length, log);
75    printf("Fragment Shader compilation failed: %s\n", log);
76    free(log);
77  }
78  program = glCreateProgram();
79  glAttachShader(program, f);
80  glAttachShader(program, v);
81  glLinkProgram(program);
82  GLint linked;
83  glGetProgramiv(program, GL_LINK_STATUS, &linked );
84  if ( !linked ) {
85    GLsizei len;
86    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len );
87    GLchar* log = malloc(sizeof(GLchar)*(len+1));
88    glGetProgramInfoLog(program, len, &len, log );
89    printf("Shader linking failed: %s\n", log);
90    free(log);
91  }
92  glUseProgram(program);
93}
94
95
96float lpos[4] = {1, 0.5, 1, 0};
97GLfloat m[4][4]; // modelview rotation matrix
98float last[4], cur[4]; // rotation tracking quaternions
99int width, height, beginx, beginy;
100float p1x, p1y, p2x, p2y;
101float zoom = 1.0;
102
103void display(void)
104{
105  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
106  glLightfv(GL_LIGHT0, GL_POSITION, lpos);
107  GLuint location = glGetUniformLocation(program, "RotationMatrix");
108  build_rotmatrix(m, cur); 
109  if( location >= 0 )
110    glUniformMatrix4fv(location, 1, GL_FALSE, &m[0][0]);
111  location = glGetUniformLocation(program, "Zoom");
112  if (location >= 0) glUniform1f(location, zoom);
113  glutSolidTeapot(0.6);
114  glutSwapBuffers();
115}
116
117void reshape (int w, int h)
118{
119  double l = 1;
120  width=w;  height=h;
121  glViewport (0, 0, w, h);
122  glMatrixMode (GL_PROJECTION);
123  glLoadIdentity();
124  glOrtho(-l, l, -l, l, -l, l);
125  glMatrixMode(GL_MODELVIEW);
126  glLoadIdentity();
127}
128
129void keys(unsigned char key, int x, int y)
130{
131   if (key == 27 || key == 'q') 
132         exit(0);
133}
134
135void mouse(int button,int state, int x, int y)   
136{
137  beginx = x;
138  beginy = y;
139  if (button == 3 && state == GLUT_DOWN)
140    { zoom *= 1.1; glutPostRedisplay(); }
141  else if (button == 4 && state == GLUT_DOWN)
142    { zoom /= 1.1; glutPostRedisplay(); }
143}
144
145void motion(int x,int y)   
146{
147  p1x = (2.0*beginx - width)/width;
148  p1y = (height - 2.0*beginy)/height;
149  p2x = (2.0 * x - width) / width;
150  p2y = (height - 2.0 * y) / height;
151  trackball(last, p1x, p1y, p2x, p2y);   
152  add_quats(last, cur, cur);   
153  beginx = x;
154  beginy = y;
155  glutPostRedisplay();   
156}
157
158int main(int argc, char **argv)
159{
160  glutInit(&argc, argv);
161  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
162  glutInitWindowSize(512, 512);
163  glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH)-512)/2,
164                         (glutGet(GLUT_SCREEN_HEIGHT)-512)/2);
165  glutCreateWindow("Use mouse to rotate");
166 
167  trackball(cur, 0.0, 0.0, 0.0, 0.0);
168
169  glutDisplayFunc(display);
170  glutReshapeFunc(reshape);
171  glutMouseFunc(mouse);
172  glutMotionFunc(motion);
173  glutKeyboardFunc(keys);
174
175  glEnable(GL_DEPTH_TEST);
176  glClearColor(1.0,1.0,1.0,1.0);
177  glewInit();
178  if (!glewIsSupported("GL_VERSION_2_0"))
179   {
180     printf("GLSL not supported\n");
181     exit(EXIT_FAILURE);
182   }
183  create_shaders();
184  glutMainLoop();
185  return EXIT_SUCCESS;
186}