void Billboard::Render(const matrix4x4f &trans, const RenderData *rd) { Graphics::Renderer *r = GetRenderer(); Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_UV0, 6); const matrix3x3f rot = trans.GetOrient().Transpose(); //some hand-tweaked scaling, to make the lights seem larger from distance const float size = m_size * Graphics::GetFovFactor() * Clamp(trans.GetTranslate().Length() / 500.f, 0.25f, 15.f); const vector3f rotv1 = rot * vector3f(size/2.f, -size/2.f, 0.0f); const vector3f rotv2 = rot * vector3f(size/2.f, size/2.f, 0.0f); va.Add(m_offset-rotv1, vector2f(0.f, 0.f)); //top left va.Add(m_offset-rotv2, vector2f(0.f, 1.f)); //bottom left va.Add(m_offset+rotv2, vector2f(1.f, 0.f)); //top right va.Add(m_offset+rotv2, vector2f(1.f, 0.f)); //top right va.Add(m_offset-rotv2, vector2f(0.f, 1.f)); //bottom left va.Add(m_offset+rotv1, vector2f(1.f, 1.f)); //bottom right r->SetTransform(trans); r->DrawTriangles(&va, m_renderState, m_material.Get()); }
void Billboard::Render(const matrix4x4f &trans, const RenderData *rd) { PROFILE_SCOPED() Graphics::Renderer *r = GetRenderer(); const matrix3x3f rot = trans.GetOrient().Transpose(); //some hand-tweaked scaling, to make the lights seem larger from distance const float size = m_size * Graphics::GetFovFactor() * Clamp(trans.GetTranslate().Length() / 500.f, 0.25f, 15.f); const vector3f rotv1 = rot * vector3f(size*0.5f, -size*0.5f, 0.0f); const vector3f rotv2 = rot * vector3f(size*0.5f, size*0.5f, 0.0f); if( !m_vbuffer.Valid() ) { //create buffer and upload data Graphics::VertexBufferDesc vbd; vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.attrib[1].semantic = Graphics::ATTRIB_UV0; vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT2; vbd.numVertices = 6; vbd.usage = Graphics::BUFFER_USAGE_DYNAMIC; // we could be updating this per-frame m_vbuffer.Reset( r->CreateVertexBuffer(vbd) ); } #pragma pack(push, 4) struct PosUVVert { vector3f pos; vector2f uv; }; #pragma pack(pop) PosUVVert* vtxPtr = m_vbuffer->Map<PosUVVert>(Graphics::BUFFER_MAP_WRITE); vtxPtr[0].pos = (m_offset - rotv1); vtxPtr[0].uv = vector2f(0.f, 0.f); //top left vtxPtr[1].pos = (m_offset - rotv2); vtxPtr[1].uv = vector2f(0.f, 1.f); //bottom left vtxPtr[2].pos = (m_offset + rotv2); vtxPtr[2].uv = vector2f(1.f, 0.f); //top right vtxPtr[3].pos = (m_offset + rotv2); vtxPtr[3].uv = vector2f(1.f, 0.f); //top right vtxPtr[4].pos = (m_offset - rotv2); vtxPtr[4].uv = vector2f(0.f, 1.f); //bottom left vtxPtr[5].pos = (m_offset + rotv1); vtxPtr[5].uv = vector2f(1.f, 1.f); //bottom right m_vbuffer->Unmap(); r->SetTransform(trans); r->DrawBuffer(m_vbuffer.Get(), m_renderState, m_material.Get()); r->GetStats().AddToStatCount(Graphics::Stats::STAT_BILLBOARD, 1); }
void Billboard::Render(const matrix4x4f &trans, const RenderData *rd) { PROFILE_SCOPED() //some hand-tweaked scaling, to make the lights seem larger from distance (final size is in pixels) const float pixrad = Clamp(Graphics::GetScreenHeight() / trans.GetTranslate().Length(), 1.0f, 15.0f); const float size = (m_size * Graphics::GetFovFactor()) * pixrad; m_bbVA.Add(trans * vector3f(0.0f), vector3f(m_colorUVoffset, size)); }
void SystemView::PutBody(SystemBody *b, vector3d offset) { if (b->type == SystemBody::TYPE_STARPORT_SURFACE) return; if (b->type != SystemBody::TYPE_GRAVPOINT) { glGetFloatv (GL_MODELVIEW_MATRIX, &s_invRot[0]); s_invRot[12] = s_invRot[13] = s_invRot[14] = 0; s_invRot = s_invRot.InverseOf(); // Draw a filled circle VertexArray va(ATTRIB_POSITION); Material mat; mat.unlit = true; mat.diffuse = Color(1.f); const double radius = b->GetRadius() * m_zoom; const vector3f offsetf(offset); for (float ang=0; ang<2.0f*float(M_PI); ang+=float(M_PI)*0.05f) { vector3f p = offsetf + s_invRot * vector3f(radius*sin(ang), -radius*cos(ang), 0); va.Add(p); } m_renderer->DrawTriangles(&va, &mat, TRIANGLE_FAN); PutLabel(b, offset); } if (b->children.size()) for(std::vector<SystemBody*>::iterator kid = b->children.begin(); kid != b->children.end(); ++kid) { if (is_zero_general((*kid)->orbit.semiMajorAxis)) continue; if ((*kid)->orbit.semiMajorAxis * m_zoom < ROUGH_SIZE_OF_TURD) { PutOrbit(*kid, offset); } // not using current time yet vector3d pos = (*kid)->orbit.OrbitalPosAtTime(m_time); pos *= double(m_zoom); //glTranslatef(pos.x, pos.y, pos.z); PutBody(*kid, offset + pos); } }
void SystemView::PutBody(SBody *b, vector3d offset) { if (b->type == SBody::TYPE_STARPORT_SURFACE) return; if (b->type != SBody::TYPE_GRAVPOINT) { glGetFloatv (GL_MODELVIEW_MATRIX, &s_invRot[0]); s_invRot[12] = s_invRot[13] = s_invRot[14] = 0; s_invRot = s_invRot.InverseOf(); glColor3f(1,1,1); glBegin(GL_TRIANGLE_FAN); double radius = b->GetRadius() * m_zoom; const vector3f offsetf(offset); for (float ang=0; ang<2.0f*M_PI; ang+=M_PI*0.05f) { vector3f p = offsetf + s_invRot * vector3f(radius*sin(ang), -radius*cos(ang), 0); glVertex3fv(&p.x); } glEnd(); PutLabel(b, offset); } if (b->children.size()) for(std::vector<SBody*>::iterator kid = b->children.begin(); kid != b->children.end(); ++kid) { if (float_is_zero_general((*kid)->orbit.semiMajorAxis)) continue; if ((*kid)->orbit.semiMajorAxis * m_zoom < ROUGH_SIZE_OF_TURD) { PutOrbit(*kid, offset); } // not using current time yet vector3d pos = (*kid)->orbit.OrbitalPosAtTime(m_time); pos *= double(m_zoom); //glTranslatef(pos.x, pos.y, pos.z); PutBody(*kid, offset + pos); } }
void Viewer::MainLoop() { Uint32 lastTurd = SDL_GetTicks(); Uint32 t = SDL_GetTicks(); int numFrames = 0; Uint32 lastFpsReadout = SDL_GetTicks(); g_campos = vector3f(0.0f, 0.0f, m_cmesh->GetBoundingRadius()); g_camorient = matrix4x4f::Identity(); matrix4x4f modelRot = matrix4x4f::Identity(); printf("Geom tree build in %dms\n", SDL_GetTicks() - t); Render::State::SetZnearZfar(1.0f, 10000.0f); for (;;) { PollEvents(); Render::PrepareFrame(); if (g_keyState[SDLK_LSHIFT] || g_keyState[SDLK_RSHIFT]) { if (g_keyState[SDLK_UP]) g_camorient = g_camorient * matrix4x4f::RotateXMatrix(g_frameTime); if (g_keyState[SDLK_DOWN]) g_camorient = g_camorient * matrix4x4f::RotateXMatrix(-g_frameTime); if (g_keyState[SDLK_LEFT]) g_camorient = g_camorient * matrix4x4f::RotateYMatrix(-g_frameTime); if (g_keyState[SDLK_RIGHT]) g_camorient = g_camorient * matrix4x4f::RotateYMatrix(g_frameTime); if (g_mouseButton[3]) { float rx = 0.01f*g_mouseMotion[1]; float ry = 0.01f*g_mouseMotion[0]; g_camorient = g_camorient * matrix4x4f::RotateXMatrix(rx); g_camorient = g_camorient * matrix4x4f::RotateYMatrix(ry); if (g_mouseButton[1]) { g_campos = g_campos - g_camorient * vector3f(0.0f,0.0f,1.0f) * 0.01 * m_model->GetDrawClipRadius(); } } } else { if (g_keyState[SDLK_UP]) modelRot = modelRot * matrix4x4f::RotateXMatrix(g_frameTime); if (g_keyState[SDLK_DOWN]) modelRot = modelRot * matrix4x4f::RotateXMatrix(-g_frameTime); if (g_keyState[SDLK_LEFT]) modelRot = modelRot * matrix4x4f::RotateYMatrix(-g_frameTime); if (g_keyState[SDLK_RIGHT]) modelRot = modelRot * matrix4x4f::RotateYMatrix(g_frameTime); if (g_mouseButton[3]) { float rx = 0.01f*g_mouseMotion[1]; float ry = 0.01f*g_mouseMotion[0]; modelRot = modelRot * matrix4x4f::RotateXMatrix(rx); modelRot = modelRot * matrix4x4f::RotateYMatrix(ry); } } if (g_keyState[SDLK_EQUALS]) g_campos = g_campos - g_camorient * vector3f(0.0f,0.0f,1.0f); if (g_keyState[SDLK_MINUS]) g_campos = g_campos + g_camorient * vector3f(0.0f,0.0f,1.0f); if (g_keyState[SDLK_PAGEUP]) g_campos = g_campos - g_camorient * vector3f(0.0f,0.0f,1.0f); if (g_keyState[SDLK_PAGEDOWN]) g_campos = g_campos + g_camorient * vector3f(0.0f,0.0f,1.0f); // geom->MoveTo(modelRot, vector3d(0.0,0.0,0.0)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float fracH = g_height / (float)g_width; glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SetSbreParams(); int beforeDrawTriStats = LmrModelGetStatsTris(); if (g_renderType == 0) { glPushAttrib(GL_ALL_ATTRIB_BITS); matrix4x4f m = g_camorient.InverseOf() * matrix4x4f::Translation(-g_campos) * modelRot.InverseOf(); if (g_doBenchmark) { for (int i=0; i<1000; i++) m_model->Render(m, ¶ms); } else { m_model->Render(m, ¶ms); } glPopAttrib(); } else if (g_renderType == 1) { glPushMatrix(); matrix4x4f m = g_camorient.InverseOf() * matrix4x4f::Translation(-g_campos) * modelRot.InverseOf(); glMultMatrixf(&m[0]); render_coll_mesh(m_cmesh); glPopMatrix(); } else { matrix4x4f tran = modelRot * g_camorient;//.InverseOf(); vector3d forward = tran * vector3d(0.0,0.0,-1.0); vector3d up = tran * vector3d(0.0,1.0,0.0); raytraceCollMesh(modelRot * g_campos, up, forward, m_space); } Render::State::UseProgram(0); Render::UnbindAllBuffers(); { char buf[128]; Aabb aabb = m_cmesh->GetAabb(); snprintf(buf, sizeof(buf), "%d triangles, collision mesh size: %.1fx%.1fx%.1f (radius %.1f)", (g_renderType == 0 ? LmrModelGetStatsTris() - beforeDrawTriStats : m_cmesh->m_numTris), aabb.max.x-aabb.min.x, aabb.max.y-aabb.min.y, aabb.max.z-aabb.min.z, aabb.GetBoundingRadius()); m_trisReadout->SetText(buf); } Render::PostProcess(); Gui::Draw(); glError(); Render::SwapBuffers(); numFrames++; g_frameTime = (SDL_GetTicks() - lastTurd) * 0.001f; lastTurd = SDL_GetTicks(); if (SDL_GetTicks() - lastFpsReadout > 1000) { int numTris = LmrModelGetStatsTris(); LmrModelClearStatsTris(); printf("%d fps, %.3f Million tris/sec\n", numFrames, numTris/1000000.0f); numFrames = 0; lastFpsReadout = SDL_GetTicks(); } //space->Collide(onCollision); } }