~george-edison55/stackfusion/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <math.h>
#include <string.h>
#include "bubble.h"

#ifndef PI2
#define PI2 6.2831853
#endif

#ifndef HALFPI
#define HALFPI 1.57079633
#endif

#define NUM_DIVISIONS 10

Bubble::Bubble()
  : m_vertices(NULL), m_indices(NULL), m_fadein_remaining(0)
{
    // Create the rectangle
    CreateRoundedRectangle(NUM_DIVISIONS, 0.4);
}

Bubble::~Bubble()
{
    if(m_vertices)
        delete [] m_vertices;
    if(m_indices)
        delete [] m_indices;
}

void Bubble::CreateRoundedRectangle(int num_divisions,
                                    float radius)
{
    // Calculate some values
    float circle_offset = 1.0f - radius;
    int total_divisions = (num_divisions + 1) * 4;
    
    // Storage for the points
    m_vertices = new GLfloat[(total_divisions + 1) * 2];
    memset(m_vertices, 0, sizeof(GLfloat) * (total_divisions + 1) * 2);
    
    // Fill in the quadrants
    int calc_offset  = 0;
    int index_offset = 0;
    for(int i=0;i<=num_divisions;++i,++calc_offset,++index_offset)
    {
        float f = (float)calc_offset / (float)(num_divisions * 4);
        m_vertices[index_offset * 2]     = cos(PI2 * f) * radius + circle_offset;
        m_vertices[index_offset * 2 + 1] = sin(PI2 * f) * radius + circle_offset;
    }
    calc_offset -= 1;
    for(int i=0;i<=num_divisions;++i,++calc_offset,++index_offset)
    {
        float f = (float)calc_offset / (float)(num_divisions * 4);
        m_vertices[index_offset * 2]     = cos(PI2 * f) * radius - circle_offset;
        m_vertices[index_offset * 2 + 1] = sin(PI2 * f) * radius + circle_offset;
    }
    calc_offset -= 1;
    for(int i=0;i<=num_divisions;++i,++calc_offset,++index_offset)
    {
        float f = (float)calc_offset / (float)(num_divisions * 4);
        m_vertices[index_offset * 2]     = cos(PI2 * f) * radius - circle_offset;
        m_vertices[index_offset * 2 + 1] = sin(PI2 * f) * radius - circle_offset;
    }
    calc_offset -= 1;
    for(int i=0;i<=num_divisions;++i,++calc_offset,++index_offset)
    {
        float f = (float)calc_offset / (float)(num_divisions * 4);
        m_vertices[index_offset * 2]     = cos(PI2 * f) * radius + circle_offset;
        m_vertices[index_offset * 2 + 1] = sin(PI2 * f) * radius - circle_offset;
    }
    
    // Now create the indices
    m_indices = new GLuint[total_divisions + 2];
    
    m_indices[0] = total_divisions;
    for(int i=1; i<=total_divisions; ++i)
        m_indices[i] = i - 1;
    m_indices[total_divisions + 1] = 0;
}

void Bubble::Render(int ms)
{
    // Check for a transition
    float trans = 1.0f;
    
    if(m_fadein_remaining > 0)
    {
        m_fadein_remaining -= ms;
        trans = sin((1.0f - (float)m_fadein_remaining / (float)m_fadein_time) * HALFPI);
    }
    
    // Set up the matrix
    glPushMatrix();
    glScalef(trans * 0.15f + 0.85f, trans * 0.15f + 0.85f, 1.0f);
    
    // Set up the blending
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glColor4f(0.5, 0.5, 0.5, trans * 0.4f);
    
    // Draw the stuff
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, m_vertices);
    glDrawElements(GL_TRIANGLE_FAN, (NUM_DIVISIONS + 1) * 4 + 2, GL_UNSIGNED_INT, m_indices);
    glDisableClientState(GL_VERTEX_ARRAY);
    
    glDisable(GL_BLEND);
    glPopMatrix();
}