static void make_circle_thing(VertexArray &va, float radius, const Color &colCenter, const Color &colEdge) { va.Add(vector3f(0.f, 0.f, 0.f), colCenter); for (float ang=0; ang<float(M_PI)*2.f; ang+=0.1f) { va.Add(vector3f(radius*sin(ang), radius*cos(ang), 0.0f), colEdge); } va.Add(vector3f(0.f, radius, 0.f), colEdge); }
MilkyWay::MilkyWay(Graphics::Renderer *r) { m_model = new StaticMesh(TRIANGLE_STRIP); //build milky way model in two strips (about 256 verts) //The model is built as a generic vertex array first. The renderer //will reprocess this into buffered format as it sees fit. The old data is //kept around as long as StaticMesh is alive (needed if the cache is to be regenerated) VertexArray *bottom = new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE); VertexArray *top = new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE); const Color dark(0.f); const Color bright(0.05f, 0.05f, 0.05f, 0.05f); //bottom float theta; for (theta=0.0; theta < 2.f*float(M_PI); theta+=0.1f) { bottom->Add( vector3f(100.0f*sin(theta), float(-40.0 - 30.0*noise(sin(theta),1.0,cos(theta))), 100.0f*cos(theta)), dark); bottom->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); } theta = 2.f*float(M_PI); bottom->Add( vector3f(100.0f*sin(theta), float(-40.0 - 30.0*noise(sin(theta),1.0,cos(theta))), 100.0f*cos(theta)), dark); bottom->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); //top for (theta=0; theta < 2.f*float(M_PI); theta+=0.1f) { top->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); top->Add( vector3f(100.0f*sin(theta), float(40.0 + 30.0*noise(sin(theta),-1.0,cos(theta))), 100.0f*cos(theta)), dark); } theta = 2.f*float(M_PI); top->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); top->Add( vector3f(100.0f*sin(theta), float(40.0 + 30.0*noise(sin(theta),-1.0,cos(theta))), 100.0f*cos(theta)), dark); Graphics::MaterialDescriptor desc; desc.effect = Graphics::EFFECT_STARFIELD; desc.vertexColors = true; m_material.Reset(r->CreateMaterial(desc)); m_material->emissive = Color::WHITE; //This doesn't fade. Could add a generic opacity/intensity value. m_model->AddSurface(RefCountedPtr<Surface>(new Surface(TRIANGLE_STRIP, bottom, m_material))); m_model->AddSurface(RefCountedPtr<Surface>(new Surface(TRIANGLE_STRIP, top, m_material))); }
MilkyWay::MilkyWay() { m_model = new StaticMesh(TRIANGLE_STRIP); //build milky way model in two strips (about 256 verts) //The model is built as a generic vertex array first. The renderer //will reprocess this into buffered format as it sees fit. The old data is //kept around as long as StaticMesh is alive (needed if the cache is to be regenerated) VertexArray *bottom = new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE); VertexArray *top = new VertexArray(ATTRIB_POSITION | ATTRIB_DIFFUSE); const Color dark(0.f); const Color bright(0.05f, 0.05f, 0.05f, 0.05f); //bottom float theta; for (theta=0.0; theta < 2.f*float(M_PI); theta+=0.1f) { bottom->Add( vector3f(100.0f*sin(theta), float(-40.0 - 30.0*noise(sin(theta),1.0,cos(theta))), 100.0f*cos(theta)), dark); bottom->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); } theta = 2.f*float(M_PI); bottom->Add( vector3f(100.0f*sin(theta), float(-40.0 - 30.0*noise(sin(theta),1.0,cos(theta))), 100.0f*cos(theta)), dark); bottom->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); //top for (theta=0; theta < 2.f*float(M_PI); theta+=0.1f) { top->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); top->Add( vector3f(100.0f*sin(theta), float(40.0 + 30.0*noise(sin(theta),-1.0,cos(theta))), 100.0f*cos(theta)), dark); } theta = 2.f*float(M_PI); top->Add( vector3f(100.0f*sin(theta), float(5.0*noise(sin(theta),0.0,cos(theta))), 100.0f*cos(theta)), bright); top->Add( vector3f(100.0f*sin(theta), float(40.0 + 30.0*noise(sin(theta),-1.0,cos(theta))), 100.0f*cos(theta)), dark); m_material.Reset(new Material); m_material->unlit = true; m_material->vertexColors = true; m_shader.Reset(new Shader("bgstars")); m_material->shader = m_shader.Get(); m_model->AddSurface(new Surface(TRIANGLE_STRIP, bottom, m_material)); m_model->AddSurface(new Surface(TRIANGLE_STRIP, top, m_material)); }
Disk::Disk(Graphics::Renderer *r, RefCountedPtr<Material> material, Graphics::RenderState *state, const int edges, const float rad) : m_material(material) { PROFILE_SCOPED() m_renderState = state; VertexArray vertices (ATTRIB_POSITION); vertices.Add(vector3f(0.f, 0.f, 0.f)); const float edgeStep = 360.0f / float(edges); for (int i = edges; i >= 0; i--) { vertices.Add(vector3f( 0.f+sinf(DEG2RAD(i*edgeStep))*rad, 0.f+cosf(DEG2RAD(i*edgeStep))*rad, 0.f)); } SetupVertexBuffer(vertices, r); }
Disk::Disk(Graphics::Renderer *r, Graphics::RenderState *state, const Color &c, float rad) { PROFILE_SCOPED() m_renderState = state; VertexArray vertices (ATTRIB_POSITION); m_material.Reset(r->CreateMaterial(MaterialDescriptor())); m_material->diffuse = c; vertices.Add(vector3f(0.f, 0.f, 0.f)); for (int i = 72; i >= 0; i--) { vertices.Add(vector3f( 0.f+sinf(DEG2RAD(i*5.f))*rad, 0.f+cosf(DEG2RAD(i*5.f))*rad, 0.f)); } SetupVertexBuffer(vertices, r); }
float TextDraw::RenderCharacter( const Font & font, char c, float x, float y, float scalex, float scaley, VertexArray & output_array) { const Font::CharInfo * ci = 0; if (!font.GetCharInfo(c, ci)) return 0; float invsize = font.GetInvSize(); float x1 = x + ci->xoffset * invsize * scalex; float x2 = x1 + ci->width * invsize * scalex; float y1 = y - ci->yoffset * invsize * scaley; float y2 = y1 + ci->height * invsize * scaley; float u1 = ci->x; float u2 = u1 + ci->width; float v1 = ci->y; float v2 = v1 + ci->height; float v[] = {x1, y1, 0, x2, y1, 0, x2, y2, 0, x1, y2, 0}; float t[] = {u1, v1, u2, v1, u2, v2, u1, v2}; int f[] = {0, 1, 2, 0, 2, 3}; if (output_array.GetTexCoordSets() == 0) { output_array.SetFaces(f, 6); output_array.SetVertices(v, 12); output_array.SetTexCoordSets(1); output_array.SetTexCoords(0, t, 8); } else { float * n = 0; output_array.Add(0, 0, n, 0, v, 12, f, 6, t, 8); } return ci->xadvance * invsize * scalex; }
void Starfield::Fill(unsigned long seed) { VertexArray *va = m_model->GetSurface(0)->GetVertices(); va->Clear(); // clear if previously filled // Slight colour variation to stars based on seed MTRand rand(seed); //fill the array for (int i=0; i<BG_STAR_MAX; i++) { float col = float(rand.Double(0.2,0.7)); // this is proper random distribution on a sphere's surface const float theta = float(rand.Double(0.0, 2.0*M_PI)); const float u = float(rand.Double(-1.0, 1.0)); va->Add(vector3f( 1000.0f * sqrt(1.0f - u*u) * cos(theta), 1000.0f * u, 1000.0f * sqrt(1.0f - u*u) * sin(theta) ), Color(col, col, col, 1.f) ); } }
void Camera::DrawSpike(double rad, const vector3d &viewCoords, const matrix4x4d &viewTransform) { // draw twinkly star-thing on faraway objects // XXX this seems like a good case for drawing in 2D - use projected position, then the // "face the camera dammit" bits can be skipped if (!m_renderer) return; const double newdist = m_zNear + 0.5f * (m_zFar - m_zNear); const double scale = newdist / viewCoords.Length(); matrix4x4d trans = matrix4x4d::Identity(); trans.Translate(scale*viewCoords.x, scale*viewCoords.y, scale*viewCoords.z); // face the camera dammit vector3d zaxis = viewCoords.Normalized(); vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized(); vector3d yaxis = zaxis.Cross(xaxis); matrix4x4d rot = matrix4x4d::MakeInvRotMatrix(xaxis, yaxis, zaxis); trans = trans * rot; m_renderer->SetDepthTest(false); m_renderer->SetBlendMode(BLEND_ALPHA_ONE); // XXX this is supposed to pick a correct light colour for the object twinkle. // Not quite correct, since it always uses the first light GLfloat col[4]; glGetLightfv(GL_LIGHT0, GL_DIFFUSE, col); col[3] = 1.f; static VertexArray va(ATTRIB_POSITION | ATTRIB_DIFFUSE); va.Clear(); const Color center(col[0], col[1], col[2], col[2]); const Color edges(col[0], col[1], col[2], 0.f); //center va.Add(vector3f(0.f), center); const float spikerad = float(scale*rad); // bezier with (0,0,0) control points { const vector3f p0(0,spikerad,0), p1(spikerad,0,0); float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) { const vector3f p = (1-t)*(1-t)*p0 + t*t*p1; va.Add(p, edges); } } { const vector3f p0(spikerad,0,0), p1(0,-spikerad,0); float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) { const vector3f p = (1-t)*(1-t)*p0 + t*t*p1; va.Add(p, edges); } } { const vector3f p0(0,-spikerad,0), p1(-spikerad,0,0); float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) { const vector3f p = (1-t)*(1-t)*p0 + t*t*p1; va.Add(p, edges); } } { const vector3f p0(-spikerad,0,0), p1(0,spikerad,0); float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) { const vector3f p = (1-t)*(1-t)*p0 + t*t*p1; va.Add(p, edges); } } glPushMatrix(); m_renderer->SetTransform(trans); m_renderer->DrawTriangles(&va, Graphics::vtxColorMaterial, TRIANGLE_FAN); m_renderer->SetBlendMode(BLEND_SOLID); m_renderer->SetDepthTest(true); glPopMatrix(); }
void HudGauge::Set( SceneNode & parent, const std::tr1::shared_ptr<Texture> & texture, const Font & font, float hwratio, float centerx, float centery, float radius, float startangle, float endangle, float startvalue, float endvalue, float valuedelta) { assert(texture); // calculate number of segments (max 9) float segments = (endvalue - startvalue) / valuedelta; float factor = ceil(segments / 9.0f); segments = ceil(segments / factor); valuedelta = valuedelta * factor; endvalue = startvalue + segments * valuedelta; this->texture = texture; this->centerx = centerx; this->centery = centery; this->scalex = radius * hwratio; this->scaley = radius; this->startangle = startangle; this->endangle = endangle; this->scale = (endangle - startangle) / (endvalue - startvalue); // reset EraseTextDrawable(parent, dialnum_draw); EraseDrawable(parent, pointer_draw); EraseDrawable(parent, dial_draw); pointer_rotated.Clear(); pointer.Clear(); dial_label.Clear(); dial_marks.Clear(); // dial marks { // big marker float pb[] = {-0.02, 1, 0, 0.02, 1, 0, 0.02, 0.92, 0, -0.02, 0.92, 0}; float t[] = {0, 0, 1, 0, 1, 1, 0, 1}; unsigned int f[] = {0, 2, 1, 0, 3, 2}; VertexArray bm; bm.Add(f, 6, pb, 12, t, 8); // small marker float ps[] = {-0.01, 1, 0, 0.01, 1, 0, 0.01, 0.95, 0, -0.01, 0.95, 0}; VertexArray sm; sm.Add(f, 6, ps, 12, t, 8); float delta = (endangle - startangle) / (3.0 * segments); float angle = startangle; for (int i = 0; i <= 3 * segments; ++i) { VertexArray temp = (i % 3) ? sm : bm; temp.Rotate(angle, 0, 0, -1); dial_marks = dial_marks + temp; angle = angle + delta; } dial_marks.Scale(radius * hwratio, radius, 1); dial_marks.Translate(centerx, centery, 0.0); dial_draw = AddDrawable(parent); Drawable & drawref = GetDrawable(parent, dial_draw); drawref.SetTextures(texture->GetId()); drawref.SetVertArray(&dial_marks); drawref.SetCull(false); //drawref.SetColor(1, 1, 1, 0.5); drawref.SetDrawOrder(1); } // dial label { VertexArray temp; float w = 0.25 * radius * hwratio; float h = 0.25 * radius; float angle = startangle; float angle_delta = (endangle - startangle) / segments; float value = startvalue; float value_delta = (endvalue - startvalue) / segments; for (int i = 0; i <= segments; ++i) { std::ostringstream s; s << value; float x = centerx + 0.75 * sin(angle) * radius * hwratio; float y = centery + 0.75 * cos(angle) * radius; float xn = TextDraw::RenderText(font, s.str(), x, y, w, h, temp); temp.Translate((x - xn) * 0.5, 0, 0); dial_label = dial_label + temp; angle += angle_delta; value += value_delta; } dialnum_draw = AddTextDrawable(parent); Drawable & drawref = GetTextDrawable(parent, dialnum_draw); drawref.SetTextures(font.GetFontTexture()->GetId()); drawref.SetVertArray(&dial_label); drawref.SetCull(false); //drawref.SetColor(1, 1, 1, 0.5); drawref.SetDrawOrder(1); } // pointer { float p[] = {-0.015, 0.92, 0, 0.015, 0.92, 0, 0.025, -0.1, 0, -0.025, -0.1, 0}; float t[] = {0, 0, 1, 0, 1, 1, 0, 1}; unsigned int f[] = {0, 2, 1, 0, 3, 2}; pointer.Clear(); pointer.Add(f, 6, p, 12, t, 8); pointer_draw = AddDrawable(parent); Drawable & drawref = GetDrawable(parent, pointer_draw); drawref.SetTextures(texture->GetId()); drawref.SetVertArray(&pointer_rotated); drawref.SetCull(false); //drawref.SetColor(1, 1, 1, 0.5); drawref.SetDrawOrder(2); } }