tutorial: temperature.c

File temperature.c, 5.2 KB (added by leon, 6 years ago)

Exercise 2.2

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <GL/glew.h>
4#include <GL/glut.h>
5
6GLuint program;
7GLuint vbo_vertices;
8GLUINT vbo_temperature;
9GLint attribute_coord2d;
10GLint attribute_temperature;
11
12static const GLchar * vertex_shader[] = {
13  "attribute vec2 coord2d;" // input vertex position
14  "attribute float temperature;" // custom variable along with vertex position
15  "varying float  t;" // communicate between the vertex and the fragment shader
16  "void main()"
17  "{"
18  "  t = temperature;"
19  "  gl_Position = gl_ModelViewProjectionMatrix*vec4(coord2d, 0.0, 1.0);"
20  "}"
21};
22static const GLchar * fragment_shader[] = {
23  "vec3 Cool = vec3(0, 0, 1);" // Red
24  "vec3 Hot  = vec3(1, 0, 0);" // Blue
25  "varying float t;" // Interpolated by fragment
26  "void main()"
27  "{"
28  "  vec3 color = mix(Cool, Hot, t);"  // use the built-in mix() function
29  "  gl_FragColor = vec4(color, 1.0);" // append alpha channel
30  "}"
31};
32
33void active_vertex_shader_inputs(GLuint prog)
34{
35  char *name;
36  GLint active_attribs, max_length;
37  unsigned i;
38
39  glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &active_attribs);
40  glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_length);
41
42  name = malloc(max_length + 1);
43  printf("Active vertex shader inputs:\n");
44  for (i = 0; i < active_attribs; i++) {
45    GLint size;
46    GLenum type;
47   
48    glGetActiveAttrib(prog, i, max_length + 1, NULL,
49                      &size, &type, name);
50    printf("Vertex input attribute %s of type %d is at location %d\n", 
51           name, type, glGetAttribLocation(prog, name));
52  }
53  free(name);
54}
55
56void create_shaders()
57{
58  GLuint v, f;
59
60  v = glCreateShader(GL_VERTEX_SHADER);
61  f = glCreateShader(GL_FRAGMENT_SHADER);
62  glShaderSource(v, 1, vertex_shader, NULL);
63  glShaderSource(f, 1, fragment_shader, NULL);
64  glCompileShader(v);
65  GLint compiled;
66  glGetShaderiv(v, GL_COMPILE_STATUS, &compiled );
67  if ( !compiled ) {
68    GLsizei  maxLength, length;
69    glGetShaderiv( v, GL_INFO_LOG_LENGTH, &maxLength );
70    GLchar* log = malloc(sizeof(GLchar)*(maxLength+1));
71    glGetShaderInfoLog(v,  maxLength, &length, log);
72    printf("Vertex Shader compilation failed: %s\n", log);
73    free(log);
74  }
75  glCompileShader(f);
76  glGetShaderiv(f, GL_COMPILE_STATUS, &compiled );
77  if ( !compiled ) {
78    GLsizei  maxLength, length;
79    glGetShaderiv( f, GL_INFO_LOG_LENGTH, &maxLength );
80    GLchar* log = malloc(sizeof(GLchar)*(maxLength+1));
81    glGetShaderInfoLog(f,  maxLength, &length, log);
82    printf("Fragment Shader compilation failed: %s\n", log);
83    free(log);
84  }
85  program = glCreateProgram();
86  glAttachShader(program, f);
87  glAttachShader(program, v);
88  glLinkProgram(program);
89  GLint linked;
90  glGetProgramiv(program, GL_LINK_STATUS, &linked );
91  if ( !linked ) {
92    GLsizei len;
93    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len );
94    GLchar* log = malloc(sizeof(GLchar)*(len+1));
95    glGetProgramInfoLog(program, len, &len, log );
96    printf("Shader linking failed: %s\n", log);
97    free(log);
98  }
99  glUseProgram(program);
100
101
102  attribute_coord2d = glGetAttribLocation(program, "coord2d");
103  if (attribute_coord2d == -1) {
104    fprintf(stderr, "Could not bind attribute coord2d\n");
105  }
106  glEnableVertexAttribArray(attribute_coord2d);
107
108  attribute_temperature = glGetAttribLocation(program, "temperature");
109  if (attribute_temperature == -1) {
110    fprintf(stderr, "Could not bind attribute temperature\n");
111  }
112  glEnableVertexAttribArray(attribute_temperature); // toggle this
113  active_vertex_shader_inputs(program);
114 
115}
116
117void send_buffers_to_GPU(void)
118{
119  GLuint vertex_array_object;
120  glGenVertexArrays(1, &vertex_array_object);
121  glBindVertexArray(vertex_array_object);
122 
123  GLfloat vertices[][2] = {
124    { -0.90, -0.90 }, // Triangle 1
125    {  0.85, -0.90 },
126    { -0.90,  0.85 },
127    {  0.90, -0.85 }, // Triangle 2
128    {  0.90,  0.90 },
129    { -0.85,  0.90 }
130  };
131
132  glGenBuffers(1, &vbo_vertices);
133  glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
134  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
135
136  GLfloat vertex_temperature[] = {0, 1, 0.2, 0.1, 0.5, 0.9};
137  glGenBuffers(1, &vbo_temperature);
138  glBindBuffer(GL_ARRAY_BUFFER, vbo_temperature);
139  glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_temperature),
140             vertex_temperature, GL_STATIC_DRAW);
141}
142
143
144void display(void)
145{
146  glClear(GL_COLOR_BUFFER_BIT);
147 
148  glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
149  glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, NULL);
150
151  glBindBuffer(GL_ARRAY_BUFFER, vbo_temperature);
152  glVertexAttribPointer(attribute_temperature, 1, GL_FLOAT, GL_FALSE, 0, NULL);
153                         
154  glDrawArrays(GL_TRIANGLES, 0, 6); // Draw 6 vertices
155  glutSwapBuffers();
156}
157
158int main(int argc, char **argv)
159{
160  glutInit(&argc, argv);
161  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
162  glutCreateWindow("GLSL Intro");
163  glutDisplayFunc(display);
164  glewInit();
165  if (!glewIsSupported("GL_VERSION_2_0"))
166   {
167     printf("GLSL not supported\n");
168     exit(EXIT_FAILURE);
169   }
170  glClearColor(0.9,1.0,1.0,1.0);
171  send_buffers_to_GPU();
172  create_shaders();
173
174  glutMainLoop();
175  return EXIT_SUCCESS;
176}