void Map::setVisibleSize(const Size& visibleSize) { m_visibleSize = visibleSize; if(m_visibleSize.width() > MAX_WIDTH || m_visibleSize.height() > MAX_HEIGHT) m_visibleSize = Size(MAP_VISIBLE_WIDTH, MAP_VISIBLE_HEIGHT); m_centralOffset = Point(std::ceil(m_visibleSize.width() / 2.0), std::ceil(m_visibleSize.height() / 2.0)); m_size = m_visibleSize + Size(3, 3); if(m_framebuffer) m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS)); }
FrameBufferPtr HardwareFactory::CreateFrameBuffer(int width, int height) { return FrameBufferPtr(new ImageWritingFrameBuffer(width, height, FRAME_BUFFER_IMAGE)); }
void SDSMCascadedShadowLayer::UpdateCascades(Camera const & camera, float4x4 const & light_view_proj, float3 const & light_space_border) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); uint32_t const num_cascades = static_cast<uint32_t>(intervals_.size()); uint32_t const copy_index = frame_index_ & 1; uint32_t const read_back_index = (0 == frame_index_) ? copy_index : !copy_index; if (cs_support_) { re.BindFrameBuffer(FrameBufferPtr()); float max_blur_light_space = 8.0f / 1024; float3 max_cascade_scale(max_blur_light_space / light_space_border.x(), max_blur_light_space / light_space_border.y(), std::numeric_limits<float>::max()); int const TILE_DIM = 128; int dispatch_x = (depth_tex_->Width(0) + TILE_DIM - 1) / TILE_DIM; int dispatch_y = (depth_tex_->Height(0) + TILE_DIM - 1) / TILE_DIM; *interval_buff_param_ = interval_buff_; *interval_buff_uint_param_ = interval_buff_; *interval_buff_read_param_ = interval_buff_; *cascade_min_buff_uint_param_ = cascade_min_buff_; *cascade_max_buff_uint_param_ = cascade_max_buff_; *cascade_min_buff_read_param_ = cascade_min_buff_; *cascade_max_buff_read_param_ = cascade_max_buff_; *scale_buff_param_ = scale_buff_; *bias_buff_param_ = bias_buff_; *depth_tex_param_ = depth_tex_; *num_cascades_param_ = static_cast<int32_t>(num_cascades); *inv_depth_width_height_param_ = float2(1.0f / depth_tex_->Width(0), 1.0f / depth_tex_->Height(0)); *near_far_param_ = float2(camera.NearPlane(), camera.FarPlane()); float4x4 const & inv_proj = camera.InverseProjMatrix(); float3 upper_left = MathLib::transform_coord(float3(-1, +1, 1), inv_proj); float3 upper_right = MathLib::transform_coord(float3(+1, +1, 1), inv_proj); float3 lower_left = MathLib::transform_coord(float3(-1, -1, 1), inv_proj); *upper_left_param_ = upper_left; *xy_dir_param_ = float2(upper_right.x() - upper_left.x(), lower_left.y() - upper_left.y()); *view_to_light_view_proj_param_ = camera.InverseViewMatrix() * light_view_proj; *light_space_border_param_ = light_space_border; *max_cascade_scale_param_ = max_cascade_scale; re.Dispatch(*clear_z_bounds_tech_, 1, 1, 1); re.Dispatch(*reduce_z_bounds_from_depth_tech_, dispatch_x, dispatch_y, 1); re.Dispatch(*compute_log_cascades_from_z_bounds_tech_, 1, 1, 1); re.Dispatch(*clear_cascade_bounds_tech_, 1, 1, 1); re.Dispatch(*reduce_bounds_from_depth_tech_, dispatch_x, dispatch_y, 1); re.Dispatch(*compute_custom_cascades_tech_, 1, 1, 1); interval_buff_->CopyToBuffer(*interval_cpu_buffs_[copy_index]); scale_buff_->CopyToBuffer(*scale_cpu_buffs_[copy_index]); bias_buff_->CopyToBuffer(*bias_cpu_buffs_[copy_index]); GraphicsBuffer::Mapper interval_mapper(*interval_cpu_buffs_[read_back_index], BA_Read_Only); GraphicsBuffer::Mapper scale_mapper(*scale_cpu_buffs_[read_back_index], BA_Read_Only); GraphicsBuffer::Mapper bias_mapper(*bias_cpu_buffs_[read_back_index], BA_Read_Only); float2* interval_ptr = interval_mapper.Pointer<float2>(); float3* scale_ptr = scale_mapper.Pointer<float3>(); float3* bias_ptr = bias_mapper.Pointer<float3>(); for (size_t i = 0; i < intervals_.size(); ++ i) { float3 const & scale = scale_ptr[i]; float3 const & bias = bias_ptr[i]; intervals_[i] = interval_ptr[i]; scales_[i] = scale; biases_[i] = bias; } } else { float2 const near_far(camera.NearPlane(), camera.FarPlane()); reduce_z_bounds_from_depth_pp_->SetParam(1, near_far); reduce_z_bounds_from_depth_pp_->Apply(); for (uint32_t i = 1; i < depth_deriative_tex_->NumMipMaps(); ++ i) { int width = depth_deriative_tex_->Width(i - 1); int height = depth_deriative_tex_->Height(i - 1); float delta_x = 1.0f / width; float delta_y = 1.0f / height; float4 delta_offset(delta_x, delta_y, -delta_x / 2, -delta_y / 2); reduce_z_bounds_from_depth_mip_map_pp_->SetParam(0, delta_offset); reduce_z_bounds_from_depth_mip_map_pp_->OutputPin(0, depth_deriative_small_tex_, i - 1); reduce_z_bounds_from_depth_mip_map_pp_->Apply(); int sw = depth_deriative_tex_->Width(i); int sh = depth_deriative_tex_->Height(i); depth_deriative_small_tex_->CopyToSubTexture2D(*depth_deriative_tex_, 0, i, 0, 0, sw, sh, 0, i - 1, 0, 0, sw, sh); } compute_log_cascades_from_z_bounds_pp_->SetParam(1, static_cast<int32_t>(num_cascades)); compute_log_cascades_from_z_bounds_pp_->SetParam(2, near_far); compute_log_cascades_from_z_bounds_pp_->Apply(); interval_tex_->CopyToSubTexture2D(*interval_cpu_texs_[copy_index], 0, 0, 0, 0, num_cascades, 1, 0, 0, 0, 0, num_cascades, 1); Texture::Mapper interval_mapper(*interval_cpu_texs_[read_back_index], 0, 0, TMA_Read_Only, 0, 0, num_cascades, 1); Vector_T<half, 2>* interval_ptr = interval_mapper.Pointer<Vector_T<half, 2> >(); for (size_t i = 0; i < intervals_.size(); ++ i) { float2 const interval(static_cast<float>(interval_ptr[i].x()), static_cast<float>(interval_ptr[i].y())); AABBox aabb = CalcFrustumExtents(camera, interval.x(), interval.y(), light_view_proj); aabb &= AABBox(float3(-1, -1, -1), float3(+1, +1, +1)); aabb.Min() -= light_space_border; aabb.Max() += light_space_border; aabb.Min().x() = +aabb.Min().x() * 0.5f + 0.5f; aabb.Min().y() = -aabb.Min().y() * 0.5f + 0.5f; aabb.Max().x() = +aabb.Max().x() * 0.5f + 0.5f; aabb.Max().y() = -aabb.Max().y() * 0.5f + 0.5f; std::swap(aabb.Min().y(), aabb.Max().y()); float3 const scale = float3(1.0f, 1.0f, 1.0f) / (aabb.Max() - aabb.Min()); float3 const bias = -aabb.Min() * scale; intervals_[i] = interval; scales_[i] = scale; biases_[i] = bias; } } this->UpdateCropMats(); ++ frame_index_; }
void Map::draw(const Rect& rect) { if(!m_framebuffer) { m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS)); program = PainterShaderProgramPtr(new PainterShaderProgram); program->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); program->addShaderFromSourceFile(Shader::Fragment, "/shadertest.frag"); assert(program->link()); } g_painter.setColor(Fw::white); m_framebuffer->bind(); // draw offsets LocalPlayerPtr localPlayer = g_game.getLocalPlayer(); if(localPlayer) m_drawOffset = localPlayer->getWalkOffset(); //TODO: cache first/last visible floor // draw from bottom floors to top floors int firstFloor = getFirstVisibleFloor(); const int lastFloor = MAX_Z-1; for(int iz = lastFloor; iz >= firstFloor; --iz) { // draw tiles like linus pauling's rule order const int numDiagonals = m_size.width() + m_size.height() - 1; for(int diagonal = 0; diagonal < numDiagonals; ++diagonal) { // loop through / diagonal tiles for(int ix = std::min(diagonal, m_size.width() - 1), iy = std::max(diagonal - m_size.width(), 0); ix >= 0 && iy < m_size.height(); --ix, ++iy) { // position on current floor Position tilePos(m_centralPosition.x + (ix - m_centralOffset.x), m_centralPosition.y + (iy - m_centralOffset.y), m_centralPosition.z); // adjust tilePos to the wanted floor tilePos.perspectiveUp(m_centralPosition.z - iz); //TODO: cache visible tiles, m_tiles[] has a high cost (50% fps decrease) if(const TilePtr& tile = m_tiles[tilePos]) { // skip tiles that are behind another tile //if(isCompletlyCovered(tilePos, firstFloor)) // continue; tile->draw(positionTo2D(tilePos) - m_drawOffset); } } } // after drawing all tiles, draw shots for(const MissilePtr& shot : m_missilesAtFloor[iz]) { Position missilePos = shot->getPosition(); shot->draw(positionTo2D(missilePos) - m_drawOffset); } } m_framebuffer->release(); g_painter.setCustomProgram(program); g_painter.setColor(Fw::white); m_framebuffer->draw(rect); g_painter.releaseCustomProgram(); // calculate stretch factor float horizontalStretchFactor = rect.width() / (float)(m_visibleSize.width() * NUM_TILE_PIXELS); float verticalStretchFactor = rect.height() / (float)(m_visibleSize.height() * NUM_TILE_PIXELS); // draw player names and health bars //TODO: this must be cached with creature walks for(int x = 0; x < m_visibleSize.width(); ++x) { for(int y = 0; y < m_visibleSize.height(); ++y) { Position tilePos = Position(m_centralPosition.x + (x - m_centralOffset.x + 1), m_centralPosition.y + (y - m_centralOffset.y + 1), m_centralPosition.z); if(const TilePtr& tile = m_tiles[tilePos]) { auto creatures = tile->getCreatures(); if(creatures.size() == 0) continue; for(const CreaturePtr& creature : creatures) { Point p((m_centralOffset.x - 1 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(), (m_centralOffset.y - 1 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation()); if(creature != localPlayer) { p += creature->getWalkOffset() - m_drawOffset; } creature->drawInformation(rect.x() + p.x*horizontalStretchFactor, rect.y() + p.y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect); } } } } }
void GpuFftCS5::Execute(TexturePtr const & out_real, TexturePtr const & out_imag, TexturePtr const & in_real, TexturePtr const & in_imag) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); FrameBufferPtr old_fb = re.CurFrameBuffer(); re.BindFrameBuffer(FrameBufferPtr()); int index = 0; // X direction { uint32_t istride = width_ / 8; float phase_base = -PI2 / width_; *(effect_->ParameterByName("ostride2")) = uint2(width_ / 8, 0); *(effect_->ParameterByName("iscale2")) = uint2(8, 1); *(effect_->ParameterByName("istride2")) = uint4(istride, 0, istride - 1, static_cast<uint32_t>(-1)); *(effect_->ParameterByName("phase_base2")) = phase_base; this->Radix008A(tmp_real_tex_[index], tmp_imag_tex_[index], in_real, in_imag, width_ / 8, height_, 1 == istride, false); index = !index; uint32_t t = width_; while (t > 8) { istride /= 8; phase_base *= 8; *(effect_->ParameterByName("istride2")) = uint4(istride, 0, istride - 1, static_cast<uint32_t>(-1)); *(effect_->ParameterByName("phase_base2")) = phase_base; this->Radix008A(tmp_real_tex_[index], tmp_imag_tex_[index], tmp_real_tex_[!index], tmp_imag_tex_[!index], width_ / 8, height_, 1 == istride, false); index = !index; t /= 8; } } // Y direction { uint32_t istride = height_ / 8; float phase_base = -PI2 / height_; *(effect_->ParameterByName("ostride2")) = uint2(0, height_ / 8); *(effect_->ParameterByName("iscale2")) = uint2(1, 8); *(effect_->ParameterByName("istride2")) = uint4(0, istride, static_cast<uint32_t>(-1), istride - 1); *(effect_->ParameterByName("phase_base2")) = phase_base; if (1 == istride) { this->Radix008A(out_real, out_imag, tmp_real_tex_[!index], tmp_imag_tex_[!index], width_, height_ / 8, false, 1 == istride); } else { this->Radix008A(tmp_real_tex_[index], tmp_imag_tex_[index], tmp_real_tex_[!index], tmp_imag_tex_[!index], width_, height_ / 8, false, 1 == istride); } index = !index; uint32_t t = height_; while (t > 8) { istride /= 8; phase_base *= 8; *(effect_->ParameterByName("istride2")) = uint4(0, istride, static_cast<uint32_t>(-1), istride - 1); *(effect_->ParameterByName("phase_base2")) = phase_base; if (1 == istride) { this->Radix008A(out_real, out_imag, tmp_real_tex_[!index], tmp_imag_tex_[!index], width_, height_ / 8, false, 1 == istride); } else { this->Radix008A(tmp_real_tex_[index], tmp_imag_tex_[index], tmp_real_tex_[!index], tmp_imag_tex_[!index], width_, height_ / 8, false, 1 == istride); } index = !index; t /= 8; } } re.BindFrameBuffer(old_fb); }
void GpuFftCS4::Execute(TexturePtr const & out_real, TexturePtr const & out_imag, TexturePtr const & in_real, TexturePtr const & in_imag) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); tex_fb_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*out_real, 0, 1, 0)); tex_fb_->Attach(FrameBuffer::ATT_Color1, rf.Make2DRenderView(*out_imag, 0, 1, 0)); FrameBufferPtr old_fb = re.CurFrameBuffer(); re.BindFrameBuffer(FrameBufferPtr()); *real_tex_ep_ = in_real; *imag_tex_ep_ = in_imag; uint32_t const thread_count = 3 * (width_ * height_) / 8; uint32_t ostride = width_ * height_ / 8; uint32_t istride = ostride; uint32_t istride3 = height_ / 8; uint32_t pstride = width_; float phase_base = -PI2 / (width_ * height_); *(effect_->ParameterByName("thread_count")) = thread_count; // X direction *(effect_->ParameterByName("ostride")) = ostride; *(effect_->ParameterByName("pstride")) = pstride; *(effect_->ParameterByName("istride")) = istride; *(effect_->ParameterByName("istride3")) = uint2(0, istride3); *(effect_->ParameterByName("phase_base")) = phase_base; this->Radix008A(tmp_buffer_, src_, thread_count, istride, true); GraphicsBufferPtr buf[2] = { dst_, tmp_buffer_ }; int index = 0; uint32_t t = width_; while (t > 8) { istride /= 8; istride3 /= 8; phase_base *= 8.0f; *(effect_->ParameterByName("istride")) = istride; *(effect_->ParameterByName("istride3")) = uint2(0, istride3); *(effect_->ParameterByName("phase_base")) = phase_base; this->Radix008A(buf[index], buf[!index], thread_count, istride, false); index = !index; t /= 8; } // Y direction ostride = height_ / 8; pstride = 1; *(effect_->ParameterByName("ostride")) = ostride; *(effect_->ParameterByName("pstride")) = pstride; istride /= 8; istride3 /= 8; phase_base *= 8.0f; *(effect_->ParameterByName("istride")) = istride; *(effect_->ParameterByName("istride3")) = uint2(istride3, 0); *(effect_->ParameterByName("phase_base")) = phase_base; this->Radix008A(buf[index], buf[!index], thread_count, istride, false); index = !index; t = height_; while (t > 8) { istride /= 8; istride3 /= 8; phase_base *= 8.0f; *(effect_->ParameterByName("istride")) = istride; *(effect_->ParameterByName("istride3")) = uint2(istride3, 0); *(effect_->ParameterByName("phase_base")) = phase_base; this->Radix008A(buf[index], buf[!index], thread_count, istride, false); index = !index; t /= 8; } re.BindFrameBuffer(tex_fb_); re.Render(*buf2tex_tech_, *quad_layout_); re.BindFrameBuffer(old_fb); }
FrameBufferPtr GLGraphicFactory::createFrameBuffer() const { return FrameBufferPtr(new GLFrameBuffer(true)); }
FrameBufferPtr FrameBuffer::create(gl::FrameBufferPtr inFb) { return FrameBufferPtr(new FrameBuffer(inFb)); }
void FrameSequence::addFrame(void) { frameSequence.push_back(FrameBufferPtr(new Frame(this->xres,this->yres,this->pixelAspectRatio,this->screenAspectRatio))); iFrame = nFrames; nFrames++; }