Пример #1
0
/**
 *  Create a gear wheel.
 *
 *  @param inner_radius radius of hole at center
 *  @param outer_radius radius at center of teeth
 *  @param width width of gear
 *  @param teeth number of teeth
 *  @param tooth_depth depth of tooth
 *
 *  @return pointer to the constructed struct gear
 */
static struct gear *
create_gear (GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
             GLint teeth, GLfloat tooth_depth)
{
    GLfloat r0, r1, r2;
    GLfloat da;
    GearVertex *v;
    struct gear *gear;
    double s[5], c[5];
    GLfloat normal[3];
    int cur_strip = 0;
    int i;

    /* Allocate memory for the gear */
    gear = malloc (sizeof *gear);
    if (gear == NULL)
        return NULL;

    /* Calculate the radii used in the gear */
    r0 = inner_radius;
    r1 = outer_radius - tooth_depth / 2.0;
    r2 = outer_radius + tooth_depth / 2.0;

    da = 2.0 * M_PI / teeth / 4.0;

    /* Allocate memory for the triangle strip information */
    gear->nstrips = STRIPS_PER_TOOTH * teeth;
    gear->strips = calloc (gear->nstrips, sizeof (*gear->strips));

    /* Allocate memory for the vertices */
    gear->vertices = calloc (VERTICES_PER_TOOTH * teeth, sizeof(*gear->vertices));
    v = gear->vertices;

    for (i = 0; i < teeth; i++) {
        /* Calculate needed sin/cos for varius angles */
        sincos (i * 2.0 * M_PI / teeth, &s[0], &c[0]);
        sincos (i * 2.0 * M_PI / teeth + da, &s[1], &c[1]);
        sincos (i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
        sincos (i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
        sincos (i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);

      /* A set of macros for making the creation of the gears easier */
#define  GEAR_POINT(r, da) { (r) * c[(da)], (r) * s[(da)] }
#define  SET_NORMAL(x, y, z) do { \
    normal[0] = (x); normal[1] = (y); normal[2] = (z); \
} while(0)

#define  GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal)

#define START_STRIP do { \
    gear->strips[cur_strip].first = v - gear->vertices; \
} while(0);

#define END_STRIP do { \
    int _tmp = (v - gear->vertices); \
    gear->strips[cur_strip].count = _tmp - gear->strips[cur_strip].first; \
    cur_strip++; \
} while (0)

#define QUAD_WITH_NORMAL(p1, p2) do { \
    SET_NORMAL((p[(p1)].y - p[(p2)].y), -(p[(p1)].x - p[(p2)].x), 0); \
    v = GEAR_VERT(v, (p1), -1); \
    v = GEAR_VERT(v, (p1), 1); \
    v = GEAR_VERT(v, (p2), -1); \
    v = GEAR_VERT(v, (p2), 1); \
} while(0)

        {
            struct point {
                GLfloat x;
                GLfloat y;
            };

            /* Create the 7 points (only x,y coords) used to draw a tooth */
            struct point p[7] = {
                GEAR_POINT (r2, 1), // 0
                GEAR_POINT (r2, 2), // 1
                GEAR_POINT (r1, 0), // 2
                GEAR_POINT (r1, 3), // 3
                GEAR_POINT (r0, 0), // 4
                GEAR_POINT (r1, 4), // 5
                GEAR_POINT (r0, 4), // 6
            };

            /* Front face */
            START_STRIP;
            SET_NORMAL (0, 0, 1.0);
            v = GEAR_VERT (v, 0, +1);
            v = GEAR_VERT (v, 1, +1);
            v = GEAR_VERT (v, 2, +1);
            v = GEAR_VERT (v, 3, +1);
            v = GEAR_VERT (v, 4, +1);
            v = GEAR_VERT (v, 5, +1);
            v = GEAR_VERT (v, 6, +1);
            END_STRIP;

            /* Inner face */
            START_STRIP;
            QUAD_WITH_NORMAL (4, 6);
            END_STRIP;

            /* Back face */
            START_STRIP;
            SET_NORMAL (0, 0, -1.0);
            v = GEAR_VERT (v, 6, -1);
            v = GEAR_VERT (v, 5, -1);
            v = GEAR_VERT (v, 4, -1);
            v = GEAR_VERT (v, 3, -1);
            v = GEAR_VERT (v, 2, -1);
            v = GEAR_VERT (v, 1, -1);
            v = GEAR_VERT (v, 0, -1);
            END_STRIP;

            /* Outer face */
            START_STRIP;
            QUAD_WITH_NORMAL (0, 2);
            END_STRIP;

            START_STRIP;
            QUAD_WITH_NORMAL (1, 0);
            END_STRIP;

            START_STRIP;
            QUAD_WITH_NORMAL (3, 1);
            END_STRIP;

            START_STRIP;
            QUAD_WITH_NORMAL (5, 3);
            END_STRIP;
        }
    }

    gear->nvertices = (v - gear->vertices);

    /* Store the vertices in a vertex buffer object (VBO) */
    glGenBuffers (1, &gear->vbo);
    glBindBuffer (GL_ARRAY_BUFFER, gear->vbo);
    glBufferData (GL_ARRAY_BUFFER, gear->nvertices * sizeof(GearVertex),
                  gear->vertices, GL_STATIC_DRAW);

    return gear;
}
Пример #2
0
/**
 *  Create a gear wheel.
 * 
 *  @param inner_radius radius of hole at center
 *  @param outer_radius radius at center of teeth
 *  @param width width of gear
 *  @param teeth number of teeth
 *  @param tooth_depth depth of tooth
 *  
 *  @return pointer to the constructed struct gear
 */
