initial version
This commit is contained in:
15
Makefile
Normal file
15
Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
OPTS=-O0 -g
|
||||
|
||||
all: billiards
|
||||
|
||||
gl3.o: gl3.c gl3.h
|
||||
g++ -c $(OPTS) gl3.c
|
||||
|
||||
billiards.o: billiards.c gl3.h sphere.h
|
||||
g++ -c $(OPTS) billiards.c
|
||||
|
||||
billiards: billiards.o gl3.o
|
||||
g++ $(OPTS) -o billiards billiards.o gl3.o -lX11 -lGL -lGLEW
|
||||
|
||||
clean:
|
||||
rm billiards billiards.o gl3.o
|
||||
498
billiards.c
Normal file
498
billiards.c
Normal file
@@ -0,0 +1,498 @@
|
||||
#include <sys/time.h>
|
||||
#include <glm/glm.hpp>
|
||||
#define GLM_ENABLE_EXPERIMENTAL 1
|
||||
#include <glm/gtx/transform.hpp>
|
||||
#include <glm/gtx/rotate_vector.hpp>
|
||||
|
||||
#include "gl3.h"
|
||||
#include "sphere.h"
|
||||
|
||||
#define EPSILON 1e-6
|
||||
#define PATH_VERTICES 10000
|
||||
#define ARROW_VERTICES 6
|
||||
|
||||
// functions
|
||||
static void start_timer();
|
||||
static void wait_update_timer();
|
||||
static bool checkEvents();
|
||||
static int findCollision(double x1, double x2, double v1, double v2, float *line_strip, int nVertices, double *time, double *n1, double *n2);
|
||||
static int calculatePath(GLfloat *outline, int nOutlineVertices, GLfloat *path, GLfloat *times, int nPathVertices, double x1, double x2, double v1, double v2);
|
||||
static bool processEvent(XEvent *ev);
|
||||
static void select_outline(int i);
|
||||
static void init();
|
||||
static void cleanup();
|
||||
static void draw();
|
||||
|
||||
// globals
|
||||
struct timeval start_time;
|
||||
unsigned long frames;
|
||||
double elapsed, frametime;
|
||||
|
||||
GLInfo gl;
|
||||
GLuint program, program3d;
|
||||
unsigned int width = 100, height = 100;
|
||||
float speed = 1, flowtime = 0;
|
||||
int stopped = 0;
|
||||
int flowtime_index = 0;
|
||||
|
||||
FILE *dumpfile;
|
||||
|
||||
GLuint outlineVA, outlineVB;
|
||||
GLuint pathVA, pathVB[2];
|
||||
GLuint arrowVA, arrowVB;
|
||||
GLuint ballVA;
|
||||
|
||||
int outline_index = 0;
|
||||
int outline_count = 12;
|
||||
int outline_lengths[] = {5, 5, 5, 5, 4, 4, 4, 4, 7, 7, 7, 13};
|
||||
GLfloat outlines[12][30] = {
|
||||
{-2, -1, 2, -1, 2, 1, -2, 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 1, -2, 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 1, -2, 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 1, -2, 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 4/sqrt(3) - 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 4/sqrt(3) - 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 4/sqrt(3) - 1, -2, -1},
|
||||
{-2, -1, 2, -1, 2, 4*tan(M_PI/8) - 1, -2, -1},
|
||||
{1, 1, 1, 0, 2.7614348, 0, 2.7614348, -1, -1, -1, -1, 1, 1, 1},
|
||||
{1, 1, 1, 0, 2.7614348, 0, 2.7614348, -1, -1, -1, -1, 1, 1, 1},
|
||||
{-1.2, 1, 1.2, 1, 0.2, 0, 1.2, -1, -1.2, -1, -0.2, 0, -1.2, 1},
|
||||
{-2, -1, -1, -1, -1, -0.05, 1, -0.05, 1, -1, 2, -1, 2, 1, 1, 1, 1, 0.05, -1, 0.05, -1, 1, -2, 1, -2, -1},
|
||||
};
|
||||
GLfloat starting_vectors[] = {
|
||||
-1, 0, 2, 0,
|
||||
-1, 0, 1.6, 2.4,
|
||||
-1, 0, 7.04, 8,
|
||||
-1, 0, 10, 7.34819206,
|
||||
0, -0.5, 1, -sqrt(3),
|
||||
0, -0.5, 1, 2.5*sqrt(3),
|
||||
0, -0.5, 5, 5,
|
||||
0.4, -0.7, -0.5, 1 + sqrt(2),
|
||||
-0.2, -0.5, 0.5, -0.5,
|
||||
0.5, 0.7, 1, -1,
|
||||
-0.2, -0.1, 2, 1,
|
||||
-1.5, -0.1, 1, 2*sqrt(2),
|
||||
};
|
||||
|
||||
char filename[1000];
|
||||
int outline_length;
|
||||
GLfloat outline[1000];
|
||||
GLfloat starting_vector[4];
|
||||
|
||||
int nPathVertices;
|
||||
GLfloat path[PATH_VERTICES*2];
|
||||
GLfloat times[PATH_VERTICES];
|
||||
GLfloat arrow[ARROW_VERTICES*2] = {0, 0, 1, 0, 0.9, 0.1, 1, 0, 0.9, -0.1, 1, 0};
|
||||
|
||||
static void start_timer()
|
||||
{
|
||||
gettimeofday(&start_time, NULL);
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
static void wait_update_timer()
|
||||
{
|
||||
struct timeval current_time;
|
||||
double new_elapsed;
|
||||
|
||||
gettimeofday(¤t_time, NULL);
|
||||
new_elapsed = current_time.tv_sec - start_time.tv_sec;
|
||||
new_elapsed += (current_time.tv_usec - start_time.tv_usec) * 1e-6;
|
||||
frametime = new_elapsed - elapsed;
|
||||
if(frametime < 0.01) { // frames < 10ms are considered too short; sleep a while and then measure again
|
||||
usleep(10000 - frametime*1e6);
|
||||
gettimeofday(¤t_time, NULL);
|
||||
new_elapsed = current_time.tv_sec - start_time.tv_sec;
|
||||
new_elapsed += (current_time.tv_usec - start_time.tv_usec) * 1e-6;
|
||||
frametime = new_elapsed - elapsed;
|
||||
}
|
||||
elapsed = new_elapsed;
|
||||
frames++;
|
||||
}
|
||||
|
||||
static bool checkEvents() // get any events from the queue and the server, process them if neccessary, quit if wanted
|
||||
{
|
||||
XEvent ev;
|
||||
|
||||
while(XCheckIfEvent(gl.display, &ev, alwaysTruePredicate, NULL)) { // we essentially want XCheckWindowEvent, but we want to avoid that events for other windows fill up the queue
|
||||
if(ev.xany.window != gl.win)
|
||||
continue;
|
||||
|
||||
if(ev.type == KeyRelease) { // deal with autorepeat
|
||||
XEvent nev;
|
||||
if(XCheckIfEvent(gl.display, &nev, alwaysTruePredicate, NULL)) { // is there another event?
|
||||
if (nev.type == KeyPress && nev.xkey.time == ev.xkey.time && nev.xkey.keycode == ev.xkey.keycode) // which is equal, but KeyPress? Then it's just auto-repeat
|
||||
continue; // so we ignore both
|
||||
|
||||
XPutBackEvent(gl.display, &nev); // otherwise put the event back, we will consider it in the next round
|
||||
}
|
||||
}
|
||||
|
||||
if(processEvent(&ev))
|
||||
return true; // quit event queue and application
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/********************************** INTERESTING PART STARTS HERE ***************************************************/
|
||||
|
||||
static int findCollision(double x1, double x2, double v1, double v2, float *line_strip, int nVertices, double *time, double *n1, double *n2)
|
||||
{
|
||||
double a1, a2, w1, w2, t, s;
|
||||
int near_wall_count = 0;
|
||||
int index = -1;
|
||||
|
||||
*time = INFINITY;
|
||||
|
||||
for(int i = 0; i < nVertices - 1; i++) {
|
||||
a1 = line_strip[2*i];
|
||||
a2 = line_strip[2*i+1];
|
||||
w1 = line_strip[2*i+2] - a1;
|
||||
w2 = line_strip[2*i+3] - a2;
|
||||
// x + tv = a + sw
|
||||
s = ((x1-a1)*v2 - (x2-a2)*v1) / (w1*v2 - w2*v1);
|
||||
t = ((x1-a1)*w2 - (x2-a2)*w1) / (w1*v2 - w2*v1);
|
||||
if(s <= 1 && s >= 0) {
|
||||
if(t < EPSILON && t > -EPSILON)
|
||||
near_wall_count ++;
|
||||
else if(t > 0 && t < *time) {
|
||||
*time = t;
|
||||
if((x1-a1)*w2 - (x2-a2)*w1 >= 0) {
|
||||
*n1 = w2;
|
||||
*n2 = -w1;
|
||||
} else {
|
||||
*n1 = -w2;
|
||||
*n2 = w1;
|
||||
}
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(index == -1 || near_wall_count > 1) {
|
||||
return 0; // failed
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int calculatePath(GLfloat *outline, int nOutlineVertices, GLfloat *path, GLfloat *times, int nPathVertices, double x1, double x2, double v1, double v2)
|
||||
{
|
||||
double t, n1, n2, v1new, v2new, ttotal;
|
||||
|
||||
memset(path, 0, nPathVertices*2*sizeof(GLfloat));
|
||||
path[0] = x1;
|
||||
path[1] = x2;
|
||||
times[0] = ttotal = 0;
|
||||
for(int i = 1; i < nPathVertices; i++) {
|
||||
if(findCollision(x1, x2, v1, v2, outline, nOutlineVertices, &t, &n1, &n2) == 0) { // we hit a singularity, so just stay here and set the next time to infinity
|
||||
path[2*i] = x1;
|
||||
path[2*i+1] = x2;
|
||||
times[i] = INFINITY;
|
||||
return i + 1;
|
||||
}
|
||||
x1 += t * v1;
|
||||
x2 += t * v2;
|
||||
v1new = v1 - 2 * (v1*n1 + v2*n2) * n1 / (n1*n1 + n2*n2); // reflect v along the normal to n
|
||||
v2new = v2 - 2 * (v1*n1 + v2*n2) * n2 / (n1*n1 + n2*n2);
|
||||
v1 = v1new;
|
||||
v2 = v2new;
|
||||
ttotal += t;
|
||||
path[2*i] = x1;
|
||||
path[2*i+1] = x2;
|
||||
times[i] = ttotal;
|
||||
}
|
||||
|
||||
return nPathVertices;
|
||||
}
|
||||
|
||||
static bool processEvent(XEvent *ev)
|
||||
{
|
||||
int state;
|
||||
|
||||
switch(ev->type) {
|
||||
|
||||
case ConfigureNotify:
|
||||
// printf("ConfigureNotify Event, new dimensions: %d %d %d %d\n", ev->xconfigure.x, ev->xconfigure.y, ev->xconfigure.width, ev->xconfigure.height);
|
||||
width = ev->xconfigure.width;
|
||||
height = ev->xconfigure.height;
|
||||
glViewport(0, 0, width, height);
|
||||
break;
|
||||
|
||||
case KeyPress:
|
||||
state = ev->xkey.state & (ShiftMask | LockMask | ControlMask);
|
||||
// printf("KeyPress Event, keycode: %d, state: %d, masked state: %d\n", ev->xkey.keycode, ev->xkey.state, state);
|
||||
if(state == 0 && ev->xkey.keycode == 26) {
|
||||
printf("Quit\n");
|
||||
return true;
|
||||
} else if(state == 0 && ev->xkey.keycode == 27) {
|
||||
select_outline(0);
|
||||
} else if (state == 0 && ev->xkey.keycode == 114) {
|
||||
speed *= 2;
|
||||
} else if (state == 0 && ev->xkey.keycode == 113) {
|
||||
speed *= 0.5;
|
||||
} else if (state == 0 && ev->xkey.keycode == 65) {
|
||||
stopped = !stopped;
|
||||
} else if (state == 0 && ev->xkey.keycode >= 10 && ev->xkey.keycode <= 19) {
|
||||
if(ev->xkey.keycode - 10 < outline_count)
|
||||
select_outline(ev->xkey.keycode - 10);
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
state = ev->xkey.state & (ShiftMask | LockMask | ControlMask);
|
||||
// printf("KeyRelease Event, keycode: %d, state: %d, masked state: %d\n", ev->xkey.keycode, ev->xkey.state, state);
|
||||
break;
|
||||
|
||||
case ClientMessage:
|
||||
if((Atom)ev->xclient.message_type == gl.wm_protocols && (Atom)ev->xclient.data.l[0] == gl.wm_delete_window) {
|
||||
printf("Window closed\n");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// printf("Event of type %d\n", ev->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int load_outline(const char *filename)
|
||||
{
|
||||
int c;
|
||||
FILE *f = fopen(filename, "r");
|
||||
if(!f)
|
||||
return 0;
|
||||
|
||||
double x, y, vx, vy, x0, y0;
|
||||
|
||||
printf("Loading file %s:\n", filename);
|
||||
|
||||
if(fscanf(f, "%lf %lf %lf %lf", &x, &y, &vx, &vy) != 4)
|
||||
return 0;
|
||||
|
||||
printf("Line: %lf %lf %lf %lf\n", x, y, vx, vy);
|
||||
starting_vector[0] = x;
|
||||
starting_vector[1] = y;
|
||||
starting_vector[2] = vx;
|
||||
starting_vector[3] = vy;
|
||||
|
||||
do { c = fgetc(f); } while(c != EOF && c != '\n');
|
||||
fscanf(f, "%lf %lf", &x0, &y0);
|
||||
printf("Line: %lf %lf\n", x0, y0);
|
||||
outline[0] = x0;
|
||||
outline[1] = y0;
|
||||
outline_length = 1;
|
||||
|
||||
while(!feof(f)) {
|
||||
if(fscanf(f, "%lf %lf", &x, &y) != 2)
|
||||
continue;
|
||||
|
||||
do { c = fgetc(f); } while(c != EOF && c != '\n');
|
||||
printf("Line: %lf %lf\n", x, y);
|
||||
outline[outline_length*2] = x;
|
||||
outline[outline_length*2+1] = y;
|
||||
outline_length++;
|
||||
}
|
||||
|
||||
outline[outline_length*2] = x0;
|
||||
outline[outline_length*2+1] = y0;
|
||||
outline_length++;
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void select_outline(int i)
|
||||
{
|
||||
load_outline(filename);
|
||||
nPathVertices = calculatePath(outline, outline_length, path, times, PATH_VERTICES, starting_vector[0], starting_vector[1], starting_vector[2], starting_vector[3]);
|
||||
|
||||
//nPathVertices = calculatePath(outlines[i], outline_lengths[i], path, times, PATH_VERTICES, starting_vectors[4*i], starting_vectors[4*i+1], starting_vectors[4*i+2], starting_vectors[4*i+3]);
|
||||
|
||||
printf("Calculated path until time: %.2f\n", times[nPathVertices - 1]);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, outlineVB);
|
||||
// glBufferData(GL_ARRAY_BUFFER, outline_lengths[i]*2*sizeof(GLfloat), outlines[i], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, outline_length*2*sizeof(GLfloat), outline, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, pathVB[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, nPathVertices*2*sizeof(GLfloat), path, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, pathVB[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, nPathVertices*sizeof(GLfloat), times, GL_STATIC_DRAW);
|
||||
|
||||
// outline_index = i;
|
||||
flowtime = 0;
|
||||
flowtime_index = 0;
|
||||
stopped = 1;
|
||||
speed = 1;
|
||||
}
|
||||
|
||||
static void init()
|
||||
{
|
||||
glGenVertexArrays(1, &outlineVA);
|
||||
glBindVertexArray(outlineVA);
|
||||
glGenBuffers(1, &outlineVB);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, outlineVB);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glGenVertexArrays(1, &arrowVA);
|
||||
glBindVertexArray(arrowVA);
|
||||
glGenBuffers(1, &arrowVB);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, arrowVB);
|
||||
glBufferData(GL_ARRAY_BUFFER, ARROW_VERTICES*2*sizeof(GLfloat), arrow, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glGenVertexArrays(1, &pathVA);
|
||||
glBindVertexArray(pathVA);
|
||||
glGenBuffers(2, pathVB);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, pathVB[0]);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, pathVB[1]);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
select_outline(outline_index);
|
||||
|
||||
// ball
|
||||
generateSphere(20, 20, &ballVA);
|
||||
|
||||
initShaders("vertex.glsl", "fragment.glsl", &program);
|
||||
initShaders("vertex3d.glsl", "fragment3d.glsl", &program3d);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CW);
|
||||
}
|
||||
|
||||
static void cleanup()
|
||||
{
|
||||
// fclose(dumpfile);
|
||||
}
|
||||
|
||||
static void draw()
|
||||
{
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if(!stopped)
|
||||
flowtime += frametime*speed;
|
||||
|
||||
glm::mat4 proj = glm::perspective((float)M_PI/4, (float)width / (float)height, 0.1f, 100.0f);
|
||||
glm::mat4 view = glm::lookAt(glm::vec3(0,0,7), glm::vec3(0,0,0), glm::vec3(0,1,0));
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// draw arrow
|
||||
glm::mat4 rotation = glm::mat4(1.0);
|
||||
// GLfloat x = starting_vectors[4*outline_index+2];
|
||||
// GLfloat y = starting_vectors[4*outline_index+3];
|
||||
GLfloat x = starting_vector[2];
|
||||
GLfloat y = starting_vector[3];
|
||||
GLfloat norm = sqrt(x*x + y*y);
|
||||
x *= 0.5/norm;
|
||||
y *= 0.5/norm;
|
||||
rotation[0][0] = x;
|
||||
rotation[0][1] = y;
|
||||
rotation[1][0] = -y;
|
||||
rotation[1][1] = x;
|
||||
// glm::mat4 model = glm::translate(glm::vec3(starting_vectors[4*outline_index], starting_vectors[4*outline_index+1], 0)) * rotation;
|
||||
glm::mat4 model = glm::translate(glm::vec3(starting_vector[0], starting_vector[1], 0)) * rotation;
|
||||
glm::mat4 mvp = proj * view * model;
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "mvp"), 1, GL_FALSE, &mvp[0][0]);
|
||||
glUniform1i(glGetUniformLocation(program, "type"), 2);
|
||||
glBindVertexArray(arrowVA);
|
||||
glDrawArrays(GL_LINES, 0, ARROW_VERTICES);
|
||||
|
||||
// draw outline and path
|
||||
mvp = proj * view;
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "mvp"), 1, GL_FALSE, &mvp[0][0]);
|
||||
glUniform1i(glGetUniformLocation(program, "type"), 1);
|
||||
glBindVertexArray(outlineVA);
|
||||
// glDrawArrays(GL_LINE_STRIP, 0, outline_lengths[outline_index]);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, outline_length);
|
||||
|
||||
glUniform1i(glGetUniformLocation(program, "type"), 0);
|
||||
glUniform1f(glGetUniformLocation(program, "time"), flowtime);
|
||||
glBindVertexArray(pathVA);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, nPathVertices);
|
||||
|
||||
// calculate ball position from flowtime (and flowtime_index), times and path
|
||||
GLfloat pos[3];
|
||||
while(flowtime_index < nPathVertices - 1 && times[flowtime_index+1] < flowtime)
|
||||
flowtime_index++;
|
||||
if(flowtime_index < nPathVertices - 1) {
|
||||
pos[0] = path[2*flowtime_index + 0] + (path[2*flowtime_index + 2] - path[2*flowtime_index + 0])*(flowtime - times[flowtime_index])/(times[flowtime_index+1] - times[flowtime_index]);
|
||||
pos[1] = path[2*flowtime_index + 1] + (path[2*flowtime_index + 3] - path[2*flowtime_index + 1])*(flowtime - times[flowtime_index])/(times[flowtime_index+1] - times[flowtime_index]);
|
||||
pos[2] = 0;
|
||||
} else {
|
||||
pos[0] = path[2*flowtime_index + 0];
|
||||
pos[1] = path[2*flowtime_index + 1];
|
||||
pos[2] = 0;
|
||||
}
|
||||
|
||||
// draw ball
|
||||
glm::mat4 mv = view * glm::translate(glm::vec3(pos[0], pos[1], pos[2])) * glm::scale(glm::vec3(0.05f, 0.05f, 0.05f));
|
||||
mvp = proj * mv;
|
||||
glm::mat3 normal_transform = glm::transpose(glm::inverse(glm::mat3(mv)));
|
||||
|
||||
glUseProgram(program3d);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program3d, "mvp"), 1, GL_FALSE, &mvp[0][0]);
|
||||
glUniformMatrix3fv(glGetUniformLocation(program3d, "normal_transform"), 1, GL_FALSE, &normal_transform[0][0]);
|
||||
glBindVertexArray(ballVA);
|
||||
glDrawElements(GL_TRIANGLES, 6*20*20, GL_UNSIGNED_INT, 0);
|
||||
|
||||
// GLuint pixels[width*height];
|
||||
// glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
|
||||
// fwrite(pixels, sizeof(GLuint), width*height, dumpfile);
|
||||
|
||||
glXSwapBuffers(gl.display, gl.win);
|
||||
}
|
||||
|
||||
int main(int argc, char * const *argv)
|
||||
{
|
||||
int screen = 0;
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "s:n:f:")) != -1) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
screen = atoi(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
outline_index = atoi(optarg) - 1;
|
||||
break;
|
||||
case 'f':
|
||||
strncpy(filename, optarg, 1000);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [-s screen] [-f file]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!initGL(screen, StructureNotifyMask | KeyPressMask | KeyReleaseMask, &gl))
|
||||
return 1;
|
||||
|
||||
init();
|
||||
start_timer();
|
||||
|
||||
while(!checkEvents()) {
|
||||
draw();
|
||||
wait_update_timer();
|
||||
}
|
||||
|
||||
cleanup();
|
||||
destroyGL(&gl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
cube.h
Normal file
37
cube.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef CUBE_H
|
||||
#define CUBE_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
static const GLfloat cubeVertices[] = {
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, 1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static const GLfloat cubeColors[] = {
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 1.0f,
|
||||
1.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static const GLuint cubeFaces[] = {
|
||||
5, 4, 7, 7, 4, 6,
|
||||
1, 5, 3, 3, 5, 7,
|
||||
0, 1, 2, 2, 1, 3,
|
||||
4, 0, 6, 6, 0, 2,
|
||||
7, 6, 3, 3, 6, 2,
|
||||
1, 0, 4, 1, 4, 5,
|
||||
};
|
||||
|
||||
#endif
|
||||
20
fragment.glsl
Normal file
20
fragment.glsl
Normal file
@@ -0,0 +1,20 @@
|
||||
#version 130
|
||||
|
||||
in float normalizedTime;
|
||||
out vec3 color;
|
||||
|
||||
uniform int type;
|
||||
|
||||
void main() {
|
||||
if(type == 0) {
|
||||
if(normalizedTime > 0)
|
||||
discard;
|
||||
color = vec3(1, 0, 0);
|
||||
} else if(type == 1) {
|
||||
color = vec3(0, 0, 0);
|
||||
} else if(type == 2) {
|
||||
color = vec3(0, 0, 1);
|
||||
} else {
|
||||
color = vec3(0, 0, 1);
|
||||
}
|
||||
}
|
||||
12
fragment3d.glsl
Normal file
12
fragment3d.glsl
Normal file
@@ -0,0 +1,12 @@
|
||||
#version 130
|
||||
|
||||
in vec3 normal;
|
||||
out vec3 color;
|
||||
|
||||
uniform int type;
|
||||
|
||||
void main() {
|
||||
color = clamp(dot(normal, vec3(-1, 0,0)), 0, 1)*vec3(1, 1, 1) + clamp(dot(normal, vec3(0, 1, 0)), 0, 1)*vec3(1, 1, 1) + 0.1;
|
||||
// color = vec3(1,1,1);
|
||||
// color = normal;
|
||||
}
|
||||
176
gl3.c
Normal file
176
gl3.c
Normal file
@@ -0,0 +1,176 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "gl3.h"
|
||||
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, bool, const int*);
|
||||
|
||||
#define ERROR(condition, msg, ...) if(condition){fprintf(stderr, msg, ##__VA_ARGS__); return false;}
|
||||
|
||||
bool initGL(int screen, int mask, GLInfo *glinfo)
|
||||
{
|
||||
glinfo->display = XOpenDisplay(NULL);
|
||||
ERROR(!glinfo->display, "Failed to open X display\n");
|
||||
|
||||
// check GLX version >= 1.3
|
||||
int glx_major, glx_minor;
|
||||
ERROR(!glXQueryVersion(glinfo->display, &glx_major, &glx_minor), "Could not query GLX version\n");
|
||||
ERROR(glx_major == 1 && glx_minor < 3 || glx_major < 1, "Invalid GLX version\n");
|
||||
|
||||
// Let GLX suggest a frame buffer config with a minimum feature set
|
||||
static int visual_attribs[] = {
|
||||
GLX_X_RENDERABLE , True,
|
||||
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE , GLX_RGBA_BIT,
|
||||
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
|
||||
GLX_RED_SIZE , 8,
|
||||
GLX_GREEN_SIZE , 8,
|
||||
GLX_BLUE_SIZE , 8,
|
||||
GLX_ALPHA_SIZE , 8,
|
||||
GLX_DEPTH_SIZE , 24,
|
||||
GLX_STENCIL_SIZE , 8,
|
||||
GLX_DOUBLEBUFFER , True,
|
||||
None
|
||||
};
|
||||
int fbcount;
|
||||
GLXFBConfig *fbclist = glXChooseFBConfig(glinfo->display, screen, visual_attribs, &fbcount);
|
||||
ERROR(!fbclist, "Failed to retrieve a framebuffer config\n");
|
||||
GLXFBConfig fbc = fbclist[0];
|
||||
XFree(fbclist);
|
||||
|
||||
// Create X Window
|
||||
XVisualInfo *vi = glXGetVisualFromFBConfig(glinfo->display, fbc);
|
||||
ERROR(!vi, "Failed to get visual from framebuffer config\n");
|
||||
XSetWindowAttributes swa;
|
||||
glinfo->cmap = XCreateColormap(glinfo->display, RootWindow(glinfo->display, vi->screen), vi->visual, AllocNone);
|
||||
swa.colormap = glinfo->cmap;
|
||||
swa.background_pixmap = None;
|
||||
swa.border_pixel = 0;
|
||||
swa.event_mask = mask;
|
||||
glinfo->win = XCreateWindow(glinfo->display, RootWindow(glinfo->display, vi->screen), 0, 0, 100, 100, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
|
||||
ERROR(!glinfo->win, "Failed to create window.\n");
|
||||
XFree(vi);
|
||||
|
||||
// Print GLX Extensions
|
||||
// const char *glxExts = glXQueryExtensionsString(glinfo->display, screen);
|
||||
// printf("%s\n", glxExts);
|
||||
|
||||
// Create GLX context
|
||||
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
|
||||
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");
|
||||
ERROR(!glXCreateContextAttribsARB, "GLX_ARB_create_context is not supported\n");
|
||||
int context_attribs[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
None
|
||||
};
|
||||
glinfo->ctx = glXCreateContextAttribsARB(glinfo->display, fbc, 0, True, context_attribs);
|
||||
ERROR(!glXIsDirect(glinfo->display, glinfo->ctx), "GLX context is not direct\n");
|
||||
|
||||
XMapWindow(glinfo->display, glinfo->win);
|
||||
glXMakeCurrent(glinfo->display, glinfo->win, glinfo->ctx);
|
||||
|
||||
GLenum result = glewInit();
|
||||
ERROR(result != GLEW_OK, "Failed to initialize GLEW: %s\n", glewGetErrorString(result));
|
||||
|
||||
char name[] = "Billiards";
|
||||
XClassHint *classHint = XAllocClassHint();
|
||||
classHint->res_name = classHint->res_class = name;
|
||||
XSetClassHint(glinfo->display, glinfo->win, classHint);
|
||||
XStoreName(glinfo->display, glinfo->win, name);
|
||||
XFree(classHint);
|
||||
|
||||
glinfo->wm_delete_window = XInternAtom(glinfo->display, "WM_DELETE_WINDOW", false);
|
||||
glinfo->wm_protocols = XInternAtom(glinfo->display, "WM_PROTOCOLS", false);
|
||||
XSetWMProtocols(glinfo->display, glinfo->win, &glinfo->wm_delete_window, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void destroyGL(GLInfo *glinfo)
|
||||
{
|
||||
glXMakeCurrent(glinfo->display, None, 0);
|
||||
glXDestroyContext(glinfo->display, glinfo->ctx);
|
||||
XDestroyWindow(glinfo->display, glinfo->win);
|
||||
XFreeColormap(glinfo->display, glinfo->cmap);
|
||||
XCloseDisplay(glinfo->display);
|
||||
}
|
||||
|
||||
bool initShaders(const char *vertexShaderPath, const char *fragmentShaderPath, GLuint *program)
|
||||
{
|
||||
GLuint vertexShader, fragmentShader;
|
||||
GLint result;
|
||||
int infoLogLength;
|
||||
char *infoLog;
|
||||
FILE *file;
|
||||
struct stat filestat;
|
||||
char *vertexShaderSrc, *fragmentShaderSrc;
|
||||
|
||||
// load vertex shader
|
||||
file = fopen(vertexShaderPath, "r");
|
||||
ERROR(!file, "Could not open file %s\n", vertexShaderPath);
|
||||
fstat(fileno(file), &filestat);
|
||||
ERROR(filestat.st_size > 10000000, "Unreasonably large shader file\n");
|
||||
vertexShaderSrc = (char*)malloc(filestat.st_size + 1);
|
||||
vertexShaderSrc[filestat.st_size] = 0; // just for safety
|
||||
fread(vertexShaderSrc, 1, filestat.st_size, file);
|
||||
fclose(file);
|
||||
|
||||
// load framgent shader
|
||||
file = fopen(fragmentShaderPath, "r");
|
||||
ERROR(!file, "Could not open file %s\n", fragmentShaderPath);
|
||||
fstat(fileno(file), &filestat);
|
||||
ERROR(filestat.st_size > 10000000, "Unreasonably large shader file\n");
|
||||
fragmentShaderSrc = (char*)malloc(filestat.st_size + 1);
|
||||
fragmentShaderSrc[filestat.st_size] = 0; // just for safety
|
||||
fread(fragmentShaderSrc, 1, filestat.st_size, file);
|
||||
fclose(file);
|
||||
|
||||
// compile vertex shader
|
||||
vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL);
|
||||
glCompileShader(vertexShader);
|
||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &result);
|
||||
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
infoLog = (char*)malloc(infoLogLength+1);
|
||||
glGetShaderInfoLog(vertexShader, infoLogLength, NULL, infoLog);
|
||||
ERROR(!result, "Vertex shader compile error: %s\n", infoLog);
|
||||
free(infoLog);
|
||||
|
||||
// compile fragment shader
|
||||
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &result);
|
||||
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
infoLog = (char*)malloc(infoLogLength+1);
|
||||
glGetShaderInfoLog(fragmentShader, infoLogLength, NULL, infoLog);
|
||||
ERROR(!result, "Fragment shader compile error: %s\n", infoLog);
|
||||
free(infoLog);
|
||||
|
||||
// link program
|
||||
*program = glCreateProgram();
|
||||
glAttachShader(*program, vertexShader);
|
||||
glAttachShader(*program, fragmentShader);
|
||||
glLinkProgram(*program);
|
||||
glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
glGetShaderiv(*program, GL_LINK_STATUS, &result);
|
||||
glGetShaderiv(*program, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
infoLog = (char*)malloc(infoLogLength+1);
|
||||
glGetProgramInfoLog(*program, infoLogLength, NULL, infoLog);
|
||||
ERROR(!result, "Shader linking error: %s\n", infoLog);
|
||||
free(infoLog);
|
||||
|
||||
glDetachShader(*program, vertexShader);
|
||||
glDetachShader(*program, fragmentShader);
|
||||
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
free(vertexShaderSrc);
|
||||
free(fragmentShaderSrc);
|
||||
|
||||
return true;
|
||||
}
|
||||
34
gl3.h
Normal file
34
gl3.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef GL3_H
|
||||
#define GL3_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
typedef struct {
|
||||
Display *display;
|
||||
Window win;
|
||||
Colormap cmap;
|
||||
GLXContext ctx;
|
||||
Atom wm_protocols;
|
||||
Atom wm_delete_window;
|
||||
} GLInfo;
|
||||
|
||||
bool initGL(int screen, int mask, GLInfo *glinfo);
|
||||
void destroyGL(GLInfo *glinfo);
|
||||
bool initShaders(const char *vertexShaderSrc, const char *fragmentShaderSrc, GLuint *program);
|
||||
|
||||
static Bool alwaysTruePredicate(Display *display, XEvent *event, XPointer arg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
81
sphere.h
Normal file
81
sphere.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef SPHERE_H
|
||||
#define SPHERE_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
void generateSphere(int w, int h, GLuint *VA)
|
||||
{
|
||||
GLuint VB, NB, IB;
|
||||
GLfloat vertices[3*w*h + 6];
|
||||
GLfloat normals[3*w*h + 6];
|
||||
GLuint indices[6*w*h];
|
||||
|
||||
memset(vertices, 0, sizeof(vertices));
|
||||
memset(normals, 0, sizeof(normals));
|
||||
memset(indices, 0, sizeof(indices));
|
||||
|
||||
for(int i = 0; i < h; i++)
|
||||
for(int j = 0; j < w; j++) {
|
||||
vertices[3*i*w + 3*j + 0] = normals[3*i*w + 3*j + 0] = sin((float)(i+1.0)/(h+1.0)*M_PI) * cos((float)j/w*2*M_PI);
|
||||
vertices[3*i*w + 3*j + 1] = normals[3*i*w + 3*j + 1] = sin((float)(i+1.0)/(h+1.0)*M_PI) * sin((float)j/w*2*M_PI);
|
||||
vertices[3*i*w + 3*j + 2] = normals[3*i*w + 3*j + 2] = cos((float)(i+1.0)/(h+1.0)*M_PI);
|
||||
}
|
||||
|
||||
vertices[3*w*h + 0] = normals[3*w*h + 0] = 0;
|
||||
vertices[3*w*h + 1] = normals[3*w*h + 1] = 0;
|
||||
vertices[3*w*h + 2] = normals[3*w*h + 2] = 1;
|
||||
vertices[3*w*h + 3] = normals[3*w*h + 3] = 0;
|
||||
vertices[3*w*h + 4] = normals[3*w*h + 4] = 0;
|
||||
vertices[3*w*h + 5] = normals[3*w*h + 5] = -1;
|
||||
|
||||
for(int i = 0; i < h - 1; i++) {
|
||||
for(int j = 0; j < w - 1; j++) {
|
||||
indices[6*i*w + 6*j] = i*w + j;
|
||||
indices[6*i*w + 6*j + 1] = i*w + j + 1;
|
||||
indices[6*i*w + 6*j + 2] = i*w + j + w;
|
||||
indices[6*i*w + 6*j + 3] = i*w + j + 1;
|
||||
indices[6*i*w + 6*j + 4] = i*w + j + w + 1;
|
||||
indices[6*i*w + 6*j + 5] = i*w + j + w;
|
||||
}
|
||||
indices[6*i*w + 6*w - 6] = i*w + w - 1;
|
||||
indices[6*i*w + 6*w - 5] = i*w;
|
||||
indices[6*i*w + 6*w - 4] = i*w + 2*w - 1;
|
||||
indices[6*i*w + 6*w - 3] = i*w;
|
||||
indices[6*i*w + 6*w - 2] = i*w + w;
|
||||
indices[6*i*w + 6*w - 1] = i*w + 2*w - 1;
|
||||
}
|
||||
|
||||
for(int i = 0; i < w - 1; i++) {
|
||||
indices[6*h*w - 6*w + 6*i + 0] = i;
|
||||
indices[6*h*w - 6*w + 6*i + 1] = w*h;
|
||||
indices[6*h*w - 6*w + 6*i + 2] = i+1;
|
||||
indices[6*h*w - 6*w + 6*i + 3] = w*h - w + i + 1;
|
||||
indices[6*h*w - 6*w + 6*i + 4] = w*h + 1;
|
||||
indices[6*h*w - 6*w + 6*i + 5] = w*h - w + i;
|
||||
}
|
||||
|
||||
indices[6*h*w - 6 + 0] = w - 1;
|
||||
indices[6*h*w - 6 + 1] = w*h;
|
||||
indices[6*h*w - 6 + 2] = 0;
|
||||
|
||||
glGenVertexArrays(1, VA);
|
||||
glBindVertexArray(*VA);
|
||||
|
||||
glGenBuffers(1, &VB);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VB);
|
||||
glBufferData(GL_ARRAY_BUFFER, (3*w*h+6)*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glGenBuffers(1, &NB);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, NB);
|
||||
glBufferData(GL_ARRAY_BUFFER, (3*w*h+6)*sizeof(GLfloat), normals, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glGenBuffers(1, &IB);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*w*h*sizeof(GLuint), indices, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
#endif
|
||||
4
tables/dreieck6-dicht
Normal file
4
tables/dreieck6-dicht
Normal file
@@ -0,0 +1,4 @@
|
||||
0 -0.5 5 5
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1.309401076758
|
||||
4
tables/dreieck6-periodisch
Normal file
4
tables/dreieck6-periodisch
Normal file
@@ -0,0 +1,4 @@
|
||||
0 -0.5 1 4.33012701892
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1.309401076758
|
||||
4
tables/dreieck6-senkrecht
Normal file
4
tables/dreieck6-senkrecht
Normal file
@@ -0,0 +1,4 @@
|
||||
0.3 -0.3 0 -1.000000
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1.309401076758
|
||||
4
tables/dreieck8-periodisch
Normal file
4
tables/dreieck8-periodisch
Normal file
@@ -0,0 +1,4 @@
|
||||
0.4 -0.7 -0.5 2.41421356237
|
||||
-2 -1
|
||||
2 -1
|
||||
2 0.656854249492
|
||||
13
tables/hantel
Normal file
13
tables/hantel
Normal file
@@ -0,0 +1,13 @@
|
||||
-1.5 -0.1 1 2.12345567899
|
||||
-2 -1
|
||||
-1 -1
|
||||
-1 -0.05
|
||||
1 -0.05
|
||||
1 -1
|
||||
2 -1
|
||||
2 1
|
||||
1 1
|
||||
1 0.05
|
||||
-1 0.05
|
||||
-1 1
|
||||
-2 1
|
||||
7
tables/l-dicht
Normal file
7
tables/l-dicht
Normal file
@@ -0,0 +1,7 @@
|
||||
0.2 0.5 0.5 -0.5 # Kommentar
|
||||
1 1
|
||||
1 0
|
||||
2.276394569 0
|
||||
2.276394569 -1
|
||||
-1 -1
|
||||
-1 1
|
||||
7
tables/l-periodisch
Normal file
7
tables/l-periodisch
Normal file
@@ -0,0 +1,7 @@
|
||||
0.7 0.5 0.5 -0.5 # Kommentar
|
||||
1 1
|
||||
1 0
|
||||
2.276394569 0
|
||||
2.276394569 -1
|
||||
-1 -1
|
||||
-1 1
|
||||
7
tables/nichtkonvex
Normal file
7
tables/nichtkonvex
Normal file
@@ -0,0 +1,7 @@
|
||||
0.5 0 0 -1.5
|
||||
0 -1
|
||||
-0.5 1.8356409098088555
|
||||
0.5 0.6438873172146455
|
||||
1 1.0634371328032852
|
||||
1.5 0.7133333636984291
|
||||
0.5502838083459437 -1
|
||||
7
tables/nichtkonvex-2
Normal file
7
tables/nichtkonvex-2
Normal file
@@ -0,0 +1,7 @@
|
||||
0.3 0 0 -1.5
|
||||
0 -1
|
||||
-0.5 1.8356409098088555
|
||||
0.5 0.6438873172146455
|
||||
1 1.0634371328032852
|
||||
1.5 0.7133333636984291
|
||||
0.5502838083459437 -1
|
||||
4
tables/orthogonal
Normal file
4
tables/orthogonal
Normal file
@@ -0,0 +1,4 @@
|
||||
1 0 0 -1
|
||||
-2 -1
|
||||
2 -1
|
||||
0.33512798812026023 1.8836429126751244 # Dreieck mit (51,60,69)-Grad Winkel
|
||||
5
tables/rechteck-dicht
Normal file
5
tables/rechteck-dicht
Normal file
@@ -0,0 +1,5 @@
|
||||
-1 0 10 7.34819206
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1
|
||||
-2 1
|
||||
5
tables/rechteck-horizontal
Normal file
5
tables/rechteck-horizontal
Normal file
@@ -0,0 +1,5 @@
|
||||
-1 0 2 0
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1
|
||||
-2 1
|
||||
5
tables/rechteck-periodisch-kurz
Normal file
5
tables/rechteck-periodisch-kurz
Normal file
@@ -0,0 +1,5 @@
|
||||
-1 0 1.6 2.4
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1
|
||||
-2 1
|
||||
5
tables/rechteck-periodisch-lang
Normal file
5
tables/rechteck-periodisch-lang
Normal file
@@ -0,0 +1,5 @@
|
||||
-1 0 7.04 8
|
||||
-2 -1
|
||||
2 -1
|
||||
2 1
|
||||
-2 1
|
||||
7
tables/sanduhr
Normal file
7
tables/sanduhr
Normal file
@@ -0,0 +1,7 @@
|
||||
-0.2 -0.1 2 1
|
||||
-1.2 1
|
||||
1.2 1
|
||||
0.2 0
|
||||
1.2 -1
|
||||
-1.2 -1
|
||||
-0.2 0
|
||||
9
tables/stern
Normal file
9
tables/stern
Normal file
@@ -0,0 +1,9 @@
|
||||
0.2 0.5 0.5 -0.5
|
||||
0 1.5
|
||||
0.5 0.5
|
||||
1.5 0
|
||||
0.5 -0.5
|
||||
0 -1.5
|
||||
-0.5 -0.5
|
||||
-1.5 0
|
||||
-0.5 0.5
|
||||
10
tables/stern-rational
Normal file
10
tables/stern-rational
Normal file
@@ -0,0 +1,10 @@
|
||||
0.5 0 0.5 -0.8660254037844386
|
||||
0 1.3660254037844386
|
||||
0.5 0.5
|
||||
1.3660254037844386 0
|
||||
0.5 -0.5
|
||||
0 -1.3660254037844386
|
||||
-0.5 -0.5
|
||||
-1.3660254037844386 0
|
||||
-0.5 0.5
|
||||
|
||||
7
tables/test
Normal file
7
tables/test
Normal file
@@ -0,0 +1,7 @@
|
||||
0.1 0.5 0 -1.5
|
||||
0 -1
|
||||
-0.5 1.8356409098088555
|
||||
0.5 0.6438873172146455
|
||||
1 1.0634371328032852
|
||||
1.5 0.7133333636984291
|
||||
0.5502838083459437 -1
|
||||
6
tables/zahn
Normal file
6
tables/zahn
Normal file
@@ -0,0 +1,6 @@
|
||||
-0.7 0.3 -1 -1
|
||||
-1 -1
|
||||
1 -1
|
||||
1 1
|
||||
0 0
|
||||
-1 1
|
||||
14
vertex.glsl
Normal file
14
vertex.glsl
Normal file
@@ -0,0 +1,14 @@
|
||||
#version 130
|
||||
|
||||
in vec2 pos;
|
||||
in float vertexTime;
|
||||
|
||||
out float normalizedTime;
|
||||
|
||||
uniform float time;
|
||||
uniform mat4 mvp;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(pos.x, pos.y, 0, 1);
|
||||
normalizedTime = vertexTime - time;
|
||||
}
|
||||
14
vertex3d.glsl
Normal file
14
vertex3d.glsl
Normal file
@@ -0,0 +1,14 @@
|
||||
#version 130
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 vertexNormal;
|
||||
|
||||
out vec3 normal;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform mat3 normal_transform;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(pos, 1);
|
||||
normal = normalize(normal_transform * vertexNormal);
|
||||
}
|
||||
Reference in New Issue
Block a user