Example #1
0
void DebugRenderer::Render()
{
    if (!HasContent())
        return;

    Graphics* graphics = context_->m_Graphics.get();
    // Engine does not render when window is closed or device is lost
    assert(graphics && graphics->IsInitialized() && !graphics->IsDeviceLost());

    URHO3D_PROFILE(RenderDebugGeometry);

    ShaderVariation* vs = graphics->GetShader(VS, "Basic", "VERTEXCOLOR");
    ShaderVariation* ps = graphics->GetShader(PS, "Basic", "VERTEXCOLOR");

    unsigned numVertices = (lines_.size() + noDepthLines_.size()) * 2 + (triangles_.size() + noDepthTriangles_.size()) * 3;
    // Resize the vertex buffer if too small or much too large
    if (vertexBuffer_->GetVertexCount() < numVertices || vertexBuffer_->GetVertexCount() > numVertices * 2)
        vertexBuffer_->SetSize(numVertices, MASK_POSITION | MASK_COLOR, true);

    float* dest = (float*)vertexBuffer_->Lock(0, numVertices, true);
    if (!dest)
        return;

    for (unsigned i = 0; i < lines_.size(); ++i)
    {
        const DebugLine& line = lines_[i];

        dest[0] = line.start_.x_;
        dest[1] = line.start_.y_;
        dest[2] = line.start_.z_;
        ((unsigned&)dest[3]) = line.color_;
        dest[4] = line.end_.x_;
        dest[5] = line.end_.y_;
        dest[6] = line.end_.z_;
        ((unsigned&)dest[7]) = line.color_;

        dest += 8;
    }

    for (unsigned i = 0; i < noDepthLines_.size(); ++i)
    {
        const DebugLine& line = noDepthLines_[i];

        dest[0] = line.start_.x_;
        dest[1] = line.start_.y_;
        dest[2] = line.start_.z_;
        ((unsigned&)dest[3]) = line.color_;
        dest[4] = line.end_.x_;
        dest[5] = line.end_.y_;
        dest[6] = line.end_.z_;
        ((unsigned&)dest[7]) = line.color_;

        dest += 8;
    }

    for (unsigned i = 0; i < triangles_.size(); ++i)
    {
        const DebugTriangle& triangle = triangles_[i];

        dest[0] = triangle.v1_.x_;
        dest[1] = triangle.v1_.y_;
        dest[2] = triangle.v1_.z_;
        ((unsigned&)dest[3]) = triangle.color_;

        dest[4] = triangle.v2_.x_;
        dest[5] = triangle.v2_.y_;
        dest[6] = triangle.v2_.z_;
        ((unsigned&)dest[7]) = triangle.color_;

        dest[8] = triangle.v3_.x_;
        dest[9] = triangle.v3_.y_;
        dest[10] = triangle.v3_.z_;
        ((unsigned&)dest[11]) = triangle.color_;

        dest += 12;
    }

    for (unsigned i = 0; i < noDepthTriangles_.size(); ++i)
    {
        const DebugTriangle& triangle = noDepthTriangles_[i];

        dest[0] = triangle.v1_.x_;
        dest[1] = triangle.v1_.y_;
        dest[2] = triangle.v1_.z_;
        ((unsigned&)dest[3]) = triangle.color_;

        dest[4] = triangle.v2_.x_;
        dest[5] = triangle.v2_.y_;
        dest[6] = triangle.v2_.z_;
        ((unsigned&)dest[7]) = triangle.color_;

        dest[8] = triangle.v3_.x_;
        dest[9] = triangle.v3_.y_;
        dest[10] = triangle.v3_.z_;
        ((unsigned&)dest[11]) = triangle.color_;

        dest += 12;
    }

    vertexBuffer_->Unlock();

    graphics->SetBlendMode(lineAntiAlias_ ? BLEND_ALPHA : BLEND_REPLACE);
    graphics->SetColorWrite(true);
    graphics->SetCullMode(CULL_NONE);
    graphics->SetDepthWrite(true);
    graphics->SetLineAntiAlias(lineAntiAlias_);
    graphics->SetScissorTest(false);
    graphics->SetStencilTest(false);
    graphics->SetShaders(vs, ps);
    graphics->SetShaderParameter(VSP_MODEL, Matrix3x4::IDENTITY);
    graphics->SetShaderParameter(VSP_VIEW, view_);
    graphics->SetShaderParameter(VSP_VIEWINV, view_.Inverse());
    graphics->SetShaderParameter(VSP_VIEWPROJ, gpuProjection_ * view_);
    graphics->SetShaderParameter(PSP_MATDIFFCOLOR, Color(1.0f, 1.0f, 1.0f, 1.0f));
    graphics->SetVertexBuffer(vertexBuffer_);

    unsigned start = 0;
    unsigned count = 0;
    if (!lines_.empty())
    {
        count = lines_.size() * 2;
        graphics->SetDepthTest(CMP_LESSEQUAL);
        graphics->Draw(LINE_LIST, start, count);
        start += count;
    }
    if (!noDepthLines_.empty())
    {
        count = noDepthLines_.size() * 2;
        graphics->SetDepthTest(CMP_ALWAYS);
        graphics->Draw(LINE_LIST, start, count);
        start += count;
    }

    graphics->SetBlendMode(BLEND_ALPHA);
    graphics->SetDepthWrite(false);

    if (!triangles_.empty())
    {
        count = triangles_.size() * 3;
        graphics->SetDepthTest(CMP_LESSEQUAL);
        graphics->Draw(TRIANGLE_LIST, start, count);
        start += count;
    }
    if (!noDepthTriangles_.empty())
    {
        count = noDepthTriangles_.size() * 3;
        graphics->SetDepthTest(CMP_ALWAYS);
        graphics->Draw(TRIANGLE_LIST, start, count);
    }
    graphics->SetLineAntiAlias(false); //todo: only set this to false if we switched it on
}
Example #2
0
void DebugRenderer::Render()
{
    if (lines_.Empty() && noDepthLines_.Empty())
        return;

    Graphics* graphics = GetSubsystem<Graphics>();
    Renderer* renderer = GetSubsystem<Renderer>();

    if (!graphics || graphics->IsDeviceLost())
        return;

    PROFILE(RenderDebugGeometry);

    // Cache shaders
    if (!vs_)
        vs_ = renderer->GetVertexShader("Basic_VCol");
    if (!ps_)
        ps_ = renderer->GetPixelShader("Basic_VCol");
    
    unsigned numVertices = (lines_.Size() + noDepthLines_.Size()) * 2;
    // Resize the vertex buffer if too small or much too large
    if (vertexBuffer_->GetVertexCount() < numVertices || vertexBuffer_->GetVertexCount() > numVertices * 2)
        vertexBuffer_->SetSize(numVertices, MASK_POSITION | MASK_COLOR, true);

    float* dest = (float*)vertexBuffer_->Lock(0, numVertices, true);
    if (!dest)
        return;

    for (unsigned i = 0; i < lines_.Size(); ++i)
    {
        const DebugLine& line = lines_[i];

        *dest++ = line.start_.x_; *dest++ = line.start_.y_; *dest++ = line.start_.z_;
        *((unsigned*)dest) = line.color_; dest++;

        *dest++ = line.end_.x_; *dest++ = line.end_.y_; *dest++ = line.end_.z_;
        *((unsigned*)dest) = line.color_; dest++;
    }

    for (unsigned i = 0; i < noDepthLines_.Size(); ++i)
    {
        const DebugLine& line = noDepthLines_[i];

        *dest++ = line.start_.x_; *dest++ = line.start_.y_; *dest++ = line.start_.z_;
        *((unsigned*)dest) = line.color_; dest++;

        *dest++ = line.end_.x_; *dest++ = line.end_.y_; *dest++ = line.end_.z_;
        *((unsigned*)dest) = line.color_; dest++;
    }

    vertexBuffer_->Unlock();

    graphics->SetBlendMode(BLEND_REPLACE);
    graphics->SetColorWrite(true);
    graphics->SetCullMode(CULL_NONE);
    graphics->SetDepthWrite(true);
    graphics->SetScissorTest(false);
    graphics->SetStencilTest(false);
    graphics->SetShaders(vs_, ps_);
    graphics->SetShaderParameter(VSP_MODEL, Matrix3x4::IDENTITY);
    graphics->SetShaderParameter(VSP_VIEWPROJ, projection_ * view_);
    graphics->SetShaderParameter(PSP_MATDIFFCOLOR, Color(1.0f, 1.0f, 1.0f, 1.0f));
    graphics->SetVertexBuffer(vertexBuffer_);

    if (lines_.Size())
    {
        graphics->SetDepthTest(CMP_LESSEQUAL);
        graphics->Draw(LINE_LIST, 0, lines_.Size() * 2);
    }
    if (noDepthLines_.Size())
    {
        graphics->SetDepthTest(CMP_ALWAYS);
        graphics->Draw(LINE_LIST, lines_.Size() * 2, noDepthLines_.Size() * 2);
    }
}
void PlayerGraphics::Update( Actor& a, Graphics& g	) {
	
	g.Draw( mdl, skltn, position, rotation, scale );
}
Example #4
0
void BatchGroup::Draw(View* view) const
{
    Graphics* graphics = view->GetGraphics();
    Renderer* renderer = view->GetRenderer();
    
    if (instances_.Size() && !geometry_->IsEmpty())
    {
        // Draw as individual objects if instancing not supported
        VertexBuffer* instanceBuffer = renderer->GetInstancingBuffer();
        if (!instanceBuffer || geometryType_ != GEOM_INSTANCED)
        {
            Batch::Prepare(view, false);
            
            graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
            graphics->SetVertexBuffers(geometry_->GetVertexBuffers(), geometry_->GetVertexElementMasks());
            
            for (unsigned i = 0; i < instances_.Size(); ++i)
            {
                if (graphics->NeedParameterUpdate(SP_OBJECTTRANSFORM, instances_[i].worldTransform_))
                    graphics->SetShaderParameter(VSP_MODEL, *instances_[i].worldTransform_);
                
                graphics->Draw(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(), geometry_->GetIndexCount(),
                    geometry_->GetVertexStart(), geometry_->GetVertexCount());
            }
        }
        else
        {
            Batch::Prepare(view, false);
            
            // Get the geometry vertex buffers, then add the instancing stream buffer
            // Hack: use a const_cast to avoid dynamic allocation of new temp vectors
            Vector<SharedPtr<VertexBuffer> >& vertexBuffers = const_cast<Vector<SharedPtr<VertexBuffer> >&>
                (geometry_->GetVertexBuffers());
            PODVector<unsigned>& elementMasks = const_cast<PODVector<unsigned>&>(geometry_->GetVertexElementMasks());
            vertexBuffers.Push(SharedPtr<VertexBuffer>(instanceBuffer));
            elementMasks.Push(instanceBuffer->GetElementMask());
            
            // No stream offset support, instancing buffer not pre-filled with transforms: have to fill now
            if (startIndex_ == M_MAX_UNSIGNED)
            {
                unsigned startIndex = 0;
                while (startIndex < instances_.Size())
                {
                    unsigned instances = instances_.Size() - startIndex;
                    if (instances > instanceBuffer->GetVertexCount())
                        instances = instanceBuffer->GetVertexCount();
                    
                    // Copy the transforms
                    Matrix3x4* dest = (Matrix3x4*)instanceBuffer->Lock(0, instances, true);
                    if (dest)
                    {
                        for (unsigned i = 0; i < instances; ++i)
                            dest[i] = *instances_[i + startIndex].worldTransform_;
                        instanceBuffer->Unlock();
                        
                        graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
                        graphics->SetVertexBuffers(vertexBuffers, elementMasks);
                        graphics->DrawInstanced(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(),
                            geometry_->GetIndexCount(), geometry_->GetVertexStart(), geometry_->GetVertexCount(), instances);
                    }
                    
                    startIndex += instances;
                }
            }
            // Stream offset supported and instancing buffer has been already filled, so just draw
            else
            {
                graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
                graphics->SetVertexBuffers(vertexBuffers, elementMasks, startIndex_);
                graphics->DrawInstanced(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(), geometry_->GetIndexCount(),
                    geometry_->GetVertexStart(), geometry_->GetVertexCount(), instances_.Size());
            }
            
            // Remove the instancing buffer & element mask now
            vertexBuffers.Pop();
            elementMasks.Pop();
        }
    }
}