void Button::OnRender(Renderer2D& renderer) { float horizontalPadding = debug::DebugMenu::GetSettings().horizontalPadding * 0.5f; renderer.DrawRect(m_Bounds); renderer.FillRect(m_Bounds, m_State == ButtonState::PRESSED ? 0xcfbbbbbb : 0xcf5f5f5f); renderer.DrawString(m_Label, m_Bounds.position - vec2(m_Bounds.width - horizontalPadding, m_Font->GetHeight(m_Label) * 0.5f), *m_Font); // TODO: Actually use a Label }
void Slider::OnRender(Renderer2D& renderer) { renderer.FillRect(m_Bounds, 0xcf7f7f7f); renderer.DrawRect(m_Bounds); renderer.FillRect(m_HeadBounds, 0xcfbfbfbf); renderer.DrawRect(m_HeadBounds); vec2 offset = m_Vertical ? vec2(0, m_Bounds.size.y / 2.0f) : vec2(m_Bounds.size.x / 2.0f, 0); renderer.DrawLine(m_Bounds.Center() - offset, m_Bounds.Center() + offset); }
void CheckDrawableVisibility(const WorkItem* item, unsigned threadIndex) { Renderer2D* renderer = reinterpret_cast<Renderer2D*>(item->aux_); Drawable2D** start = reinterpret_cast<Drawable2D**>(item->start_); Drawable2D** end = reinterpret_cast<Drawable2D**>(item->end_); while (start != end) { Drawable2D* drawable = *start++; if (renderer->CheckVisibility(drawable)) drawable->MarkInView(renderer->frame_); } }
void HudItemDesc::onDraw(Renderer2D &out) const { HudLayer::onDraw(out); FRect rect = this->rect(); if(!m_item.isDummy()) { float ypos = topOffset() + rect.y(); FRect uv_rect; auto texture = m_item.guiImage(false, uv_rect); float2 size(texture->width() * uv_rect.width(), texture->height() * uv_rect.height()); float2 pos = (float2)(int2)(float2(rect.center().x - size.x * 0.5f, ypos)); out.addFilledRect(FRect(pos, pos + size), uv_rect, {texture, mulAlpha(ColorId::white, alpha())}); ypos += size.y + 10.0f; FRect desc_rect(rect.x() + 5.0f, ypos, rect.ex() - 5.0f, rect.ey() - 5.0f); // TODO: fix drawing of text that does not fit string params_desc; if(m_item.type() == ItemType::weapon) params_desc = Weapon(m_item).paramDesc(); else if(m_item.type() == ItemType::ammo) params_desc = Ammo(m_item).paramDesc(); else if(m_item.type() == ItemType::armour) params_desc = Armour(m_item).paramDesc(); m_font->draw(out, float2(rect.x() + 5.0f, ypos), {titleColor(), titleShadowColor()}, params_desc); } }
void Test2D::OnInit(Renderer2D& renderer, Material& material) { // m_Window->SetVsync(false); m_Renderer = &renderer; renderer.SetRenderTarget(RenderTarget::SCREEN); //renderer.AddPostEffectsPass(new PostEffectsPass(Shader::CreateFromFile("Horizontal Blur", "shaders/postfx.shader"))); //renderer.SetPostEffects(false); TextureParameters params(TextureFilter::NEAREST); Add(spnew Sprite(4.0f, 4.0f, 4, 4, Texture2D::CreateFromFile("Tex", "res/tb.png", params))); Add(spnew Sprite(-5.0f, -5.0f, 3, 3, 0xffff00ff)); FontManager::Add(spnew Font("Consolas", "res/consola.ttf", 96)); FontManager::Add(spnew Font("Brush Script", "res/BrushScriptStd.otf", 96)); m_DebugInfo = spnew Label*[10]; Add(m_DebugInfo[0] = spnew Label("", -15.5f, 8.5f, 0xffffffff)); Add(m_DebugInfo[1] = spnew Label("", -15.5f, 7.5f, 0xffffffff)); Add(m_DebugInfo[2] = spnew Label("", -15.5f, 6.5f, 0xffffffff)); Add(m_DebugInfo[3] = spnew Label("", -15.5f, 5.5f, 0xffffffff)); Add(m_DebugInfo[4] = spnew Label("", -15.5f, 4.5f, 0xffffffff)); Add(spnew Label("Consolas", -15.5f, 0.0f, FontManager::Get("Consolas"), 0xffffffff)); Add(spnew Label("Brush Script", -15.5f, 2.0f, FontManager::Get("Brush Script"), 0xffffffff)); Texture::SetWrap(TextureWrap::CLAMP_TO_BORDER); Mask* mask = spnew Mask(Texture2D::CreateFromFile("Mask", "res/mask.png")); mask->transform = mat4::Translate(vec3(-16.0f, -9.0f, 0.0f)) * mat4::Scale(vec3(32, 18, 1)); SetMask(mask); }
void Window::draw(Renderer2D &out) const { out.setViewPos(-m_clipped_rect.min); out.setScissorRect(m_clipped_rect); if(m_background_color.a > 0.0f && !(m_background && m_background->size() == m_rect.size())) out.addFilledRect(IRect(m_clipped_rect.size()), m_background_color); if(m_background) out.addFilledRect(IRect(m_background->size()), m_background); drawContents(out); out.setViewPos(-m_clipped_rect.min); if(m_has_inner_rect) { int2 rsize = m_rect.size(); int2 isize = m_inner_rect.size(); auto col1 = WindowStyle::gui_dark; auto col2 = WindowStyle::gui_light; col1 = FColor(col1.rgb() * 0.8f, 0.5f); col2 = FColor(col2.rgb() * 1.333f, 0.5f); // TODO: minimum size of progress bar, coz sometimes its almost invisible if(isize.x > rsize.x) { float divisor = 1.0f / float(isize.x); float spos = float(0 - m_inner_rect.min.x) * divisor; float epos = float(rsize.x - m_inner_rect.min.x) * divisor; out.addFilledRect(IRect(0, rsize.y - 5, rsize.x, rsize.y), col1); out.addFilledRect(IRect(spos * rsize.x, rsize.y - 5, (spos + epos) * rsize.x, rsize.y), col2); } if(isize.y > rsize.y) { float divisor = 1.0f / float(isize.y); float spos = float(0 - m_inner_rect.min.y) * divisor; float epos = float(rsize.y - m_inner_rect.min.y) * divisor; out.addFilledRect(IRect(rsize.x - 5, 0, rsize.x, rsize.y), col1); out.addFilledRect(IRect(rsize.x - 5, spos * rsize.y, rsize.x, epos * rsize.y), col2); } } for(int n = 0; n < (int)m_children.size(); n++) if(m_children[n]->isVisible()) m_children[n]->draw(out); if(!m_parent) out.setScissorRect(none); }
void ImageButton::drawContents(Renderer2D &out) const { bool is_pressed = m_mode == mode_toggle? m_is_pressed ^ m_mouse_press : m_mode == mode_toggle_on? m_is_pressed || m_mouse_press : m_mouse_press; if(is_pressed) out.addFilledRect(IRect(m_proto.down->size()), m_proto.down); else out.addFilledRect(IRect(m_proto.up->size()), m_proto.up); if(m_proto.font) { int2 rect_center = size() / 2; int2 pos(m_proto.text_rect.min.x - 1, m_proto.text_rect.center().y - m_text_extents.height() / 2 - 1); if(m_mouse_press) pos += int2(2, 2); m_proto.font->draw(out, pos, {m_is_enabled? Color(255, 200, 0) : Color::gray, Color::black}, m_text); } }
void Window::drawWindow(Renderer2D &out, IRect rect, FColor color, int outline) { FColor lighter(color.rgb() * 1.2f, color.a); FColor darker(color.rgb() * 0.8f, color.a); int aoutline = fwk::abs(outline); if(outline) { int2 hsize(rect.width(), aoutline); int2 vsize(aoutline, rect.height()); FColor col1 = outline < 0? darker : lighter; out.addFilledRect(IRect(rect.min, rect.min + hsize), col1); out.addFilledRect(IRect(rect.min, rect.min + vsize), col1); int2 p1(rect.min.x, rect.max.y - aoutline); int2 p2(rect.max.x - aoutline, rect.min.y); FColor col2 = outline < 0? lighter : darker; out.addFilledRect(IRect(p1, p1 + hsize), col2); out.addFilledRect(IRect(p2, p2 + vsize), col2); } int2 off(aoutline, aoutline); out.addFilledRect(inset(rect, off, off), color); }
void MultiPlayerMenu::onDraw(Renderer2D &out) const { FRect back_quad((float2)m_window_size); out.addFilledRect(back_quad, mulAlpha(ColorId::black, m_visible_time * 0.8f)); HudLayer::onDraw(out); if(!m_message.empty()) { double msg_time = getTime() - m_message_time; double alpha = min(1.0, 5.0 - msg_time); if(msg_time < 5.0) m_font->draw(out, rect() + float2(spacing, 0.0f), {mulAlpha(m_message_color, alpha), mulAlpha(ColorId::black, alpha), HAlign::left, VAlign::bottom}, m_message); } }
void TestLayer::OnInit(Renderer2D& renderer, Shader& shader) { // m_Window->SetVsync(false); m_Renderer = &renderer; renderer.SetRenderTarget(RenderTarget::BUFFER); renderer.AddPostEffectsPass(new PostEffectsPass(Shader::FromFile("Horizontal Blur", "shaders/postfx.shader"))); renderer.SetPostEffects(false); Texture::SetFilter(TextureFilter::NEAREST); Add(new Sprite(0.0f, 0.0f, 8, 8, new Texture("Tex", "res/tb.png"))); Add(new Sprite(-8.0f, -8.0f, 6, 6, 0xffff00ff)); debugInfo = new Label*[10]; debugInfo[0] = new Label("", -15.5f, 6.8f, 0xffffffff); debugInfo[1] = new Label("", -15.5f, 5.8f, 0xffffffff); Add(debugInfo[0]); Add(debugInfo[1]); Texture::SetWrap(TextureWrap::CLAMP_TO_BORDER); Mask* mask = new Mask(new Texture("Mask", "res/mask.png")); mask->transform = mat4::Translate(vec3(-16.0f, -9.0f, 0.0f)) * mat4::Scale(vec3(32, 18, 1)); SetMask(mask); }
void HudItemButton::onDraw(Renderer2D &out) const { HudButton::onDraw(out); FRect rect = this->rect(); if(!m_entry.item.isDummy()) { FRect uv_rect; auto texture = m_entry.item.guiImage(true, uv_rect); float2 size(texture->width() * uv_rect.width(), texture->height() * uv_rect.height()); float2 pos = (float2)(int2)(rect.center() - size / 2); out.addFilledRect(FRect(pos, pos + size), texture); if(m_entry.count > 1) m_font->draw(out, rect, {textColor(), textShadowColor(), HAlign::right}, format("%", m_entry.count)); if(isDropping()) m_font->draw(out, rect, {textColor(true), textShadowColor(), HAlign::left, VAlign::bottom}, format("-%", dropCount())); } }
void HudWeapon::onDraw(Renderer2D &out) const { HudButton::onDraw(out); FRect rect = this->rect(); if(!m_weapon.isDummy()) { FRect uv_rect; auto texture = m_weapon.guiImage(false, uv_rect); float2 size(texture->width() * uv_rect.width(), texture->height() * uv_rect.height()); float2 pos = (int2)(rect.center() - size / 2); out.addFilledRect(FRect(pos, pos + size), uv_rect, {texture, Color::white}); //TODO: print current attack mode if(m_weapon.proto().max_ammo) { TextFormatter fmt; fmt("%d/%d", m_ammo_count, m_weapon.proto().max_ammo); //TODO: alpha for shadow color m_font->draw(out, rect, {m_style.enabled_color, Color::black, HAlign::right, VAlign::top}, fmt); } } }
void TileSelector::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const Tile *tile = m_tile_list[n].tile; IRect tile_rect = tile->rect(); int2 pos = m_tile_list[n].pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) tile->draw(out, pos); } if(m_selection) { int2 pos = m_selection->pos - offset; out.setViewPos(-clippedRect().min - pos + m_selection->tile->rect().min); IBox box(int3(0, 0, 0), m_selection->tile->bboxSize()); drawBBox(out, box); // out.addFilledRect(IRect(pos, pos + m_selection->size)); } }
void Text::draw(glm::ivec2 position, Renderer2D &renderer) { renderer.draw(position, text, color, font); }
void Image::draw(glm::ivec2 position, glm::ivec2 size, Renderer2D &renderer) { renderer.draw(position, size, texture); }
void Color::draw(glm::ivec2 position, glm::ivec2 size, Renderer2D &renderer) { renderer.draw(position, size, color); }
void GroupEditor::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); for(int n = 0; n < m_tile_group->entryCount(); n++) m_tile_group->entryTile(n)->m_temp = n; IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; entry.is_selected = m_mode == mAddRemove? m_tile_group->isValidEntryId(entry.tile->m_temp, entry.tile) : entry.group_id == m_selected_group_id; IRect tile_rect = entry.tile->rect(); int2 pos = entry.pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) entry.tile->draw(out, pos); } DTexture::unbind(); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; if(!entry.is_selected) continue; Color col = m_tile_group->isEntryDirty(entry.tile->m_temp)? ColorId::red : ColorId::white; int2 pos = entry.pos - offset; out.addRect(IRect(pos, pos + entry.size), col); } if(m_mode == mModify && m_selected_group_id != -1) { IRect edit_rect(clippedRect().max - int2(280, 250), clippedRect().max - int2(5, 0)); int2 center = edit_rect.center(); out.setViewPos(-center); int2 half_size = edit_rect.size() / 2; out.addFilledRect(IRect(-half_size, half_size), FColor(0.3f, 0.3f, 0.3f)); drawBBox(out, IBox({-9, 0, -9}, {9, 1, 9}), ColorId::white); auto font = res::getFont(WindowStyle::fonts[0]); for(int n = 0; n < TileGroup::Group::side_count; n++) { out.setViewPos(-center - worldToScreen(TileGroup::Group::s_side_offsets[n] * 9)); font->draw(out, float2(0, 0), {ColorId::white}, format("%d", m_tile_group->groupSurface(m_selected_group_id, n))); } out.setViewPos(-center +edit_rect.size() / 2); font->draw(out, float2(0, 0), {ColorId::white}, format("setting surface: %d", m_selected_surface_id)); /* const char *names[] = { "", "snow", "gravel", "dirt", "grass", "mud", "mud_cracked", "sand", "green goo", }; out.setViewPos(-int2(bottom_rect.max.x - 200, bottom_rect.min.y)); for(int n = 0; n < arraySize(names); n++) font->draw(int2(0, 10), ColorId::white, m_selected_surface_id == n? "%d: [%s]\n" : "%d: %s\n", n, names[n]); */ out.setViewPos(-clippedRect().min); } if(m_current_entry) m_font->draw(out, float2(5, height() - 20), {ColorId::white, ColorId::black}, format("%s", m_current_entry->tile->resourceName().c_str())); }
void EntitiesEditor::drawContents(Renderer2D &out) const { m_view.updateVisibility(); SceneRenderer renderer(clippedRect(), m_view.pos()); { vector<int> visible_ids; visible_ids.reserve(1024); m_tile_map.findAll(visible_ids, renderer.targetRect(), Flags::all | Flags::visible); for(int i = 0; i < (int)visible_ids.size(); i++) { auto &object = m_tile_map[visible_ids[i]]; int3 pos(object.bbox.min); object.ptr->addToRender(renderer, pos, Color::white); } visible_ids.clear(); m_entity_map.findAll(visible_ids, renderer.targetRect(), Flags::all | Flags::visible); vector<char> selection_map(m_entity_map.size(), 0); vector<float3> old_positions(m_selected_ids.size()); for(int n = 0; n < (int)m_selected_ids.size(); n++) { selection_map[m_selected_ids[n]] = 1; visible_ids.push_back(m_selected_ids[n]); if(m_is_moving) { auto &object = m_entity_map[m_selected_ids[n]]; old_positions[n] = object.ptr->pos(); object.ptr->setPos(old_positions[n] + float3(m_move_offset)); m_entity_map.update(m_selected_ids[n]); } } sort(visible_ids.begin(), visible_ids.end()); visible_ids.resize(std::unique(visible_ids.begin(), visible_ids.end()) - visible_ids.begin()); for(int n = 0; n < (int)visible_ids.size(); n++) { auto &object = m_entity_map[visible_ids[n]]; float3 old_pos = object.ptr->pos(); bool is_selected = selection_map[visible_ids[n]]; FBox bbox = object.ptr->boundingBox(); if(object.ptr->typeId() == EntityId::trigger) { renderer.addBox(bbox, Color(Color::green, 64), true); renderer.addBox(FBox(bbox.min + float3(0.1, 0.1, 0.1), bbox.max - float3(0.1, 0.1, 0.1)), Color::green); } else { object.ptr->addToRender(renderer); } bool is_colliding = m_tile_map.findAny(bbox) != -1 || m_entity_map.findAny(bbox, visible_ids[n]) != -1; if(is_colliding) renderer.addBox(bbox, Color::red); if(is_selected) { if(!is_colliding) renderer.addBox(bbox, Color::white); FBox overground_box = computeOvergroundBox(bbox); if(!overground_box.isEmpty()) renderer.addBox(overground_box, Color::yellow); } } if(m_is_moving) for(int n = 0; n < (int)m_selected_ids.size(); n++) { auto &object = m_entity_map[m_selected_ids[n]]; object.ptr->setPos(old_positions[n]); m_entity_map.update(m_selected_ids[n]); } } if(m_proto && m_mode == Mode::placing) { m_proto->setPos(m_cursor_pos); m_proto->addToRender(renderer); FBox bbox = m_proto->boundingBox(); bool is_colliding = m_tile_map.findAny(bbox) != -1 || m_entity_map.findAny(bbox) != -1; renderer.addBox(bbox, is_colliding? Color::red : Color::white); if(bbox.max.y == bbox.min.y) bbox.max.y += 1.0f; FBox overground_box = computeOvergroundBox(bbox); if(!overground_box.isEmpty()) renderer.addBox(overground_box, Color::yellow); } renderer.render(); if(m_mode == Mode::selecting && m_is_selecting) out.addRect(m_selection - m_view.pos(), Color::white); out.setScissorRect(clippedRect()); out.setViewPos(-clippedRect().min + m_view.pos()); m_view.drawGrid(out); out.setViewPos(-clippedRect().min); auto font = res::getFont(WindowStyle::fonts[1]); font->draw(out, int2(0, clippedRect().height() - 25), {Color::white, Color::black}, format("Cursor: (%.0f, %.0f, %.0f) Grid: %d Mode: %s\n", m_cursor_pos.x, m_cursor_pos.y, m_cursor_pos.z, m_view.gridHeight(), EntitiesEditorMode::toString(m_mode))); }
void GameController::gameLoop() { //set program scale. View::Camera camera; camera.scale = Vec2(1.f, 1.f); screenHeight *= camera.scale.y; screenWidth *= camera.scale.x; Vec2 boarder = Vec2((screenWidth / 2) - (boarderMargin * camera.scale.x), (screenHeight / 2) - (boarderMargin * camera.scale.y)); Vec2 origin = Vec2(screenWidth / 2, screenHeight / 2); wParams.mFullscreen = false; wParams.mHeight = screenHeight; wParams.mWidth = screenWidth; wParams.mTitle = "Laboration 3"; wParams.mPosX = 0; wParams.mPosY = 0; if (common.init(wParams)) { //Load all textures common.registerTextureResource("smoke", "image/particlesmoke.tga"); common.registerTextureResource("spark", "image/spark.png"); common.registerTextureResource("explosion", "image/explosion.png"); common.registerTextureResource("ball", "image/ball.png"); common.registerSoundResource("shoot", "sound/fire.wav"); EventManager em; common.setEventProcessor(&em); Graphics *g = common.getGraphics(); g->setViewport(0, 0, screenWidth, screenHeight); Renderer2D *renderer = g->createRenderer2D(); float rot = 0.0f; HiResTimer timer; timer.restart(); const float TIME_STEP = 1.0 / 60.0f; float accumulator = 0.0f; float accumulatorKeyPress = 0.0f; float oldAccumulatorKeyPress = 0.0f; while (gRunning) { common.getInputState(&inputState); if (inputState.isDown(Button::BUTTON_ESCAPE)) { gRunning = 0; } common.frame(); timer.tick(); g->clear(Color::White, true); accumulator += timer.getDeltaSeconds(); //setting timer for key pressing. accumulatorKeyPress += timer.getDeltaSeconds(); //Identify key press. if (accumulatorKeyPress - oldAccumulatorKeyPress > .5f) { if (inputState.isDown(Button::BUTTON_MOUSELEFT)) { oldAccumulatorKeyPress = accumulatorKeyPress; splitter.push_back(new View::SplitterSystem(common, camera.scale, Vec2(screenWidth, screenHeight), Vec2(inputState.mMouseX, inputState.mMouseY))); smoke.push_back(new View::SmokeSystem(common, camera.scale, Vec2(screenWidth, screenHeight), Vec2(inputState.mMouseX, inputState.mMouseY))); common.getAudio(); } } while (accumulator >= TIME_STEP) { accumulator -= TIME_STEP; for (int i = 0; i != splitter.size(); ++i) { splitter[i]->UpdateEmitter(TIME_STEP); smoke[i]->UpdateEmitter(TIME_STEP); } } renderer->begin(Renderer2D::SPRITE_SORT_DEFERRED, Renderer2D::SPRITE_BLEND_ALPHA); for (int i = 0; i != splitter.size(); ++i) { splitter[i]->RenderEmitter(renderer); smoke[i]->RenderEmitter(renderer); } rot += timer.getDeltaSeconds() * 0.1f; renderer->end(); g->present(); } } }
void Test2D::OnRender(Renderer2D& renderer) { m_DebugInfo[0]->SetText(String("Target: ") + (renderer.GetRenderTarget() == RenderTarget::SCREEN ? "Screen" : "Buffer")); m_DebugInfo[1]->SetText(String("PostFX: ") + (renderer.GetPostEffects() ? "On" : "Off")); }
void TestLayer::OnRender(Renderer2D& renderer) { debugInfo[0]->text = String("Target: ") + (renderer.GetRenderTarget() == RenderTarget::SCREEN ? "Screen" : "Buffer"); debugInfo[1]->text = String("PostFX: ") + (renderer.GetPostEffects() ? "On" : "Off"); }
void gameLoop() { wParams.mFullscreen = false; wParams.mHeight = screenHeight; wParams.mWidth = screenWidth; wParams.mTitle = "Laboration 2"; wParams.mPosX = 0; wParams.mPosY = 0; if (common.init(wParams)) { common.registerTextureResource("explosion", "image/explosion.png"); EventManager em; common.setEventProcessor(&em); Graphics *g = common.getGraphics(); g->setViewport(0, 0, screenWidth, screenHeight); Renderer2D *renderer = g->createRenderer2D(); float rot = 0.0f; HiResTimer timer; timer.restart(); //Set program scale. AnimationSystem animationSystem(common); const float TIME_STEP = 1.0 / 50.0f; float accumulator = 0.0f; while (gRunning) { common.getInputState(&inputState); if (inputState.isDown(Button::BUTTON_ESCAPE)) { gRunning = 0; } common.frame(); timer.tick(); g->clear(Color::Black, true); accumulator += timer.getDeltaSeconds(); while (accumulator >= TIME_STEP) { accumulator -= TIME_STEP; animationSystem.UpdateEmitter(TIME_STEP); } renderer->begin(Renderer2D::SPRITE_SORT_DEFERRED, Renderer2D::SPRITE_BLEND_ALPHA); animationSystem.RenderEmitter(renderer); rot += timer.getDeltaSeconds() * 0.1f; renderer->end(); g->present(); } animationSystem.FreeMem(); } }