9cc8fc0d0a
The cached error code cannot be made per-thread unless it required glfwInit (due to lack of __thread on OS X), which would be confusing and partially defeats the purpose of it. Beginners would use the generic error string facility instead of the error callback and then be confused by its nondescript messages. Storing the provided error code from within the error callback, whether globally or per-thread, requires just a few lines of code and hands control to the user without compromising thread safety.
103 lines
2.9 KiB
C
103 lines
2.9 KiB
C
//========================================================================
|
|
// This is a small test application for GLFW.
|
|
// The program opens a window (640x480), and renders a spinning colored
|
|
// triangle (it is controlled with both the GLFW timer and the mouse).
|
|
//========================================================================
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define GLFW_INCLUDE_GLU
|
|
#include <GL/glfw3.h>
|
|
|
|
static void error_callback(int error, const char* description)
|
|
{
|
|
fprintf(stderr, "Error: %s\n", description);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int width, height, x;
|
|
GLFWwindow window;
|
|
|
|
glfwSetErrorCallback(error_callback);
|
|
|
|
// Initialise GLFW
|
|
if (!glfwInit())
|
|
exit(EXIT_FAILURE);
|
|
|
|
// Open a window and create its OpenGL context
|
|
window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Spinning Triangle", NULL);
|
|
if (!window)
|
|
{
|
|
glfwTerminate();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Enable vertical sync (on cards that support it)
|
|
glfwMakeContextCurrent(window);
|
|
glfwSwapInterval(1);
|
|
|
|
// Ensure we can capture the escape key being pressed below
|
|
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
|
|
|
|
for (;;)
|
|
{
|
|
double t = glfwGetTime();
|
|
glfwGetCursorPos(window, &x, NULL);
|
|
|
|
// Get window size (may be different than the requested size)
|
|
glfwGetWindowSize(window, &width, &height);
|
|
|
|
// Special case: avoid division by zero below
|
|
height = height > 0 ? height : 1;
|
|
|
|
glViewport(0, 0, width, height);
|
|
|
|
// Clear color buffer to black
|
|
glClearColor(0.f, 0.f, 0.f, 0.f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
// Select and setup the projection matrix
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluPerspective(65.f, (GLfloat) width / (GLfloat) height, 1.f, 100.f);
|
|
|
|
// Select and setup the modelview matrix
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glLoadIdentity();
|
|
gluLookAt(0.f, 1.f, 0.f, // Eye-position
|
|
0.f, 20.f, 0.f, // View-point
|
|
0.f, 0.f, 1.f); // Up-vector
|
|
|
|
// Draw a rotating colorful triangle
|
|
glTranslatef(0.f, 14.f, 0.f);
|
|
glRotatef(0.3f * (GLfloat) x + (GLfloat) t * 100.f, 0.f, 0.f, 1.f);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
glColor3f(1.f, 0.f, 0.f);
|
|
glVertex3f(-5.f, 0.f, -4.f);
|
|
glColor3f(0.f, 1.f, 0.f);
|
|
glVertex3f(5.f, 0.f, -4.f);
|
|
glColor3f(0.f, 0.f, 1.f);
|
|
glVertex3f(0.f, 0.f, 6.f);
|
|
glEnd();
|
|
|
|
// Swap buffers
|
|
glfwSwapBuffers(window);
|
|
glfwPollEvents();
|
|
|
|
// Check if the ESC key was pressed or the window should be closed
|
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE))
|
|
break;
|
|
if (glfwGetWindowParam(window, GLFW_CLOSE_REQUESTED))
|
|
break;
|
|
}
|
|
|
|
// Close OpenGL window and terminate GLFW
|
|
glfwTerminate();
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|