static struct gear *
create_gear(struct pipe_screen *screen, struct pipe_context *pipe, float inner_radius, float outer_radius, float width,
      int teeth, float tooth_depth)
{
   float r0, r1, r2;
   float da;
   GearVertex *v;
   struct gear *gear;
   double s[5], c[5];
   float normal[3];
   int cur_strip = 0;
   int i;

   /* Allocate memory for the gear */
   gear = malloc(sizeof *gear);
   if (gear == NULL)
      return NULL;

   /* Calculate the radii used in the gear */
   r0 = inner_radius;
   r1 = outer_radius - tooth_depth / 2.0;
   r2 = outer_radius + tooth_depth / 2.0;

   da = 2.0 * M_PI / teeth / 4.0;

   /* Allocate memory for the triangle strip information */
   gear->nstrips = STRIPS_PER_TOOTH * teeth;
   gear->strips = calloc(gear->nstrips, sizeof (*gear->strips));

   /* Allocate memory for the vertices */
   gear->vertices = calloc(VERTICES_PER_TOOTH * teeth, sizeof(*gear->vertices));
   v = gear->vertices;

   for (i = 0; i < teeth; i++) {
      /* Calculate needed sin/cos for varius angles */
      sincos_(i * 2.0 * M_PI / teeth, &s[0], &c[0]);
      sincos_(i * 2.0 * M_PI / teeth + da, &s[1], &c[1]);
      sincos_(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
      sincos_(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
      sincos_(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);

      /* A set of macros for making the creation of the gears easier */
#define  GEAR_POINT(r, da) { (r) * c[(da)], (r) * s[(da)] }
#define  SET_NORMAL(x, y, z) do { \
   normal[0] = (x); normal[1] = (y); normal[2] = (z); \
} while(0)

#define  GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal)

#define START_STRIP do { \
   gear->strips[cur_strip].first = v - gear->vertices; \
} while(0);

#define END_STRIP do { \
   int _tmp = (v - gear->vertices); \
   gear->strips[cur_strip].count = _tmp - gear->strips[cur_strip].first; \
   cur_strip++; \
} while (0)

#define QUAD_WITH_NORMAL(p1, p2) do { \
   SET_NORMAL((p[(p1)].y - p[(p2)].y), -(p[(p1)].x - p[(p2)].x), 0); \
   v = GEAR_VERT(v, (p1), -1); \
   v = GEAR_VERT(v, (p1), 1); \
   v = GEAR_VERT(v, (p2), -1); \
   v = GEAR_VERT(v, (p2), 1); \
} while(0)

      struct point {
         float x;
         float y;
      };

      /* Create the 7 points (only x,y coords) used to draw a tooth */
      struct point p[7] = {
         GEAR_POINT(r2, 1), // 0
         GEAR_POINT(r2, 2), // 1
         GEAR_POINT(r1, 0), // 2
         GEAR_POINT(r1, 3), // 3
         GEAR_POINT(r0, 0), // 4
         GEAR_POINT(r1, 4), // 5
         GEAR_POINT(r0, 4), // 6
      };

      /* Front face */
      START_STRIP;
      SET_NORMAL(0, 0, 1.0);
      v = GEAR_VERT(v, 0, +1);
      v = GEAR_VERT(v, 1, +1);
      v = GEAR_VERT(v, 2, +1);
      v = GEAR_VERT(v, 3, +1);
      v = GEAR_VERT(v, 4, +1);
      v = GEAR_VERT(v, 5, +1);
      v = GEAR_VERT(v, 6, +1);
      END_STRIP;

      /* Inner face */
      START_STRIP;
      QUAD_WITH_NORMAL(4, 6);
      END_STRIP;

      /* Back face */
      START_STRIP;
      SET_NORMAL(0, 0, -1.0);
      v = GEAR_VERT(v, 6, -1);
      v = GEAR_VERT(v, 5, -1);
      v = GEAR_VERT(v, 4, -1);
      v = GEAR_VERT(v, 3, -1);
      v = GEAR_VERT(v, 2, -1);
      v = GEAR_VERT(v, 1, -1);
      v = GEAR_VERT(v, 0, -1);
      END_STRIP;

      /* Outer face */
      START_STRIP;
      QUAD_WITH_NORMAL(0, 2);
      END_STRIP;

      START_STRIP;
      QUAD_WITH_NORMAL(1, 0);
      END_STRIP;

      START_STRIP;
      QUAD_WITH_NORMAL(3, 1);
      END_STRIP;

      START_STRIP;
      QUAD_WITH_NORMAL(5, 3);
      END_STRIP;
   }

   gear->nvertices = (v - gear->vertices);

    /* element layout */
    struct pipe_vertex_element pipe_vertex_elements[] = {
        { /* positions */
            .src_offset = 0x0,
            .instance_divisor = 0,
            .vertex_buffer_index = 0,
            .src_format = PIPE_FORMAT_R32G32B32_FLOAT 
        },
        { /* normals */
            .src_offset = 0xc,