mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-24 12:30:17 +00:00
243 lines
6.9 KiB
C++
243 lines
6.9 KiB
C++
//
|
|
// This file contains standard OpenGL API calls that are mostly uninteresting if
|
|
// you are purely trying to learn OSD. The following operations are implemented
|
|
// here:
|
|
//
|
|
// * First time OpenGL state initialization
|
|
// * Compile vertex and fragment shaders
|
|
// * Link shaders into a program
|
|
// * Per-frame drawing state setup
|
|
//
|
|
|
|
#pragma once
|
|
|
|
//
|
|
// ### OS Compatibility
|
|
// The following is to ensure the example runs on Linux, Windows and OS X
|
|
//
|
|
#if defined(__APPLE__)
|
|
#include <OpenGL/gl3.h>
|
|
#define GLFW_INCLUDE_GL3
|
|
#define GLFW_NO_GLU
|
|
#else
|
|
#include <stdlib.h>
|
|
#include <GL/glew.h>
|
|
#if defined(WIN32)
|
|
#include <GL/wglew.h>
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(GLFW_VERSION_3)
|
|
#include <GL/glfw3.h>
|
|
GLFWwindow* g_window=0;
|
|
GLFWmonitor* g_primary=0;
|
|
#else
|
|
#include <GL/glfw.h>
|
|
#endif
|
|
|
|
|
|
|
|
#include "algebra.h"
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
|
|
//
|
|
// Microsoft uses a slightly different snprintf declaration, which we hide
|
|
// here by aliasing it as snprintf
|
|
//
|
|
#if _MSC_VER
|
|
#define snprintf _snprintf
|
|
#endif
|
|
|
|
#if defined(__APPLE__)
|
|
#define drawString(x, y, ...);
|
|
/* \
|
|
GLUT on OSX means gl 2.1, so forgoe the text drawing until we have a better solution
|
|
{ char line[1024]; \
|
|
snprintf(line, 1024, __VA_ARGS__); \
|
|
char *p = line; \
|
|
glWindowPos2f(x, y); \
|
|
while(*p) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *p++); } }
|
|
*/
|
|
#else
|
|
#define drawString(x, y, ...) \
|
|
{ char line[1024]; \
|
|
snprintf(line, 1024, __VA_ARGS__); \
|
|
char *p = line; \
|
|
glWindowPos2i(x, y); \
|
|
while(*p) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *p++); } }
|
|
#endif
|
|
|
|
//
|
|
// These are standard OpenGL shader program handles. One for wire frame and one
|
|
// for shaded rendering
|
|
//
|
|
GLuint g_quadLineProgram = 0;
|
|
GLuint g_quadFillProgram = 0;
|
|
|
|
//
|
|
// To avoid reading the shader source from a file, we include it here as a string
|
|
// see [shader.glsl](shader.html).
|
|
//
|
|
static const char *shaderSource =
|
|
#include "shader.inc"
|
|
;
|
|
|
|
GLfloat g_modelView[16], g_proj[16], g_mvp[16];
|
|
|
|
void
|
|
bindProgram(GLuint program)
|
|
{
|
|
glUseProgram(program);
|
|
|
|
// shader uniform setting
|
|
GLint position = glGetUniformLocation(program, "lightSource[0].position");
|
|
GLint ambient = glGetUniformLocation(program, "lightSource[0].ambient");
|
|
GLint diffuse = glGetUniformLocation(program, "lightSource[0].diffuse");
|
|
GLint specular = glGetUniformLocation(program, "lightSource[0].specular");
|
|
GLint position1 = glGetUniformLocation(program, "lightSource[1].position");
|
|
GLint ambient1 = glGetUniformLocation(program, "lightSource[1].ambient");
|
|
GLint diffuse1 = glGetUniformLocation(program, "lightSource[1].diffuse");
|
|
GLint specular1 = glGetUniformLocation(program, "lightSource[1].specular");
|
|
|
|
glUniform4f(position, 0.5, 0.2f, 1.0f, 0.0f);
|
|
glUniform4f(ambient, 0.1f, 0.1f, 0.1f, 1.0f);
|
|
glUniform4f(diffuse, 0.7f, 0.7f, 0.7f, 1.0f);
|
|
glUniform4f(specular, 0.8f, 0.8f, 0.8f, 1.0f);
|
|
|
|
glUniform4f(position1, -0.8f, 0.4f, -1.0f, 0.0f);
|
|
glUniform4f(ambient1, 0.0f, 0.0f, 0.0f, 1.0f);
|
|
glUniform4f(diffuse1, 0.5f, 0.5f, 0.5f, 1.0f);
|
|
glUniform4f(specular1, 0.8f, 0.8f, 0.8f, 1.0f);
|
|
|
|
GLint otcMatrix = glGetUniformLocation(program, "objectToClipMatrix");
|
|
GLint oteMatrix = glGetUniformLocation(program, "objectToEyeMatrix");
|
|
multMatrix(g_mvp, g_modelView, g_proj);
|
|
|
|
glUniformMatrix4fv(otcMatrix, 1, false, g_mvp);
|
|
glUniformMatrix4fv(oteMatrix, 1, false, g_modelView);
|
|
}
|
|
|
|
static GLuint
|
|
compileShader(GLenum shaderType, const char *section, const char *define)
|
|
{
|
|
const char *sources[4];
|
|
char sdefine[64];
|
|
sprintf(sdefine, "#define %s\n", section);
|
|
|
|
sources[0] = "#version 330\n";
|
|
sources[1] = define;
|
|
sources[2] = sdefine;
|
|
sources[3] = shaderSource;
|
|
|
|
GLuint shader = glCreateShader(shaderType);
|
|
glShaderSource(shader, 4, sources, NULL);
|
|
glCompileShader(shader);
|
|
|
|
GLint status;
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
|
if( status == GL_FALSE ) {
|
|
GLchar emsg[1024];
|
|
glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
|
|
fprintf(stderr, "Error compiling GLSL shader (%s): %s\n", section, emsg );
|
|
fprintf(stderr, "Section: %s\n", sdefine);
|
|
fprintf(stderr, "Defines: %s\n", define);
|
|
fprintf(stderr, "Source: %s\n", sources[2]);
|
|
exit(0);
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
GLuint
|
|
linkProgram(const char *define)
|
|
{
|
|
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, "VERTEX_SHADER", define);
|
|
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, "FRAGMENT_SHADER", define);
|
|
|
|
GLuint program = glCreateProgram();
|
|
glAttachShader(program, vertexShader);
|
|
glAttachShader(program, fragmentShader);
|
|
|
|
glBindAttribLocation(program, 0, "position");
|
|
|
|
glLinkProgram(program);
|
|
|
|
glDeleteShader(vertexShader);
|
|
glDeleteShader(fragmentShader);
|
|
|
|
GLint status;
|
|
glGetProgramiv(program, GL_LINK_STATUS, &status );
|
|
if( status == GL_FALSE ) {
|
|
GLchar emsg[1024];
|
|
glGetProgramInfoLog(program, sizeof(emsg), 0, emsg);
|
|
fprintf(stderr, "Error linking GLSL program : %s\n", emsg );
|
|
fprintf(stderr, "Defines: %s\n", define);
|
|
exit(0);
|
|
}
|
|
|
|
return program;
|
|
}
|
|
|
|
void
|
|
initGL()
|
|
{
|
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_CULL_FACE);
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
g_quadFillProgram = linkProgram("#define PRIM_QUAD\n#define GEOMETRY_OUT_FILL\n");
|
|
g_quadLineProgram = linkProgram("#define PRIM_QUAD\n#define GEOMETRY_OUT_LINE\n");
|
|
}
|
|
|
|
void
|
|
setupForDisplay(int width, int height, float size, float* center)
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glViewport(0, 0, width, height);
|
|
setIdentity(g_proj);
|
|
setIdentity(g_modelView);
|
|
setIdentity(g_mvp);
|
|
|
|
// setup the projection
|
|
float aspect = width/(float)height;
|
|
setPersp(45.0f, aspect, 0.01f, 500.0f, g_proj);
|
|
|
|
// setup the model view matrix
|
|
translateMatrix(-center[0], -center[1], -center[2], g_modelView);
|
|
rotateMatrix(-90, 1, 0, 0, g_modelView); // z-up model
|
|
translateMatrix(0, 0, -size, g_modelView);
|
|
}
|
|
|
|
|
|
static void
|
|
checkGLErrors(std::string const & where = "")
|
|
{
|
|
GLuint err;
|
|
while ((err = glGetError()) != GL_NO_ERROR) {
|
|
std::cout << "Where = " << where << std::endl;
|
|
|
|
if (err == GL_INVALID_ENUM) {
|
|
std::cout << "GL_INVALID_ENUM\n";
|
|
} else
|
|
if (err == GL_INVALID_VALUE) {
|
|
std::cout << "GL_INVALID_VALUE\n";
|
|
} else
|
|
if (err == GL_INVALID_OPERATION) {
|
|
std::cout << "GL_INVALID_OPERATION\n";
|
|
} else
|
|
if (err == GL_INVALID_OPERATION) {
|
|
std::cout << "GL_INVALID_OPERATION\n";
|
|
} else
|
|
if (err == GL_OUT_OF_MEMORY) {
|
|
std::cout << "GL_OUT_OF_MEMORY\n";
|
|
} else {
|
|
std::cout << "Some other gl error \n";
|
|
}
|
|
}
|
|
}
|