我正在进行软体模拟。我试图用c ++中的OpenGL来做。但是,我有一些问题,我在互联网上找不到任何东西。我正在使用质量弹簧法 首先,我在2d完成了模拟,它没有问题。有一个代码可用。但是,当我直接将它应用到3d时,它没有,我找不到问题。是UV球吗?人们正在使用二十面体球,我知道,但是,我无法弄清楚如何初始化弹簧。由于弹簧的方向很重要;当我在2d改变方向时,它不起作用。或者它可能是紫外线球体中弹簧的方向。另外,我怀疑力累积和欧拉积分器。这可能是正常的,但是,在我施加压力的第一部分中,模拟不起作用。所以可以肯定的是,我将法线改为从原点到弹簧中点的矢量,因为球最初位于原点,但再次失败。自从我上了物理课程以来已经有一段时间了。我把代码放在下面,我知道它效率不高而且编写得不好,但我对模拟工作很感兴趣,但不管我感谢所有评论。无论如何,感谢阅读迄今为止。祝大家一切顺利。
质点初始化
void
InitPoints()
{
float dxy = (360.0 * DegreesToRadians) / CircleVertices;
float dz = (360.0 * DegreesToRadians) / NumCirclesx2;
points[0] = vec4( 0.0, 1.0, 0.0, 1.0);
for(int j=1;j<NumCirclesx2/2;j++){
for(int i=0;i<CircleVertices;i++){
points[(j-1)*CircleVertices + i+1] = vec4(BALLRADIUS * sin(i * dxy)*sin(j*dz), BALLRADIUS *cos(j*dz), BALLRADIUS *cos(i * dxy)*sin(j*dz), 1.0);
}
}
points[NumVertices-1] = vec4( 0.0, -1.0, 0.0, 1.0);
}
弹簧初始化
void
InitEdges(){
int k = 0;
for(int j=0;j<CircleVertices;j++){
edges[4*j] = points[1+j];
edges[4*j+1] = points[0];
spring[k].p1 = 0;
spring[k].p2 = 1+j;
spring[k].index = 4*j;
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
edges[4*j+2] = points[(1+j)];
spring[k].p1 = 1+j;
spring[k].index = 4*j+2;
if(2+j == CircleVertices){
edges[4*j+3] = points[(2+j)];
spring[k].p2 = 2+j;
}
else{
edges[4*j+3] = points[(2+j)%(CircleVertices)];
spring[k].p2 = (2+j)%(CircleVertices);
}
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
}
for(int i=1;i<NumCirclesx2/2-1;i++){
for(int j=0;j<CircleVertices;j++){
edges[i*CircleVertices*4+4*j] = points[i*CircleVertices+1+j];
edges[i*CircleVertices*4+4*j+1] = points[(i-1)*CircleVertices+1+j];
spring[k].p1 = i*CircleVertices+1+j;
spring[k].p2 = (i-1)*CircleVertices+1+j;
spring[k].index = i*CircleVertices*4+4*j;
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
edges[i*CircleVertices*4+4*j+2] = points[i*CircleVertices+1+j];
spring[k].p1 = i*CircleVertices+1+j;
spring[k].index = i*CircleVertices*4+4*j+2;
if(2+j == CircleVertices){
edges[i*CircleVertices*4+4*j+3] = points[i*CircleVertices+(2+j)];
spring[k].p2 = i*CircleVertices+(2+j);
}
else {
edges[i*CircleVertices*4+4*j+3] = points[i*CircleVertices+(2+j)%CircleVertices];
spring[k].p2 = i*CircleVertices+(2+j)%CircleVertices;
}
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
}
}
for(int j=0;j<CircleVertices;j++){
edges[(NumCirclesx2/2-1)*CircleVertices*4+2*j] = points[NumVertices-1];
edges[(NumCirclesx2/2-1)*CircleVertices*4+2*j+1] = points[(NumCirclesx2/2-1)*CircleVertices-CircleVertices+j+1];
spring[k].p1 = (NumCirclesx2/2-1)*CircleVertices-CircleVertices+j+1;
spring[k].p2 = NumVertices-1;
spring[k].index = (NumCirclesx2/2-1)*CircleVertices*4+2*j;
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
}
}
球的体积
float VolumeBall(){
float minx = 100000,miny = 100000,minz = 100000, maxx = -100000, maxy = -100000, maxz = -100000;
for(int i = 0; i<NumVertices; i++){
if(points[i].x < minx) minx = points[i].x;
if(points[i].y < miny) miny = points[i].y;
if(points[i].z < minz) minz = points[i].z;
if(points[i].x > maxx) maxx = points[i].x;
if(points[i].y > maxy) maxy = points[i].y;
if(points[i].z > maxz) maxz = points[i].z;
}
return (maxx - minx) * (maxz - minz) * (maxy - miny);
}
强制累加器
void AccumulateForces(){
vec3 point1, point2,point3,point4;
float r12;
vec3 v12;
float f;
vec3 F;
vec3 norm;
bool flag = true;
float volume=0;
float pressurev;
for(int i =0; i<NumVertices; i++){
mass[i].f.x = 0;
mass[i].f.z = 0;
mass[i].f.y = 0;
if(Pressure - FINAL_PRESSURE >= 0) mass[i].f.y = Mass * GY;
}
for(int i=0; i<NumEdges/2; i++){
point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
r12 = distance(point1, point2);
if(r12 != 0){
v12 = mass[spring[i].p1].v - mass[spring[i].p2].v;
f = (r12 - spring[i].length) * KS + innerprod(v12,point1 - point2) * KD / r12;
F = (point1-point2)/r12 * f;
mass[spring[i].p1].f -= F;
mass[spring[i].p2].f += F;
}
spring[i].n = normalize(point1-point2);
}
volume = VolumeBall();
for(int i=0;i<NumEdges/2;i++){
point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
r12 = distance(point1,point2);
pressurev = r12 * Pressure * (1.0f/volume);
mass[spring[i].p1].f += spring[i].n * pressurev;
mass[spring[i].p2].f += spring[i].n * pressurev;
}
}void AccumulateForces(){
vec3 point1, point2,point3,point4;
float r12;
vec3 v12;
float f;
vec3 F;
vec3 norm;
bool flag = true;
float volume=0;
float pressurev;
for(int i =0; i<NumVertices; i++){
mass[i].f.x = 0;
mass[i].f.z = 0;
mass[i].f.y = 0;
if(Pressure - FINAL_PRESSURE >= 0) mass[i].f.y = Mass * GY;
}
for(int i=0; i<NumEdges/2; i++){
point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
r12 = distance(point1, point2);
if(r12 != 0){
v12 = mass[spring[i].p1].v - mass[spring[i].p2].v;
f = (r12 - spring[i].length) * KS + innerprod(v12,point1 - point2) * KD / r12;
F = (point1-point2)/r12 * f;
mass[spring[i].p1].f -= F;
mass[spring[i].p2].f += F;
}
spring[i].n = normalize(point1-point2);
}
volume = VolumeBall();
for(int i=0;i<NumEdges/2;i++){
point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
r12 = distance(point1,point2);
pressurev = r12 * Pressure * (1.0f/volume);
mass[spring[i].p1].f += spring[i].n * pressurev;
mass[spring[i].p2].f += spring[i].n * pressurev;
}
}
欧拉集成商
void IntegrateEuler(){
float dry,drx,drz;
for(int i=0;i<NumVertices;i++){
mass[i].v.x = mass[i].v.x + (mass[i].f.x/Mass) * DT;
drx = mass[i].v.x * DT;
if(points[i].x + drx < -SCRSIZE){
drx = -SCRSIZE - points[i].x;
mass[i].v.x = -0.1 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
mass[i].v.z = 0.95 * mass[i].v.z;
}
if(points[i].x + drx > SCRSIZE){
drx = SCRSIZE - points[i].x;
mass[i].v.x = -0.1 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
mass[i].v.z = 0.95 * mass[i].v.z;
}
points[i].x = points[i].x + drx;
mass[i].v.y = mass[i].v.y + (mass[i].f.y/Mass) * DT;
dry = mass[i].v.y * DT;
if(points[i].y + dry < -SCRSIZE){
dry = -SCRSIZE - points[i].y;
mass[i].v.y = -0.1 * mass[i].v.y;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.z = 0.95 * mass[i].v.z;
}
if(points[i].y + dry > SCRSIZE){
dry = SCRSIZE - points[i].y;
mass[i].v.y = -0.1 * mass[i].v.y;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.z = 0.95 * mass[i].v.z;
}
points[i].y = points[i].y + dry;
mass[i].v.z = mass[i].v.z + (mass[i].f.z/Mass) * DT;
drz = mass[i].v.z * DT;
if(points[i].z + drz < -SCRSIZE){
drz = -SCRSIZE - points[i].z;
mass[i].v.z = -0.1 * mass[i].v.z;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
}
if(points[i].z + drz > SCRSIZE){
drz = SCRSIZE - points[i].z;
mass[i].v.z = -0.1 * mass[i].v.z;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
}
points[i].z = points[i].z + drz;
if(points[i].x > SCRSIZE)
points[i].x = SCRSIZE;
if(points[i].y > SCRSIZE)
points[i].y = SCRSIZE;
if(points[i].z > SCRSIZE)
points[i].z = SCRSIZE;
if(points[i].x < -SCRSIZE)
points[i].x = -SCRSIZE;
if(points[i].y < -SCRSIZE)
points[i].y = -SCRSIZE;
if(points[i].z < -SCRSIZE)
points[i].z = -SCRSIZE;
}
}
如果您感兴趣,请使用着色器完整代码。
#include "Angel.h"
#define Mass 1.0f
#define KS 1755.0f
#define KD 35.0f
#define GY -10.0f
#define BALLRADIUS 0.516f
#define DT 0.011f
#define FINAL_PRESSURE 85.0f
#define SCRSIZE 7
typedef Angel::vec4 color4;
typedef Angel::vec4 point4;
const int CircleVertices = 8;
const int NumCirclesx2 = 20;
const int NumVertices = CircleVertices * (NumCirclesx2/2-1) + 2;
const int NumEdges = (NumVertices-2)*4+CircleVertices*2;
point4 points[NumVertices];
GLfloat w = 512, h = 512;
//-----------------------------------------------------------------
float xLeft = -2.0;
float xRight = 2.0;
float yBottom = -2.0;
float yTop = 2.0;
float zNear = -4.0;
float zFar = 4.0;
float aspectx = 1;
float aspecty = 1;
//-----------------------------------------------------------------
GLuint vModel;
GLuint vProjection;
GLuint vView;
//------------------------------------------------------------------
typedef struct {
vec3 v;
vec3 f;
} PointMass;
typedef struct {
int p1,p2;
int index;
float length;
vec3 n;
} Spring;
PointMass mass[NumVertices];
Spring spring[NumEdges/2];
float Pressure = 0;
//------------------------------------------------------------------
point4 edges[NumEdges];
point4 b[5];
point4 c[5];
static int k = 0;
//view angle
const float dr = 5.0 * DegreesToRadians;
float theta = 0;
float phi = 0;
float distance(vec4 a, vec4 b){
return sqrt((a.x - b.x) * (a.x - b.x)+(a.y - b.y) * (a.y - b.y)+(a.z - b.z) * (a.z - b.z));
}
float distance(vec3 a, vec3 b){
return sqrt((a.x - b.x) * (a.x - b.x)+(a.y - b.y) * (a.y - b.y)+(a.z - b.z) * (a.z - b.z));
}
float innerprod(vec3 a, vec3 b){
vec3 c = a * b;
return c.x+c.y+c.z;
}
void
InitPoints()
{
float dxy = (360.0 * DegreesToRadians) / CircleVertices;
float dz = (360.0 * DegreesToRadians) / NumCirclesx2;
points[0] = vec4( 0.0, 1.0, 0.0, 1.0);
for(int j=1;j<NumCirclesx2/2;j++){
for(int i=0;i<CircleVertices;i++){
points[(j-1)*CircleVertices + i+1] = vec4(BALLRADIUS * sin(i * dxy)*sin(j*dz), BALLRADIUS *cos(j*dz), BALLRADIUS *cos(i * dxy)*sin(j*dz), 1.0);
}
}
points[NumVertices-1] = vec4( 0.0, -1.0, 0.0, 1.0);
}
void
InitEdges(){
int k = 0;
for(int j=0;j<CircleVertices;j++){
edges[4*j] = points[1+j];
edges[4*j+1] = points[0];
spring[k].p1 = 0;
spring[k].p2 = 1+j;
spring[k].index = 4*j;
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
edges[4*j+2] = points[(1+j)];
spring[k].p1 = 1+j;
spring[k].index = 4*j+2;
if(2+j == CircleVertices){
edges[4*j+3] = points[(2+j)];
spring[k].p2 = 2+j;
}
else{
edges[4*j+3] = points[(2+j)%(CircleVertices)];
spring[k].p2 = (2+j)%(CircleVertices);
}
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
}
for(int i=1;i<NumCirclesx2/2-1;i++){
for(int j=0;j<CircleVertices;j++){
edges[i*CircleVertices*4+4*j] = points[i*CircleVertices+1+j];
edges[i*CircleVertices*4+4*j+1] = points[(i-1)*CircleVertices+1+j];
spring[k].p1 = i*CircleVertices+1+j;
spring[k].p2 = (i-1)*CircleVertices+1+j;
spring[k].index = i*CircleVertices*4+4*j;
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
edges[i*CircleVertices*4+4*j+2] = points[i*CircleVertices+1+j];
spring[k].p1 = i*CircleVertices+1+j;
spring[k].index = i*CircleVertices*4+4*j+2;
if(2+j == CircleVertices){
edges[i*CircleVertices*4+4*j+3] = points[i*CircleVertices+(2+j)];
spring[k].p2 = i*CircleVertices+(2+j);
}
else {
edges[i*CircleVertices*4+4*j+3] = points[i*CircleVertices+(2+j)%CircleVertices];
spring[k].p2 = i*CircleVertices+(2+j)%CircleVertices;
}
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
}
}
for(int j=0;j<CircleVertices;j++){
edges[(NumCirclesx2/2-1)*CircleVertices*4+2*j] = points[NumVertices-1];
edges[(NumCirclesx2/2-1)*CircleVertices*4+2*j+1] = points[(NumCirclesx2/2-1)*CircleVertices-CircleVertices+j+1];
spring[k].p1 = (NumCirclesx2/2-1)*CircleVertices-CircleVertices+j+1;
spring[k].p2 = NumVertices-1;
spring[k].index = (NumCirclesx2/2-1)*CircleVertices*4+2*j;
spring[k].length = distance(points[spring[k].p1],points[spring[k].p2]);
k++;
cout << NumVertices-1 << " " << (NumCirclesx2/2-1)*CircleVertices-CircleVertices+j+1 << endl;
}
}
void updateEdge(){
for(int j=0;j<CircleVertices;j++){
edges[4*j] = points[1+j];
edges[4*j+1] = points[0];
edges[4*j+2] = points[(1+j)];
if(2+j == CircleVertices){
edges[4*j+3] = points[(2+j)];
}
else{
edges[4*j+3] = points[(2+j)%(CircleVertices)];
}
}
for(int i=1;i<NumCirclesx2/2-1;i++){
for(int j=0;j<CircleVertices;j++){
edges[i*CircleVertices*4+4*j] = points[i*CircleVertices+1+j];
edges[i*CircleVertices*4+4*j+1] = points[(i-1)*CircleVertices+1+j];
edges[i*CircleVertices*4+4*j+2] = points[i*CircleVertices+1+j];
if(2+j == CircleVertices){
edges[i*CircleVertices*4+4*j+3] = points[i*CircleVertices+(2+j)];
}
else {
edges[i*CircleVertices*4+4*j+3] = points[i*CircleVertices+(2+j)%CircleVertices];
}
}
}
for(int j=0;j<CircleVertices;j++){
edges[(NumCirclesx2/2-1)*CircleVertices*4+2*j] = points[NumVertices-1];
edges[(NumCirclesx2/2-1)*CircleVertices*4+2*j+1] = points[(NumCirclesx2/2-1)*CircleVertices-CircleVertices+j+1];
}
}
float VolumeBall(){
float minx = 100000,miny = 100000,minz = 100000, maxx = -100000, maxy = -100000, maxz = -100000;
for(int i = 0; i<NumVertices; i++){
if(points[i].x < minx) minx = points[i].x;
if(points[i].y < miny) miny = points[i].y;
if(points[i].z < minz) minz = points[i].z;
if(points[i].x > maxx) maxx = points[i].x;
if(points[i].y > maxy) maxy = points[i].y;
if(points[i].z > maxz) maxz = points[i].z;
}
return (maxx - minx) * (maxz - minz) * (maxy - miny);
}
void AccumulateForces(){
vec3 point1, point2,point3,point4;
float r12;
vec3 v12;
float f;
vec3 F;
vec3 norm;
bool flag = true;
float volume=0;
float pressurev;
for(int i =0; i<NumVertices; i++){
mass[i].f.x = 0;
mass[i].f.z = 0;
mass[i].f.y = 0;
if(Pressure - FINAL_PRESSURE >= 0) mass[i].f.y = Mass * GY;
}
for(int i=0; i<NumEdges/2; i++){
point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
r12 = distance(point1, point2);
if(r12 != 0){
v12 = mass[spring[i].p1].v - mass[spring[i].p2].v;
f = (r12 - spring[i].length) * KS + innerprod(v12,point1 - point2) * KD / r12;
F = (point1-point2)/r12 * f;
mass[spring[i].p1].f -= F;
mass[spring[i].p2].f += F;
}
spring[i].n = normalize(point1-point2);
// if(flag){
// point3 = vec3(points[spring[i+1].p1].x,points[spring[i+1].p1].y,points[spring[i+1].p1].z);
// point4 = vec3(points[spring[i+1].p2].x,points[spring[i+1].p2].y,points[spring[i+1].p2].z);
// norm = cross(point1-point2, point3-point4);
// norm = normalize(norm);
// spring[i].n = norm;
// flag = false;
// }
// else{
// spring[i].n = norm;
// flag = true;
// }
}
// for(int i=0; i< NumEdges/2; i++){
// point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
// point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
// r12 = distance(point1, point2);
// volume += 0.5 * abs(point1.x-point2.x) * abs(spring[i].n.x) * r12;
// }
volume = VolumeBall();
for(int i=0;i<NumEdges/2;i++){
point1 = vec3(points[spring[i].p1].x,points[spring[i].p1].y,points[spring[i].p1].z);
point2 = vec3(points[spring[i].p2].x,points[spring[i].p2].y,points[spring[i].p2].z);
r12 = distance(point1,point2);
pressurev = r12 * Pressure * (1.0f/volume);
mass[spring[i].p1].f += spring[i].n * pressurev;
mass[spring[i].p2].f += spring[i].n * pressurev;
}
}
void IntegrateEuler(){
float dry,drx,drz;
for(int i=0;i<NumVertices;i++){
mass[i].v.x = mass[i].v.x + (mass[i].f.x/Mass) * DT;
drx = mass[i].v.x * DT;
if(points[i].x + drx < -SCRSIZE){
drx = -SCRSIZE - points[i].x;
mass[i].v.x = -0.1 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
mass[i].v.z = 0.95 * mass[i].v.z;
}
if(points[i].x + drx > SCRSIZE){
drx = SCRSIZE - points[i].x;
mass[i].v.x = -0.1 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
mass[i].v.z = 0.95 * mass[i].v.z;
}
points[i].x = points[i].x + drx;
mass[i].v.y = mass[i].v.y + (mass[i].f.y/Mass) * DT;
dry = mass[i].v.y * DT;
if(points[i].y + dry < -SCRSIZE){
dry = -SCRSIZE - points[i].y;
mass[i].v.y = -0.1 * mass[i].v.y;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.z = 0.95 * mass[i].v.z;
}
if(points[i].y + dry > SCRSIZE){
dry = SCRSIZE - points[i].y;
mass[i].v.y = -0.1 * mass[i].v.y;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.z = 0.95 * mass[i].v.z;
}
points[i].y = points[i].y + dry;
mass[i].v.z = mass[i].v.z + (mass[i].f.z/Mass) * DT;
drz = mass[i].v.z * DT;
if(points[i].z + drz < -SCRSIZE){
drz = -SCRSIZE - points[i].z;
mass[i].v.z = -0.1 * mass[i].v.z;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
}
if(points[i].z + drz > SCRSIZE){
drz = SCRSIZE - points[i].z;
mass[i].v.z = -0.1 * mass[i].v.z;
mass[i].v.x = 0.95 * mass[i].v.x;
mass[i].v.y = 0.95 * mass[i].v.y;
}
points[i].z = points[i].z + drz;
if(points[i].x > SCRSIZE)
points[i].x = SCRSIZE;
if(points[i].y > SCRSIZE)
points[i].y = SCRSIZE;
if(points[i].z > SCRSIZE)
points[i].z = SCRSIZE;
if(points[i].x < -SCRSIZE)
points[i].x = -SCRSIZE;
if(points[i].y < -SCRSIZE)
points[i].y = -SCRSIZE;
if(points[i].z < -SCRSIZE)
points[i].z = -SCRSIZE;
}
}
// OpenGL initialization
void
init()
{
InitPoints();
InitEdges();
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create and initialize a buffer object put all of the object in the same buffer to speed things up
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(edges), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(edges), edges);
// Load shaders and use the resulting shader program
GLuint program = InitShader("vshader.glsl", "fshader.glsl");
glUseProgram(program);
// set up vertex arrays
GLuint vPosition = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0));
// uniform variables in the shader
GLuint vColor = glGetUniformLocation(program, "vColor");
glUniform4fv(vColor, 1, color4(1.0,0.0,0.0,1.0));
vView = glGetUniformLocation(program, "vView");
vProjection = glGetUniformLocation(program, "vProjection");
//glEnable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClearColor(0.0, 0.0, 0.0, 0.0);
}
//----------------------------------------------------------------------------
void
display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
point4 at( 0.0, 0.0, 0.0, 1.0 );
point4 eye( 0.5*sin(theta)*cos(phi), 0.5*sin(phi), -cos(theta)*0.5*cos(phi), 1.0 );
vec4 up( 0.0, 1.0, 0.0, 0.0 );
updateEdge();
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(edges), edges);
mat4 view = LookAt( eye, at, up );
glUniformMatrix4fv(vView, 1, GL_TRUE, view);
glUniformMatrix4fv(vProjection, 1, GL_TRUE,
Ortho( -SCRSIZE, SCRSIZE, -SCRSIZE, SCRSIZE, zNear, zFar ));
// Ortho( aspectx*xLeft, aspectx*xRight, aspecty*yBottom, aspecty*yTop, zNear, zFar ));
glDrawArrays(GL_LINES, 0, NumEdges);
glutSwapBuffers();
}
//----------------------------------------------------------------------------
void
keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'i':
case 'I': aspectx=aspectx*0.9;aspecty=aspecty*0.9;break;
case 'o':
case 'O': aspectx=aspectx*1.1;aspecty=aspecty*1.1;break;
case 033: // Escape Key
// 'q' exits
case 'q': case 'Q': exit(EXIT_SUCCESS); break;
}
}
//----------------------------------------------------------------------------
//special keyboard function catches special keyboard inputs such as arrow keys.
void SpecialKeyboard(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_LEFT: theta += dr; break;
case GLUT_KEY_RIGHT: theta -= dr; break;
case GLUT_KEY_UP: phi += dr; break;
case GLUT_KEY_DOWN: phi -= dr; break;
}
glutPostRedisplay();
}
//----------------------------------------------------------------------------
void timer(int)
{
AccumulateForces();
IntegrateEuler();
if(Pressure < FINAL_PRESSURE)
{
Pressure += FINAL_PRESSURE/100.0f;
printf("Pressure = %4.4f\n",Pressure);
}
glutPostRedisplay();
glutTimerFunc(1000, timer, 0);
}
// void
// idle(void)
// {
// AccumulateForces();
// IntegrateEuler();
// if(Pressure < FINAL_PRESSURE)
// {
// Pressure += FINAL_PRESSURE/100.0f;
// printf("Pressure = %4.4f\n",Pressure);
// }
// glutPostRedisplay();
// }
//----------------------------------------------------------------------------
void reshape(GLsizei ww, GLsizei hh)
{
glViewport( 0, 0, ww, hh );
aspectx = (GLfloat)ww/w;
aspecty = (GLfloat)hh/h;
w = ww;
h = hh;
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(512, 512);
glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("Free Fall");
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(SpecialKeyboard);
glutTimerFunc(1000.0/60.0, timer, 0);
// glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
#version 150
in vec4 vPosition;
uniform vec4 vColor;
uniform mat4 vView;
uniform mat4 vProjection;
out vec4 color;
void main()
{
gl_Position = vProjection*vView*vPosition;
color = vColor;
}
#version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}