Use VBOs in new example. Added a few comments.
[freeglut] / progs / demos / smooth_opengl3 / smooth_opengl3.c
1 /*
2  * smooth_opengl3.c, based on smooth.c, which is (c) by SGI, see below.
3  * This program demonstrates smooth shading in a way which is fully
4  * OpenGL-3.0-compliant.
5  * A smooth shaded polygon is drawn in a 2-D projection.
6  */
7
8 /*
9  * Original copyright notice from smooth.c:
10  *
11  * License Applicability. Except to the extent portions of this file are
12  * made subject to an alternative license as permitted in the SGI Free
13  * Software License B, Version 1.1 (the "License"), the contents of this
14  * file are subject only to the provisions of the License. You may not use
15  * this file except in compliance with the License. You may obtain a copy
16  * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
17  * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
18  * 
19  * http://oss.sgi.com/projects/FreeB
20  * 
21  * Note that, as provided in the License, the Software is distributed on an
22  * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
23  * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
24  * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
25  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
26  * 
27  * Original Code. The Original Code is: OpenGL Sample Implementation,
28  * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
29  * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
30  * Copyright in any portions created by third parties is as indicated
31  * elsewhere herein. All Rights Reserved.
32  * 
33  * Additional Notice Provisions: The application programming interfaces
34  * established by SGI in conjunction with the Original Code are The
35  * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
36  * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
37  * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
38  * Window System(R) (Version 1.3), released October 19, 1998. This software
39  * was created using the OpenGL(R) version 1.2.1 Sample Implementation
40  * published by SGI, but has not been independently verified as being
41  * compliant with the OpenGL(R) version 1.2.1 Specification.
42  *
43  */
44
45 #include <GL/freeglut.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48
49 /* report GL errors, if any, to stderr */
50 void reportErrors(const char *message)
51 {
52    GLenum error;
53    while (( error = glGetError() ) != GL_NO_ERROR) {
54       fprintf (stderr, "GL error 0x%X %s\n", error, message);
55    }
56 }
57
58 /* extension entries */
59 void (*gl_GenBuffers) (GLsizei n, GLuint *buffers);
60 void (*gl_BindBuffer) (GLenum target, GLuint buffer);
61 void (*gl_BufferData) (GLenum target, GLsizeiptr size, const GLvoid *data,
62                        GLenum usage);
63
64 void initExtensionEntries(void) 
65 {
66    gl_GenBuffers = glutGetProcAddress ("glGenBuffers");
67    gl_BindBuffer = glutGetProcAddress ("glBindBuffer");
68    gl_BufferData = glutGetProcAddress ("glBufferData");
69 }
70
71 /* vertex array data for a colored 2D triangle, consisting of RGB color values
72    and XY coordinates */
73 const GLsizei numColorComponents = 3;
74 const GLsizei numVertexComponents = 2;
75
76 const GLfloat varray[] = {
77    1.0f, 0.0f, 0.0f,
78    5.0f, 5.0f,
79
80    0.0f, 1.0f, 0.0f,
81    25.0f, 5.0f,
82
83    0.0f, 0.0f, 1.0f,
84    5.0f, 25.0f
85 };
86
87 /* the name of the vertex buffer object */
88 GLuint bufferName;
89
90 void initBuffer(void)
91 {
92    reportErrors ("at start of initBuffer");
93    gl_GenBuffers (1, &bufferName);
94    gl_BindBuffer (GL_ARRAY_BUFFER, bufferName);
95    gl_BufferData (GL_ARRAY_BUFFER, sizeof(varray), varray, GL_STATIC_DRAW);
96    reportErrors ("at end of initBuffer");
97 }
98
99 void initRendering(void)
100 {
101    reportErrors ("at start of initRendering");
102    glClearColor (0.0, 0.0, 0.0, 0.0);
103    glShadeModel (GL_SMOOTH);
104    reportErrors ("at end of initRendering");
105 }
106
107 void init(void) 
108 {
109    initExtensionEntries();
110    initBuffer();
111    initRendering();
112 }
113
114 void triangle(void)
115 {
116    const char *base = NULL;
117    const GLsizei stride = sizeof(GLfloat) * (numColorComponents + numVertexComponents);
118    const GLsizei numElements = sizeof(varray) / stride;
119    reportErrors ("at start of triangle");
120    gl_BindBuffer (GL_ARRAY_BUFFER, bufferName);
121    glColorPointer (numColorComponents, GL_FLOAT, stride, base);
122    glVertexPointer(numVertexComponents, GL_FLOAT, stride,
123                    base + sizeof(GLfloat) * numColorComponents);
124    glEnableClientState (GL_COLOR_ARRAY);
125    glEnableClientState (GL_VERTEX_ARRAY);
126    glDrawArrays(GL_TRIANGLES, 0, numElements);
127    reportErrors ("at end of triangle");
128 }
129
130 void display(void)
131 {
132    reportErrors ("at start of display");
133    glClear (GL_COLOR_BUFFER_BIT);
134    triangle ();
135    glFlush ();
136    reportErrors ("at end of display");
137 }
138
139 void loadOrthof(GLfloat *m, GLfloat l, GLfloat r, GLfloat b, GLfloat t,
140                 GLfloat n, GLfloat f)
141 {
142    m[ 0] = 2.0f / (r - l);
143    m[ 1] = 0.0f;
144    m[ 2] = 0.0f;
145    m[ 3] = 0.0f;
146
147    m[ 4] = 0.0f;
148    m[ 5] = 2.0f / (t - b);
149    m[ 6] = 0.0f;
150    m[ 7] = 0.0f;
151
152    m[ 8] = 0.0f;
153    m[ 9] = 0.0f;
154    m[10] = -2.0f / (f - n);
155    m[11] = 0.0f;
156
157    m[12] = -(r + l) / (r - l);
158    m[13] = -(t + b) / (t - b);
159    m[14] = -(f + n) / (f - n);
160    m[15] = 1.0f;
161 }
162
163 void loadOrtho2Df(GLfloat *m, GLfloat l, GLfloat r, GLfloat b, GLfloat t)
164 {
165    loadOrthof (m, l, r, b, t, -1.0f, 1.0f);
166 }
167
168 void reshape (int w, int h)
169 {
170    GLfloat m[16];
171    reportErrors ("at start of reshape");
172    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
173    glMatrixMode (GL_PROJECTION);
174    if (w <= h) {
175       loadOrtho2Df (m, 0.0, 30.0, 0.0, 30.0 * (GLfloat) h/(GLfloat) w);
176    } else {
177       loadOrtho2Df (m, 0.0, 30.0 * (GLfloat) w/(GLfloat) h, 0.0, 30.0);
178    }
179    glLoadMatrixf (m);
180    glMatrixMode (GL_MODELVIEW);
181    reportErrors ("at end of reshape");
182 }
183
184 void keyboard(unsigned char key, int x, int y)
185 {
186    switch (key) {
187       case 27:
188          exit(0);
189          break;
190    }
191 }
192
193 int main(int argc, char** argv)
194 {
195    glutInit(&argc, argv);
196    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
197    glutInitContextVersion(3, 0);
198    /* glutInitContextFlags(GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG); */
199    glutInitWindowSize (500, 500); 
200    glutInitWindowPosition (100, 100);
201    glutCreateWindow (argv[0]);
202    init ();
203    glutDisplayFunc(display); 
204    glutReshapeFunc(reshape);
205    glutKeyboardFunc (keyboard);
206    glutMainLoop();
207    return 0;
208 }