Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 923d663a28
Fetching contributors…

Cannot retrieve contributors at this time

208 lines (180 sloc) 7.073 kb
// Clip Planes OpenGL Demo by Philip Rideout
// Licensed under the Creative Commons Attribution 3.0 Unported License.
// http://creativecommons.org/licenses/by/3.0/
#include <stdlib.h>
#include "pez.h"
#include "vmath.h"
struct SceneParameters {
int IndexCount;
float Theta;
Matrix4 Projection;
Matrix4 Modelview;
Matrix4 ViewMatrix;
Matrix4 ModelMatrix;
Matrix3 NormalMatrix;
Vector4 ClipPlane;
GLfloat PackedNormalMatrix[9];
} Scene;
static GLuint LoadProgram(const char* vsKey, const char* gsKey, const char* fsKey);
static GLuint CurrentProgram();
#define u(x) glGetUniformLocation(CurrentProgram(), x)
#define a(x) glGetAttribLocation(CurrentProgram(), x)
PezConfig PezGetConfig()
{
PezConfig config;
config.Title = __FILE__;
config.Width = 853;
config.Height = 480;
config.Multisampling = true;
config.VerticalSync = false;
return config;
}
static void CreateTorus(float major, float minor, int slices, int stacks)
{
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
int vertexCount = slices * stacks * 3;
int vertexStride = sizeof(float) * 3;
GLsizeiptr size = vertexCount * vertexStride;
GLfloat* positions = (GLfloat*) malloc(size);
GLfloat* position = positions;
for (int slice = 0; slice < slices; slice++) {
float theta = slice * 2.0f * Pi / slices;
for (int stack = 0; stack < stacks; stack++) {
float phi = stack * 2.0f * Pi / stacks;
float beta = major + minor * cos(phi);
*position++ = cos(theta) * beta;
*position++ = sin(theta) * beta;
*position++ = sin(phi) * minor;
}
}
GLuint handle;
glGenBuffers(1, &handle);
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, size, positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(a("Position"));
glVertexAttribPointer(a("Position"), 3, GL_FLOAT, GL_FALSE,
vertexStride, 0);
free(positions);
Scene.IndexCount = slices * stacks * 6;
size = Scene.IndexCount * sizeof(GLushort);
GLushort* indices = (GLushort*) malloc(size);
GLushort* index = indices;
int v = 0;
for (int i = 0; i < slices - 1; i++) {
for (int j = 0; j < stacks; j++) {
int next = (j + 1) % stacks;
*index++ = v+next+stacks; *index++ = v+next; *index++ = v+j;
*index++ = v+j; *index++ = v+j+stacks; *index++ = v+next+stacks;
}
v += stacks;
}
for (int j = 0; j < stacks; j++) {
int next = (j + 1) % stacks;
*index++ = next; *index++ = v+next; *index++ = v+j;
*index++ = v+j; *index++ = j; *index++ = next;
}
glGenBuffers(1, &handle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW);
free(indices);
}
void PezInitialize()
{
LoadProgram("VS", "GS", "FS");
PezConfig cfg = PezGetConfig();
const float h = 5.0f;
const float w = h * cfg.Width / cfg.Height;
Scene.Projection = M4MakeFrustum(-w, w, // left & right planes
-h, h, // bottom & top planes
65, 90); // near & far planes
const float MajorRadius = 8.0f, MinorRadius = 2.0f;
const int Slices = 40, Stacks = 10;
CreateTorus(MajorRadius, MinorRadius, Slices, Stacks);
Scene.Theta = 0;
Scene.ClipPlane = (Vector4){0, 1, 0, 7};
glEnable(GL_DEPTH_TEST);
glEnable(GL_CLIP_DISTANCE0);
glClearColor(0.5f, 0.6f, 0.7f, 1.0f);
}
void PezUpdate(float seconds)
{
const float RadiansPerSecond = 0.5f;
Scene.Theta += seconds * RadiansPerSecond;
// Create the model-view matrix:
Scene.ModelMatrix = M4MakeRotationZ(Scene.Theta);
Point3 eye = {0, -75, 25};
Point3 target = {0, 0, 0};
Vector3 up = {0, 1, 0};
Scene.ViewMatrix = M4MakeLookAt(eye, target, up);
Scene.Modelview = M4Mul(Scene.ViewMatrix, Scene.ModelMatrix);
Scene.NormalMatrix = M4GetUpper3x3(Scene.Modelview);
for (int i = 0; i < 9; ++i)
Scene.PackedNormalMatrix[i] = M3GetElem(Scene.NormalMatrix, i/3, i%3);
}
void PezRender()
{
float* pModel = (float*) &Scene.ModelMatrix;
float* pView = (float*) &Scene.ViewMatrix;
float* pModelview = (float*) &Scene.Modelview;
float* pProjection = (float*) &Scene.Projection;
float* pNormalMatrix = &Scene.PackedNormalMatrix[0];
glUniformMatrix4fv(u("ViewMatrix"), 1, 0, pView);
glUniformMatrix4fv(u("ModelMatrix"), 1, 0, pModel);
glUniformMatrix4fv(u("Modelview"), 1, 0, pModelview);
glUniformMatrix4fv(u("Projection"), 1, 0, pProjection);
glUniformMatrix3fv(u("NormalMatrix"), 1, 0, pNormalMatrix);
glUniform4fv(u("ClipPlane"), 1, &Scene.ClipPlane.x);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, Scene.IndexCount, GL_UNSIGNED_SHORT, 0);
}
void PezHandleMouse(int x, int y, int action)
{
}
static GLuint CurrentProgram()
{
GLuint p;
glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*) &p);
return p;
}
static GLuint LoadProgram(const char* vsKey, const char* gsKey, const char* fsKey)
{
GLchar spew[256];
GLint compileSuccess;
GLuint programHandle = glCreateProgram();
const char* vsSource = pezGetShader(vsKey);
pezCheck(vsSource != 0, "Can't find vshader: %s\n", vsKey);
GLuint vsHandle = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vsHandle, 1, &vsSource, 0);
glCompileShader(vsHandle);
glGetShaderiv(vsHandle, GL_COMPILE_STATUS, &compileSuccess);
glGetShaderInfoLog(vsHandle, sizeof(spew), 0, spew);
pezCheck(compileSuccess, "Can't compile vshader:\n%s", spew);
glAttachShader(programHandle, vsHandle);
const char* gsSource = pezGetShader(gsKey);
pezCheck(gsSource != 0, "Can't find gshader: %s\n", gsKey);
GLuint gsHandle = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(gsHandle, 1, &gsSource, 0);
glCompileShader(gsHandle);
glGetShaderiv(gsHandle, GL_COMPILE_STATUS, &compileSuccess);
glGetShaderInfoLog(gsHandle, sizeof(spew), 0, spew);
pezCheck(compileSuccess, "Can't compile gshader:\n%s", spew);
glAttachShader(programHandle, gsHandle);
const char* fsSource = pezGetShader(fsKey);
pezCheck(fsSource != 0, "Can't find fshader: %s\n", fsKey);
GLuint fsHandle = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fsHandle, 1, &fsSource, 0);
glCompileShader(fsHandle);
glGetShaderiv(fsHandle, GL_COMPILE_STATUS, &compileSuccess);
glGetShaderInfoLog(fsHandle, sizeof(spew), 0, spew);
pezCheck(compileSuccess, "Can't compile fshader:\n%s", spew);
glAttachShader(programHandle, fsHandle);
glLinkProgram(programHandle);
GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
glGetProgramInfoLog(programHandle, sizeof(spew), 0, spew);
pezCheck(linkSuccess, "Can't link shaders:\n%s", spew);
glUseProgram(programHandle);
return programHandle;
}
Jump to Line
Something went wrong with that request. Please try again.