⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rubber.c

📁 C:Documents and SettingsAdministrator桌面VC++多媒体特效制作百例CHAR20Distort
💻 C
字号:
/*	rubber.c	Drew Olbrich, 1992	Port to OpenGL	Nate Robins, 1997*/#include <stdio.h>#include <math.h>#include "glut.h"#include "defs.h"#include "rubber.h"extern int win_size_x, win_size_y;EFFECT rubber = { rubber_init, rubber_dynamics, rubber_redraw, rubber_click };#define SPRING_KS  0.3#define DRAG	   0.5typedef struct {  float x[3];  float v[3];  float t[2];  int nail;} MASS;typedef struct {  int i, j;  float r;} SPRING;static int spring_count;static MASS *mass = NULL;static SPRING *spring = NULL;static int grab = -1;	/* index of grabbed mass point */void rubber_init(){  int i, j;  int k;  int m;  glEnable(GL_DEPTH_TEST);  if (mass == NULL)  {    mass = (MASS *) malloc(sizeof(MASS)*GRID_SIZE_X*GRID_SIZE_Y);    if (mass == NULL)    {      fprintf(stderr, "rubber: Can't allocate memory.\n");	      exit(-1);    }  }  k = 0;  for (i = 0; i < GRID_SIZE_X; i++)    for (j = 0; j < GRID_SIZE_Y; j++)    {      mass[k].nail = (i == 0 || j == 0 || i == GRID_SIZE_X - 1		      || j == GRID_SIZE_Y - 1);      mass[k].x[0] = i/(GRID_SIZE_X - 1.0)*win_size_x;      mass[k].x[1] = j/(GRID_SIZE_Y - 1.0)*win_size_y;      mass[k].x[2] = -(CLIP_FAR - CLIP_NEAR)/2.0;      mass[k].v[0] = 0.0;      mass[k].v[1] = 0.0;      mass[k].v[2] = 0.0;      mass[k].t[0] = i/(GRID_SIZE_X - 1.0);      mass[k].t[1] = j/(GRID_SIZE_Y - 1.0);      k++;    }  if (spring == NULL)  {    spring_count = (GRID_SIZE_X - 1)*(GRID_SIZE_Y - 2)      + (GRID_SIZE_Y - 1)*(GRID_SIZE_X - 2);        spring = (SPRING *) malloc(sizeof(SPRING)*spring_count);    if (spring == NULL)    {      fprintf(stderr, "rubber: Can't allocate memory.\n");	      exit(-1);    }  }  k = 0;  for (i = 1; i < GRID_SIZE_X - 1; i++)    for (j = 0; j < GRID_SIZE_Y - 1; j++)    {      m = GRID_SIZE_Y*i + j;      spring[k].i = m;      spring[k].j = m + 1;      spring[k].r = (win_size_y - 1.0)/(GRID_SIZE_Y - 1.0);      k++;    }  for (j = 1; j < GRID_SIZE_Y - 1; j++)    for (i = 0; i < GRID_SIZE_X - 1; i++)    {      m = GRID_SIZE_Y*i + j;      spring[k].i = m;      spring[k].j = m + GRID_SIZE_X;      spring[k].r = (win_size_x - 1.0)/(GRID_SIZE_X - 1.0);      k++;    }}/*	Do the dynamics simulation for the next frame.*/void rubber_dynamics(int mousex, int mousey){  int k;  float d[3];  int i, j;  float l;  float a;  /* calculate all the spring forces acting on the mass points */  for (k = 0; k < spring_count; k++)  {    i = spring[k].i;    j = spring[k].j;    d[0] = mass[i].x[0] - mass[j].x[0];    d[1] = mass[i].x[1] - mass[j].x[1];    d[2] = mass[i].x[2] - mass[j].x[2];    l = sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);    if (l != 0.0)    {      d[0] /= l;      d[1] /= l;      d[2] /= l;      a = l - spring[k].r;      mass[i].v[0] -= d[0]*a*SPRING_KS;      mass[i].v[1] -= d[1]*a*SPRING_KS;      mass[i].v[2] -= d[2]*a*SPRING_KS;      mass[j].v[0] += d[0]*a*SPRING_KS;      mass[j].v[1] += d[1]*a*SPRING_KS;      mass[j].v[2] += d[2]*a*SPRING_KS;    }  }  /* update the state of the mass points */  for (k = 0; k < GRID_SIZE_X*GRID_SIZE_Y; k++)    if (!mass[k].nail)    {      mass[k].x[0] += mass[k].v[0];      mass[k].x[1] += mass[k].v[1];      mass[k].x[2] += mass[k].v[2];            mass[k].v[0] *= (1.0 - DRAG);      mass[k].v[1] *= (1.0 - DRAG);      mass[k].v[2] *= (1.0 - DRAG);      if (mass[k].x[2] > -CLIP_NEAR - 0.01)	mass[k].x[2] = -CLIP_NEAR - 0.01;      if (mass[k].x[2] < -CLIP_FAR + 0.01)	mass[k].x[2] = -CLIP_FAR + 0.01;    }  /* if a mass point is grabbed, attach it to the mouse */  if (grab != -1 && !mass[grab].nail)  {    mass[grab].x[0] = mousex;    mass[grab].x[1] = mousey;    mass[grab].x[2] = -(CLIP_FAR - CLIP_NEAR)/4.0;  }}/*	Draw the next frame of animation.*/void rubber_redraw(){  int k;  int i, j;  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);#define _WIREFRAME#ifdef WIREFRAME  for (k = 0; k < spring_count; k++)  {    glBegin(GL_LINES);    glVertex3fv(mass[spring[k].i].x);    glVertex3fv(mass[spring[k].j].x);    glEnd();  }#else  k = 0;  for (i = 0; i < GRID_SIZE_X - 1; i++)  {    for (j = 0; j < GRID_SIZE_Y - 1; j++)    {      glBegin(GL_POLYGON);      glTexCoord2fv(mass[k].t);      glVertex3fv(mass[k].x);      glTexCoord2fv(mass[k + 1].t);      glVertex3fv(mass[k + 1].x);      glTexCoord2fv(mass[k + GRID_SIZE_Y + 1].t);      glVertex3fv(mass[k + GRID_SIZE_Y + 1].x);      glTexCoord2fv(mass[k + GRID_SIZE_Y].t);      glVertex3fv(mass[k + GRID_SIZE_Y].x);      glEnd();      k++;    }    k++;  }#endif  glutSwapBuffers();}/*	Return the index of the mass point that's nearest to the	given screen coordinate.*/int rubber_grab(int x, int y){  float dx[2];  float d;  float min_d;  float min_i;  int i;  for (i = 0; i < GRID_SIZE_X*GRID_SIZE_Y; i++)  {    dx[0] = mass[i].x[0] - x;    dx[1] = mass[i].x[1] - y;    d = sqrt(dx[0]*dx[0] + dx[1]*dx[1]);    if (i == 0 || d < min_d)    {      min_i = i;      min_d = d;    }  }  return min_i;}/*	If the mouse is pressed down, grab the nearest mass point.*/void rubber_click(int mousex, int mousey, int state){  if (state)    grab = rubber_grab(mousex, mousey);  else    grab = -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -