Created
February 26, 2015 16:32
-
-
Save progschj/0aabdf3e02bbfc913b86 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MATH_UTIL_H | |
#define MATH_UTIL_H | |
#include <math.h> | |
#include <float.h> | |
static const float PI = 3.14159265358979323846f; | |
static inline float dot3(const float *a, const float *b) { | |
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; | |
} | |
static inline float dist3(const float *a, const float *b) { | |
float dx = a[0] - b[0]; | |
float dy = a[1] - b[1]; | |
float dz = a[2] - b[2]; | |
return sqrtf(dx*dx + dy*dy + dz*dz); | |
} | |
static inline float dot4(const float *a, const float *b) { | |
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; | |
} | |
static inline float* cross(float *dst, const float *a, const float *b) { | |
dst[0] = a[1]*b[2] - a[2]*b[1]; | |
dst[1] = a[2]*b[0] - a[0]*b[2]; | |
dst[2] = a[0]*b[1] - a[1]*b[0]; | |
return dst; | |
} | |
static inline float triple_product(const float *a, const float *b, const float *c) { | |
return (a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1]) | |
- (a[0]*b[2]*c[1] + a[1]*b[0]*c[2] + a[2]*b[1]*c[0]); | |
} | |
// annoyingly fminf/fmaxf handle NaNs differently than sse and this | |
// ternary versions compile to single instructions | |
static inline float fast_minf(float a, float b) { | |
return a<b?a:b; | |
} | |
static inline float fast_maxf(float a, float b) { | |
return a>b?a:b; | |
} | |
static inline float clamp(float x, float low, float high) { | |
return fast_minf(high, fast_maxf(low, x)); | |
} | |
float smoothstep(float x) { | |
x = clamp(x, 0.0f, 1.0f); | |
return (x*x)*(3.0f - 2.0f*x); | |
} | |
static inline void cpyTransform(float *A, const float *B) { | |
for(int i = 0;i<16;++i) { | |
A[i] = B[i]; | |
} | |
} | |
static inline void transpose(float *A, const float *B) { | |
for(int i = 0;i<4;++i) { | |
for(int j = 0;j<4;++j) { | |
A[i+4*j] = B[j+4*i]; | |
} | |
} | |
} | |
static inline void normalize(float *x, float *y, float *z) { | |
float il = 1.0/sqrt(*x * *x + *y * *y + *z * *z); | |
*x *= il; *y *= il; *z *= il; | |
} | |
static inline void mul3(float *A, float *B, float *C) { | |
for(int i = 0;i<4;++i) { | |
for(int j = 0;j<4;++j) { | |
float dot = 0; | |
for(int k = 0;k<4;++k) { | |
dot += B[i+4*k]*C[k+4*j]; | |
} | |
A[i+4*j] = dot; | |
} | |
} | |
} | |
static inline void mul2(float *A, float *C) { | |
float tmp[16]; | |
cpyTransform(tmp, A); | |
mul3(A,tmp,C); | |
} | |
static inline void transpose_mul3(float *A, float *B, float *C) { | |
for(int i = 0;i<4;++i) { | |
for(int j = 0;j<4;++j) { | |
float dot = 0; | |
for(int k = 0;k<4;++k) { | |
dot += B[i+4*k]*C[j+4*k]; | |
} | |
A[i+4*j] = dot; | |
} | |
} | |
} | |
static inline void transpose_mul2(float *A, float *C) { | |
float tmp[16]; | |
cpyTransform(tmp, A); | |
transpose_mul3(A,tmp,C); | |
} | |
static inline void setIdentity(float *A) { | |
A[ 0] = 1; A[ 4] = 0; A[ 8] = 0; A[12] = 0; | |
A[ 1] = 0; A[ 5] = 1; A[ 9] = 0; A[13] = 0; | |
A[ 2] = 0; A[ 6] = 0; A[10] = 1; A[14] = 0; | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 1; | |
} | |
static inline void setTranslate(float *A, float x, float y, float z) { | |
A[ 0] = 1; A[ 4] = 0; A[ 8] = 0; A[12] = x; | |
A[ 1] = 0; A[ 5] = 1; A[ 9] = 0; A[13] = y; | |
A[ 2] = 0; A[ 6] = 0; A[10] = 1; A[14] = z; | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 1; | |
} | |
static inline void mulTranslate(float *A, float x, float y, float z) { | |
float tmp[16]; | |
setTranslate(tmp, x, y, z); | |
mul2(A, tmp); | |
} | |
static inline void setScale(float *A, float x, float y, float z) { | |
A[ 0] = x; A[ 4] = 0; A[ 8] = 0; A[12] = 0; | |
A[ 1] = 0; A[ 5] = y; A[ 9] = 0; A[13] = 0; | |
A[ 2] = 0; A[ 6] = 0; A[10] = z; A[14] = 0; | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 1; | |
} | |
static inline void mulScale(float *A, float x, float y, float z) { | |
float tmp[16]; | |
setScale(tmp, x, y, z); | |
mul2(A, tmp); | |
} | |
static inline void setRotateFromVectors(float *A, const float *u, const float *v) { | |
float lu2 = u[0]*u[0] + u[1]*u[1] + u[2]*u[2]; | |
float lv2 = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; | |
if(lu2*lv2<1.e-10) { | |
setIdentity(A); | |
return; | |
} | |
float scaler = 1.0f/sqrtf(lu2*lv2); | |
float c = (u[0]*v[0] + u[1]*v[1] + u[2]*v[2])*scaler; | |
float x = (v[1]*u[2] - v[2]*u[1])*scaler; | |
float y = (v[2]*u[0] - v[0]*u[2])*scaler; | |
float z = (v[0]*u[1] - v[1]*u[0])*scaler; | |
float s2 = x*x + y*y + z*z; | |
if(s2<1.e-10) { | |
setIdentity(A); | |
return; | |
} | |
float cs2 = (1.0f-c)/s2; | |
A[ 0] = c+x*x*cs2; A[ 4] = x*y*cs2+z; A[ 8] = x*z*cs2-y; A[12] = 0; | |
A[ 1] = x*y*cs2-z; A[ 5] = c+y*y*cs2; A[ 9] = y*z*cs2+x; A[13] = 0; | |
A[ 2] = x*z*cs2+y; A[ 6] = y*z*cs2-x; A[10] = c+z*z*cs2; A[14] = 0; | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 1; | |
} | |
static inline void mulRotateFromVectors(float *A, const float *u, const float *v) { | |
float tmp[16]; | |
setRotateFromVectors(tmp, u, v); | |
mul2(A, tmp); | |
} | |
static inline void setRotate(float *A, float x, float y, float z, float angle) { | |
float l = 1.0f/sqrtf(x*x + y*y + z*z); | |
x *= l; y *= l; z *= l; | |
float c = cosf(angle); | |
float s = sinf(angle); | |
A[ 0] = x*x*(1.0f-c)+c; A[ 4] = x*y*(1.0f-c)+z*s; A[ 8] = x*z*(1.0f-c)-y*s; A[12] = 0; | |
A[ 1] = x*y*(1.0f-c)-z*s; A[ 5] = y*y*(1.0f-c)+c; A[ 9] = y*z*(1.0f-c)+x*s; A[13] = 0; | |
A[ 2] = x*z*(1.0f-c)+y*s; A[ 6] = y*z*(1.0f-c)-x*s; A[10] = z*z*(1.0f-c)+c; A[14] = 0; | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 1; | |
} | |
static inline void mulRotate(float *A, float x, float y, float z, float angle) { | |
float tmp[16]; | |
setRotate(tmp, x, y, z, angle); | |
mul2(A, tmp); | |
} | |
static inline void setFrustum(float *A, float left, float right, float top, float bottom, float near, float far) { | |
A[ 0] = 2.0f*near/(right-left); A[ 4] = 0; A[ 8] = (right+left)/(right-left); A[12] = 0; | |
A[ 1] = 0; A[ 5] = 2.0f*near/(top-bottom); A[ 9] = (top+bottom)/(top-bottom); A[13] = 0; | |
A[ 2] = 0; A[ 6] = 0; A[10] = (far+near)/(near-far); A[14] = 2*far*near/(near-far); | |
A[ 3] = 0; A[ 7] = 0; A[11] = -1; A[15] = 0; | |
} | |
static inline void setInverseFrustum(float *A, float left, float right, float top, float bottom, float near, float far) { | |
A[ 0] = (right-left)/(2.0f*near); A[ 4] = 0; A[8] = 0; A[12] = (right+left)/(2*near); | |
A[ 1] = 0; A[ 5] = (top-bottom)/(2.0f*near); A[9] = 0; A[13] = (top+bottom)/(2*near); | |
A[ 2] = 0; A[ 6] = 0; A[10] = 0; A[14] = -1; | |
A[ 3] = 0; A[ 7] = 0; A[11] = (near-far)/(2*near*far); A[15] = (near+far)/(2*near*far); | |
} | |
static inline void mulInverseFrustum(float *A, float left, float right, float top, float bottom, float near, float far) { | |
float tmp[16]; | |
setInverseFrustum(tmp, left, right, top, bottom, near, far); | |
mul2(A, tmp); | |
} | |
static inline void setOrtho(float *A, float left, float right, float top, float bottom, float near, float far) { | |
A[ 0] = 2.0f/(right-left); A[ 4] = 0; A[ 8] = 0; A[12] = (left+right)/(left-right); | |
A[ 1] = 0; A[ 5] = 2.0f/(top-bottom); A[ 9] = 0; A[13] = (bottom+top)/(bottom-top); | |
A[ 2] = 0; A[ 6] = 0; A[10] = 2.0f/(near-far); A[14] = (near+far)/(near-far); | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 1; | |
} | |
static inline void transformVector(float *y, const float *A, const float *x) { | |
float tmp[4]; | |
for(int i = 0;i<4;++i) { | |
tmp[i] = A[0+i]*x[0] + A[4+i]*x[1] + A[8+i]*x[2] + A[12+i]*x[3]; | |
} | |
for(int i = 0;i<4;++i) { | |
y[i] = tmp[i]; | |
} | |
} | |
static inline void transformVector3(float *y, const float *A, const float *x) { | |
float tmp[4]; | |
for(int i = 0;i<4;++i) { | |
tmp[i] = A[0+i]*x[0] + A[4+i]*x[1] + A[8+i]*x[2] + A[12+i]; | |
} | |
float w = 1.0f/tmp[3]; | |
for(int i = 0;i<3;++i) { | |
y[i] = tmp[i]*w; | |
} | |
} | |
static inline void affineTransformVector3(float *y, const float *A, const float *x) { | |
float tmp[3]; | |
for(int i = 0;i<3;++i) { | |
tmp[i] = A[0+i]*x[0] + A[4+i]*x[1] + A[8+i]*x[2] + A[12+i]; | |
} | |
for(int i = 0;i<3;++i) { | |
y[i] = tmp[i]; | |
} | |
} | |
static inline void transposeTransformVector3(float *y, const float *A, const float *x) { | |
float tmp[4]; | |
for(int i = 0;i<4;++i) { | |
tmp[i] = A[4*i+0]*x[0] + A[4*i+1]*x[1] + A[4*i+2]*x[2] + A[4*i+3]; | |
} | |
float w = 1.0f/tmp[3]; | |
for(int i = 0;i<3;++i) { | |
y[i] = tmp[i]*w; | |
} | |
} | |
static inline void setRotateDerivative(float *A, float x, float y, float z, float angle) { | |
float l = 1.0f/sqrtf(x*x + y*y + z*z); | |
x *= l; y *= l; z *= l; | |
float c = -sinf(angle); | |
float s = cosf(angle); | |
A[ 0] = c+x*x*(-c); A[ 4] = x*y*(-c)+z*s; A[ 8] = x*z*(-c)-y*s; A[12] = 0; | |
A[ 1] = x*y*(-c)-z*s; A[ 5] = c+y*y*(-c); A[ 9] = y*z*(-c)+x*s; A[13] = 0; | |
A[ 2] = x*z*(-c)+y*s; A[ 6] = y*z*(-c)-x*s; A[10] = c+z*z*(-c); A[14] = 0; | |
A[ 3] = 0; A[ 7] = 0; A[11] = 0; A[15] = 0; | |
} | |
static inline void mulRotateDerivative(float *A, float x, float y, float z, float angle) { | |
float tmp[16]; | |
setRotateDerivative(tmp, x, y, z, angle); | |
mul2(A, tmp); | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SHADER_BUILD_H | |
#define SHADER_BUILD_H | |
#include <gl_core_3_3.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
static int check_shader_compile_status(GLuint obj) { | |
GLint status; | |
glGetShaderiv(obj, GL_COMPILE_STATUS, &status); | |
if(status == GL_FALSE) { | |
GLint length; | |
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &length); | |
char *log = (char*)malloc(length); | |
glGetShaderInfoLog(obj, length, &length, &log[0]); | |
fprintf(stderr, "%s", log); | |
free(log); | |
return 0; | |
} | |
return 1; | |
} | |
static int check_program_link_status(GLuint obj) { | |
GLint status; | |
glGetProgramiv(obj, GL_LINK_STATUS, &status); | |
if(status == GL_FALSE) { | |
GLint length; | |
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &length); | |
char *log = (char*)malloc(length); | |
glGetProgramInfoLog(obj, length, &length, &log[0]); | |
fprintf(stderr, "%s", log); | |
free(log); | |
return 0; | |
} | |
return 1; | |
} | |
typedef struct shader_source_t { | |
GLenum type; | |
const char *source; | |
} shader_source; | |
static GLuint shader_build(const shader_source *sources) { | |
GLuint shader_program = glCreateProgram(); | |
for(;sources->source != NULL;++sources) { | |
GLuint shader = glCreateShader(sources->type); | |
glShaderSource(shader, 1, &sources->source, 0); | |
glCompileShader(shader); | |
if(!check_shader_compile_status(shader)) { | |
return 0; | |
} | |
glAttachShader(shader_program, shader); | |
glDeleteShader(shader); | |
} | |
glLinkProgram(shader_program); | |
if(!check_program_link_status(shader_program)) { | |
return 0; | |
} | |
return shader_program; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment