| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- /*
- * smooth_opengl3.c, based on smooth.c, which is (c) by SGI, see below.
- * This program demonstrates smooth shading in a way which is fully
- * OpenGL-3.1-compliant.
- * A smooth shaded polygon is drawn in a 2-D projection.
- */
- /*
- * Original copyright notice from smooth.c:
- *
- * License Applicability. Except to the extent portions of this file are
- * made subject to an alternative license as permitted in the SGI Free
- * Software License B, Version 1.1 (the "License"), the contents of this
- * file are subject only to the provisions of the License. You may not use
- * this file except in compliance with the License. You may obtain a copy
- * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
- * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
- *
- * http://oss.sgi.com/projects/FreeB
- *
- * Note that, as provided in the License, the Software is distributed on an
- * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
- * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
- * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
- *
- * Original Code. The Original Code is: OpenGL Sample Implementation,
- * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
- * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
- * Copyright in any portions created by third parties is as indicated
- * elsewhere herein. All Rights Reserved.
- *
- * Additional Notice Provisions: The application programming interfaces
- * established by SGI in conjunction with the Original Code are The
- * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
- * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
- * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
- * Window System(R) (Version 1.3), released October 19, 1998. This software
- * was created using the OpenGL(R) version 1.2.1 Sample Implementation
- * published by SGI, but has not been independently verified as being
- * compliant with the OpenGL(R) version 1.2.1 Specification.
- *
- */
- #include <GL/freeglut.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <stddef.h>
- #include <string.h>
- /* report GL errors, if any, to stderr */
- void checkError(const char *functionName)
- {
- GLenum error;
- while (( error = glGetError() ) != GL_NO_ERROR) {
- fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
- }
- }
- /* extension #defines, types and entries, avoiding a dependency on additional
- libraries like GLEW or the GL/glext.h header */
- #ifndef GL_ARRAY_BUFFER
- #define GL_ARRAY_BUFFER 0x8892
- #endif
- #ifndef GL_STATIC_DRAW
- #define GL_STATIC_DRAW 0x88E4
- #endif
- #ifndef GL_FRAGMENT_SHADER
- #define GL_FRAGMENT_SHADER 0x8B30
- #endif
- #ifndef GL_VERTEX_SHADER
- #define GL_VERTEX_SHADER 0x8B31
- #endif
- #ifndef GL_SHADING_LANGUAGE_VERSION
- #define GL_SHADING_LANGUAGE_VERSION 0x8B8C
- #endif
- #ifndef GL_COMPILE_STATUS
- #define GL_COMPILE_STATUS 0x8B81
- #endif
- #ifndef GL_LINK_STATUS
- #define GL_LINK_STATUS 0x8B82
- #endif
- #ifndef GL_INFO_LOG_LENGTH
- #define GL_INFO_LOG_LENGTH 0x8B84
- #endif
- typedef ptrdiff_t ourGLsizeiptr;
- typedef char ourGLchar;
- #ifndef APIENTRY
- #define APIENTRY
- #endif
- #ifndef GL_ARB_vertex_array_object
- typedef void (APIENTRY *PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
- typedef void (APIENTRY *PFNGLBINDVERTEXARRAYPROC) (GLuint array);
- #endif
- #ifndef GL_VERSION_1_5
- typedef void (APIENTRY *PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
- typedef void (APIENTRY *PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
- typedef void (APIENTRY *PFNGLBUFFERDATAPROC) (GLenum target, ourGLsizeiptr size, const GLvoid *data, GLenum usage);
- #endif
- #ifndef GL_VERSION_2_0
- typedef GLuint (APIENTRY *PFNGLCREATESHADERPROC) (GLenum type);
- typedef void (APIENTRY *PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const ourGLchar **string, const GLint *length);
- typedef void (APIENTRY *PFNGLCOMPILESHADERPROC) (GLuint shader);
- typedef GLuint (APIENTRY *PFNGLCREATEPROGRAMPROC) (void);
- typedef void (APIENTRY *PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
- typedef void (APIENTRY *PFNGLLINKPROGRAMPROC) (GLuint program);
- typedef void (APIENTRY *PFNGLUSEPROGRAMPROC) (GLuint program);
- typedef void (APIENTRY *PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
- typedef void (APIENTRY *PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog);
- typedef void (APIENTRY *PFNGLGETPROGRAMIVPROC) (GLenum target, GLenum pname, GLint *params);
- typedef void (APIENTRY *PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog);
- typedef GLint (APIENTRY *PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const ourGLchar *name);
- typedef void (APIENTRY *PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
- typedef void (APIENTRY *PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
- typedef GLint (APIENTRY *PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const ourGLchar *name);
- typedef void (APIENTRY *PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- #endif
- PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays;
- PFNGLBINDVERTEXARRAYPROC gl_BindVertexArray;
- PFNGLGENBUFFERSPROC gl_GenBuffers;
- PFNGLBINDBUFFERPROC gl_BindBuffer;
- PFNGLBUFFERDATAPROC gl_BufferData;
- PFNGLCREATESHADERPROC gl_CreateShader;
- PFNGLSHADERSOURCEPROC gl_ShaderSource;
- PFNGLCOMPILESHADERPROC gl_CompileShader;
- PFNGLCREATEPROGRAMPROC gl_CreateProgram;
- PFNGLATTACHSHADERPROC gl_AttachShader;
- PFNGLLINKPROGRAMPROC gl_LinkProgram;
- PFNGLUSEPROGRAMPROC gl_UseProgram;
- PFNGLGETSHADERIVPROC gl_GetShaderiv;
- PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog;
- PFNGLGETPROGRAMIVPROC gl_GetProgramiv;
- PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog;
- PFNGLGETATTRIBLOCATIONPROC gl_GetAttribLocation;
- PFNGLVERTEXATTRIBPOINTERPROC gl_VertexAttribPointer;
- PFNGLENABLEVERTEXATTRIBARRAYPROC gl_EnableVertexAttribArray;
- PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation;
- PFNGLUNIFORMMATRIX4FVPROC gl_UniformMatrix4fv;
- void initExtensionEntries(void)
- {
- gl_GenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) glutGetProcAddress ("glGenVertexArrays");
- gl_BindVertexArray = (PFNGLBINDVERTEXARRAYPROC) glutGetProcAddress ("glBindVertexArray");
- if (!gl_GenVertexArrays || !gl_BindVertexArray)
- {
- fprintf (stderr, "glGenVertexArrays or glBindVertexArray not found");
- exit(1);
- }
- gl_GenBuffers = (PFNGLGENBUFFERSPROC) glutGetProcAddress ("glGenBuffers");
- gl_BindBuffer = (PFNGLBINDBUFFERPROC) glutGetProcAddress ("glBindBuffer");
- gl_BufferData = (PFNGLBUFFERDATAPROC) glutGetProcAddress ("glBufferData");
- if (!gl_GenBuffers || !gl_BindBuffer || !gl_BufferData)
- {
- fprintf (stderr, "glGenBuffers, glBindBuffer or glBufferData not found");
- exit(1);
- }
- gl_CreateShader = (PFNGLCREATESHADERPROC) glutGetProcAddress ("glCreateShader");
- gl_ShaderSource = (PFNGLSHADERSOURCEPROC) glutGetProcAddress ("glShaderSource");
- gl_CompileShader = (PFNGLCOMPILESHADERPROC) glutGetProcAddress ("glCompileShader");
- gl_CreateProgram = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress ("glCreateProgram");
- gl_AttachShader = (PFNGLATTACHSHADERPROC) glutGetProcAddress ("glAttachShader");
- gl_LinkProgram = (PFNGLLINKPROGRAMPROC) glutGetProcAddress ("glLinkProgram");
- gl_UseProgram = (PFNGLUSEPROGRAMPROC) glutGetProcAddress ("glUseProgram");
- gl_GetShaderiv = (PFNGLGETSHADERIVPROC) glutGetProcAddress ("glGetShaderiv");
- gl_GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress ("glGetShaderInfoLog");
- gl_GetProgramiv = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress ("glGetProgramiv");
- gl_GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress ("glGetProgramInfoLog");
- gl_GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress ("glGetAttribLocation");
- gl_VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) glutGetProcAddress ("glVertexAttribPointer");
- gl_EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress ("glEnableVertexAttribArray");
- gl_GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress ("glGetUniformLocation");
- gl_UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress ("glUniformMatrix4fv");
- if (!gl_CreateShader || !gl_ShaderSource || !gl_CompileShader || !gl_CreateProgram || !gl_AttachShader || !gl_LinkProgram || !gl_UseProgram || !gl_GetShaderiv || !gl_GetShaderInfoLog || !gl_GetProgramiv || !gl_GetProgramInfoLog || !gl_GetAttribLocation || !gl_VertexAttribPointer || !gl_EnableVertexAttribArray || !gl_GetUniformLocation || !gl_UniformMatrix4fv)
- {
- fprintf (stderr, "glCreateShader, glShaderSource, glCompileShader, glCreateProgram, glAttachShader, glLinkProgram, glUseProgram, glGetShaderiv, glGetShaderInfoLog, glGetProgramiv, glGetProgramInfoLog, glGetAttribLocation, glVertexAttribPointer, glEnableVertexAttribArray, glGetUniformLocation or glUniformMatrix4fv not found");
- exit(1);
- }
- }
- /* vertex array data for a colored 2D triangle, consisting of RGB color values
- and XY coordinates */
- const GLfloat varray[] = {
- 1.0f, 0.0f, 0.0f, /* red */
- 5.0f, 5.0f, /* lower left */
- 0.0f, 1.0f, 0.0f, /* green */
- 25.0f, 5.0f, /* lower right */
- 0.0f, 0.0f, 1.0f, /* blue */
- 5.0f, 25.0f /* upper left */
- };
- /* ISO C somehow enforces this silly use of 'enum' for compile-time constants */
- enum {
- numColorComponents = 3,
- numVertexComponents = 2,
- stride = sizeof(GLfloat) * (numColorComponents + numVertexComponents),
- numElements = sizeof(varray) / stride
- };
- /* the name of the vertex buffer object */
- GLuint vertexBufferName;
- GLuint vertexArrayName;
- void initBuffer(void)
- {
- /* Need to setup a vertex array as otherwise invalid operation errors can
- * occur when accessing vertex buffer (OpenGL 3.3 has no default zero named
- * vertex array)
- */
- gl_GenVertexArrays(1, &vertexArrayName);
- gl_BindVertexArray(vertexArrayName);
- gl_GenBuffers (1, &vertexBufferName);
- gl_BindBuffer (GL_ARRAY_BUFFER, vertexBufferName);
- gl_BufferData (GL_ARRAY_BUFFER, sizeof(varray), varray, GL_STATIC_DRAW);
- checkError ("initBuffer");
- }
- const ourGLchar *vertexShaderSource[] = {
- "#version 140\n",
- "uniform mat4 fg_ProjectionMatrix;\n",
- "in vec4 fg_Color;\n",
- "in vec4 fg_Vertex;\n",
- "smooth out vec4 fg_SmoothColor;\n",
- "void main()\n",
- "{\n",
- " fg_SmoothColor = fg_Color;\n",
- " gl_Position = fg_ProjectionMatrix * fg_Vertex;\n",
- "}\n"
- };
- const ourGLchar *fragmentShaderSource[] = {
- "#version 140\n",
- "smooth in vec4 fg_SmoothColor;\n",
- "out vec4 fg_FragColor;\n",
- "void main(void)\n",
- "{\n",
- " fg_FragColor = fg_SmoothColor;\n",
- "}\n"
- };
- void compileAndCheck(GLuint shader)
- {
- GLint status;
- gl_CompileShader (shader);
- gl_GetShaderiv (shader, GL_COMPILE_STATUS, &status);
- if (status == GL_FALSE) {
- GLint infoLogLength;
- ourGLchar *infoLog;
- gl_GetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLogLength);
- infoLog = (ourGLchar*) malloc (infoLogLength);
- gl_GetShaderInfoLog (shader, infoLogLength, NULL, infoLog);
- fprintf (stderr, "compile log: %s\n", infoLog);
- free (infoLog);
- }
- }
- GLuint compileShaderSource(GLenum type, GLsizei count, const ourGLchar **string)
- {
- GLuint shader = gl_CreateShader (type);
- gl_ShaderSource (shader, count, string, NULL);
- compileAndCheck (shader);
- return shader;
- }
- void linkAndCheck(GLuint program)
- {
- GLint status;
- gl_LinkProgram (program);
- gl_GetProgramiv (program, GL_LINK_STATUS, &status);
- if (status == GL_FALSE) {
- GLint infoLogLength;
- ourGLchar *infoLog;
- gl_GetProgramiv (program, GL_INFO_LOG_LENGTH, &infoLogLength);
- infoLog = (ourGLchar*) malloc (infoLogLength);
- gl_GetProgramInfoLog (program, infoLogLength, NULL, infoLog);
- fprintf (stderr, "link log: %s\n", infoLog);
- free (infoLog);
- }
- }
- GLuint createProgram(GLuint vertexShader, GLuint fragmentShader)
- {
- GLuint program = gl_CreateProgram ();
- if (vertexShader != 0) {
- gl_AttachShader (program, vertexShader);
- }
- if (fragmentShader != 0) {
- gl_AttachShader (program, fragmentShader);
- }
- linkAndCheck (program);
- return program;
- }
- GLuint fgProjectionMatrixIndex;
- GLuint fgColorIndex;
- GLuint fgVertexIndex;
- void initShader(void)
- {
- const GLsizei vertexShaderLines = sizeof(vertexShaderSource) / sizeof(ourGLchar*);
- GLuint vertexShader =
- compileShaderSource (GL_VERTEX_SHADER, vertexShaderLines, vertexShaderSource);
- const GLsizei fragmentShaderLines = sizeof(fragmentShaderSource) / sizeof(ourGLchar*);
- GLuint fragmentShader =
- compileShaderSource (GL_FRAGMENT_SHADER, fragmentShaderLines, fragmentShaderSource);
- GLuint program = createProgram (vertexShader, fragmentShader);
- gl_UseProgram (program);
- fgProjectionMatrixIndex = gl_GetUniformLocation(program, "fg_ProjectionMatrix");
- fgColorIndex = gl_GetAttribLocation(program, "fg_Color");
- gl_EnableVertexAttribArray (fgColorIndex);
- fgVertexIndex = gl_GetAttribLocation(program, "fg_Vertex");
- gl_EnableVertexAttribArray (fgVertexIndex);
- checkError ("initShader");
- }
- void initRendering(void)
- {
- glClearColor (0.0, 0.0, 0.0, 0.0);
- checkError ("initRendering");
- }
- void init(void)
- {
- initExtensionEntries ();
- initBuffer ();
- initShader ();
- initRendering ();
- }
- void dumpInfo(void)
- {
- printf ("Vendor: %s\n", glGetString (GL_VENDOR));
- printf ("Renderer: %s\n", glGetString (GL_RENDERER));
- printf ("Version: %s\n", glGetString (GL_VERSION));
- printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
- checkError ("dumpInfo");
- }
- const GLvoid *bufferObjectPtr (GLsizei index)
- {
- return (const GLvoid *) (((char *) NULL) + index);
- }
- GLfloat projectionMatrix[16];
- void triangle(void)
- {
- gl_UniformMatrix4fv (fgProjectionMatrixIndex, 1, GL_FALSE, projectionMatrix);
- gl_BindBuffer (GL_ARRAY_BUFFER, vertexBufferName);
- gl_VertexAttribPointer (fgColorIndex, numColorComponents, GL_FLOAT, GL_FALSE,
- stride, bufferObjectPtr (0));
- gl_VertexAttribPointer (fgVertexIndex, numVertexComponents, GL_FLOAT, GL_FALSE,
- stride, bufferObjectPtr (sizeof(GLfloat) * numColorComponents));
- glDrawArrays(GL_TRIANGLES, 0, numElements);
- checkError ("triangle");
- }
- void display(void)
- {
- glClear (GL_COLOR_BUFFER_BIT);
- triangle ();
- glFlush ();
- checkError ("display");
- }
- void loadOrthof(GLfloat *m, GLfloat l, GLfloat r, GLfloat b, GLfloat t,
- GLfloat n, GLfloat f)
- {
- m[ 0] = 2.0f / (r - l);
- m[ 1] = 0.0f;
- m[ 2] = 0.0f;
- m[ 3] = 0.0f;
- m[ 4] = 0.0f;
- m[ 5] = 2.0f / (t - b);
- m[ 6] = 0.0f;
- m[ 7] = 0.0f;
- m[ 8] = 0.0f;
- m[ 9] = 0.0f;
- m[10] = -2.0f / (f - n);
- m[11] = 0.0f;
- m[12] = -(r + l) / (r - l);
- m[13] = -(t + b) / (t - b);
- m[14] = -(f + n) / (f - n);
- m[15] = 1.0f;
- }
- void loadOrtho2Df(GLfloat *m, GLfloat l, GLfloat r, GLfloat b, GLfloat t)
- {
- loadOrthof (m, l, r, b, t, -1.0f, 1.0f);
- }
- void reshape (int w, int h)
- {
- glViewport (0, 0, (GLsizei) w, (GLsizei) h);
- if (w <= h) {
- loadOrtho2Df (projectionMatrix, 0.0f, 30.0f, 0.0f, 30.0f * (GLfloat) h/(GLfloat) w);
- } else {
- loadOrtho2Df (projectionMatrix, 0.0f, 30.0f * (GLfloat) w/(GLfloat) h, 0.0f, 30.0f);
- }
- checkError ("reshape");
- }
- void keyboard(unsigned char key, int x, int y)
- {
- switch (key) {
- case 27:
- exit(0);
- break;
- }
- }
- void samplemenu(int menuID)
- {}
- int main(int argc, char** argv)
- {
- int menuA;
- glutInit(&argc, argv);
- glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
- /* add command line argument "classic" for a pre-3.x context */
- if ((argc != 2) || (strcmp (argv[1], "classic") != 0)) {
- glutInitContextVersion (3, 1);
- glutInitContextFlags (GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG);
- }
- glutInitWindowSize (500, 500);
- glutInitWindowPosition (100, 100);
- glutCreateWindow (argv[0]);
- dumpInfo ();
- init ();
- glutDisplayFunc(display);
- glutReshapeFunc(reshape);
- glutKeyboardFunc (keyboard);
- /* Add a menu. They have their own context and should thus work with forward compatible main windows too. */
- menuA = glutCreateMenu(samplemenu);
- glutAddMenuEntry("Sub menu A1 (01)",1);
- glutAddMenuEntry("Sub menu A2 (02)",2);
- glutAddMenuEntry("Sub menu A3 (03)",3);
- glutSetMenu(menuA);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- glutMainLoop();
- return 0;
- }
|