// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode) { const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); int samples = framebufferObject->getSamples(data); gl::RasterizerState rasterizer = data.state->getRasterizerState(); rasterizer.pointDrawMode = (drawMode == GL_POINTS); rasterizer.multiSample = (samples != 0); gl::Error error = setRasterizerState(rasterizer); if (error.isError()) { return error; } unsigned int mask = 0; if (data.state->isSampleCoverageEnabled()) { GLclampf coverageValue = data.state->getSampleCoverageValue(); if (coverageValue != 0) { float threshold = 0.5f; for (int i = 0; i < samples; ++i) { mask <<= 1; if ((i + 1) * coverageValue >= threshold) { threshold += 1.0f; mask |= 1; } } } bool coverageInvert = data.state->getSampleCoverageInvert(); if (coverageInvert) { mask = ~mask; } } else { mask = 0xFFFFFFFF; } error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask); if (error.isError()) { return error; } error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(), data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW); if (error.isError()) { return error; } return gl::Error(GL_NO_ERROR); }
void SkeletalMeshRenderer::render() { //should have an update check and recall set if updated. if(drawBuffers_.size() > 0 && isRendering()) { auto context = Sly::display->getContext(); auto display = Sly::display; const unsigned int stride = sizeof(MeshVertex); const unsigned int offset = 0; context->IASetInputLayout(inputLayout_); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); display->setRasterizerState(rasterizerState_); display->setSamplerStates(samplerStates_); display->setBlendState(blendState_); display->setDepthStencilState(depthStencilState_); context->VSSetShader(vertexShader_, nullptr, 0); context->HSSetShader(hullShader_, nullptr, 0); context->DSSetShader(domainShader_, nullptr, 0); context->GSSetShader(geometryShader_, nullptr, 0); context->PSSetShader(pixelShader_, nullptr, 0); const auto meshTransform = (transform_) ? XMLoadFloat4x4(transform_) : XMMatrixIdentity(); //Default to identity if null (same for subMeshTransform) for(auto b = drawBuffers_.begin(); b != drawBuffers_.end(); ++b) { const auto subMeshTransform = ((*b)->transform) ? XMLoadFloat4x4((*b)->transform) : XMMatrixIdentity(); const auto transform = meshTransform * subMeshTransform; auto materialBuffer = display->getConstantBuffer("material"); auto worldBuffer = display->getConstantBuffer("world"); MaterialCB materialCB = { (*b)->material->diffuse, (*b)->material->specular }; materialBuffer->update(context, &materialCB , sizeof(MaterialCB)); WorldCB worldCB; XMStoreFloat4x4(&worldCB.world, transform); worldBuffer->update(context, &worldCB, sizeof(WorldCB)); context->VSSetConstantBuffers(0, 1, &worldBuffer->buffer); context->PSSetConstantBuffers(3, 1, &materialBuffer->buffer); context->VSSetConstantBuffers(0, 1, &worldBuffer->buffer); context->PSSetConstantBuffers(3, 1, &materialBuffer->buffer); ID3D11ShaderResourceView* srvs[4] = { (*b)->material->diffuseMap, (*b)->material->normalMap, (*b)->material->specularMap, (*b)->material->environmentMap}; context->PSSetShaderResources(0, 4, srvs); context->IASetVertexBuffers(0, 1, &(*b)->vertexBuffer, &stride, &offset ); //maybe able to group these together context->IASetIndexBuffer((*b)->indexBuffer, DXGI_FORMAT_R32_UINT, 0); context->DrawIndexed((*b)->drawCount, 0, 0); } } }
void ShadowsDemo::onDraw() { App::onDraw(); const auto device = graphicsDevice(); device->setClearColor(0.0f, 0.0f, 0.0f, 0.0f); device->clear(ciri::ClearFlags::Color | ciri::ClearFlags::Depth); device->setRasterizerState(_rasterState); device->restoreDefaultBlendState(); if( _spotlightShader->isValid() && _directionalShader->isValid() ) { const cc::Mat4f& cameraViewProj = _camera.getProj() * _camera.getView(); bool firstLight = true; Light::Type boundLightType = Light::Type::Invalid; for( auto& light : _lights ) { // compute light matrices //const cc::Mat4f& lightView = light.view(); //const cc::Mat4f& lightProj = light.proj();//cc::math::perspectiveRH(45.0f, 1.0f, 0.1f, light.range());//light.proj(); //const cc::Mat4f lightViewProj = lightProj * lightView; if( light.type() == Light::Type::Directional ) { //light.computeViewProjFromFrustum(BoundingFrustum(cameraViewProj)); light.computeViewProjFromFrustum(BoundingFrustum(_camera.getFov(), _camera.getAspect(), _camera.getNearPlane(), _camera.getFarPlane(), _camera.getPosition(), _camera.getFpsFront(), _camera.getUp())); //light.computeViewProjOrtho(_camera.getView(), _camera.getFov(), _camera.getAspect(), _camera.getNearPlane(), _camera.getFarPlane()); } const cc::Mat4f lightViewProj = light.proj() * light.view(); if( light.castShadows() ) { device->setDepthStencilState(device->getDefaultDepthStencilDefault()); // set and clear render target ciri::IRenderTarget2D* depthTarget = _shadowTarget.get(); device->setRenderTargets(&depthTarget, 1); device->setClearColor(0.0f, 0.0f, 0.0f, 0.0f); device->clear(ciri::ClearFlags::Color | ciri::ClearFlags::Depth); // apply depth shader device->applyShader(_depthShader); // set viewport to depth size device->setViewport(ciri::Viewport(0, 0, _shadowTarget->getDepth()->getWidth(), _shadowTarget->getDepth()->getHeight())); // render all models for( auto& mdl : _models ) { _depthConstants.xform = lightViewProj * mdl->getXform().getWorld(); _depthConstantsBuffer->setData(sizeof(DepthConstants), &_depthConstants); device->setVertexBuffer(mdl->getVertexBuffer()); if( mdl->getIndexBuffer() != nullptr ) { device->setIndexBuffer(mdl->getIndexBuffer()); device->drawIndexed(ciri::PrimitiveTopology::TriangleList, mdl->getIndexBuffer()->getIndexCount()); } else { device->drawArrays(ciri::PrimitiveTopology::TriangleList, mdl->getVertexBuffer()->getVertexCount(), 0); } } // reser viewport to screen device->setViewport(ciri::Viewport(0, 0, window()->getWidth(), window()->getHeight())); // restore default render targets device->restoreDefaultRenderTargets(); } switch( light.type() ) { case Light::Type::Directional: { if( boundLightType != Light::Type::Directional || light.castShadows() ) { boundLightType = Light::Type::Directional; device->applyShader(_directionalShader); device->setTexture2D(0, _shadowTarget->getDepth(), ciri::ShaderStage::Pixel); device->setSamplerState(0, _shadowSampler, ciri::ShaderStage::Pixel); } _directionalConstants.LightDirection = light.direction(); _directionalConstants.LightColor = light.diffuseColor(); _directionalConstants.LightIntensity = light.diffuseIntensity(); _directionalConstants.campos = _camera.getPosition(); _directionalConstants.CastShadows = light.castShadows(); _directionalConstants.lightViewProj = lightViewProj; for( auto& mdl : _models ) { if( !mdl->isValid() ) { continue; } _directionalConstants.world = mdl->getXform().getWorld(); _directionalConstants.xform = cameraViewProj * _directionalConstants.world; _directionalConstantsBuffer->setData(sizeof(DirectionalConstants), &_directionalConstants); device->setVertexBuffer(mdl->getVertexBuffer()); if( mdl->getIndexBuffer() != nullptr ) { device->setIndexBuffer(mdl->getIndexBuffer()); device->drawIndexed(ciri::PrimitiveTopology::TriangleList, mdl->getIndexBuffer()->getIndexCount()); } else { device->drawArrays(ciri::PrimitiveTopology::TriangleList, mdl->getVertexBuffer()->getVertexCount(), 0); } } break; } case Light::Type::Spot: { if( boundLightType != Light::Type::Spot || light.castShadows() ) { boundLightType = Light::Type::Spot; device->applyShader(_spotlightShader); device->setTexture2D(0, _shadowTarget->getDepth(), ciri::ShaderStage::Pixel); device->setSamplerState(0, _shadowSampler, ciri::ShaderStage::Pixel); } _spotlightConstants.LightPosition = light.position(); _spotlightConstants.LightDirection = light.direction(); _spotlightConstants.LightColor = light.diffuseColor(); _spotlightConstants.LightCosInner = light.cosConeInnerAngle(true); _spotlightConstants.LightCosOuter = light.cosConeOuterAngle(true); _spotlightConstants.LightIntensity = light.diffuseIntensity(); _spotlightConstants.LightRange = light.range(); _spotlightConstants.CastShadows = light.castShadows(); _spotlightConstants.lightViewProj = lightViewProj; for( auto& mdl : _models ) { _spotlightConstants.world = mdl->getXform().getWorld(); _spotlightConstants.xform = cameraViewProj * _spotlightConstants.world; _spotlightConstantsBuffer->setData(sizeof(SpotlightConstants), &_spotlightConstants); device->setVertexBuffer(mdl->getVertexBuffer()); if( mdl->getIndexBuffer() != nullptr ) { device->setIndexBuffer(mdl->getIndexBuffer()); device->drawIndexed(ciri::PrimitiveTopology::TriangleList, mdl->getIndexBuffer()->getIndexCount()); } else { device->drawArrays(ciri::PrimitiveTopology::TriangleList, mdl->getVertexBuffer()->getVertexCount(), 0); } } break; } } if( firstLight ) { firstLight = false; device->setBlendState(_additiveBlendState); } } } device->present(); }
void GraphicsDevice::executeRenderPass( RenderPass p_pass, BufferBase* p_cbuf/*=NULL*/, vector<BufferBase*>* p_instancesLists/*=NULL*/, vector<Mesh*>* p_meshList/*=NULL*/) { switch(p_pass) { case RenderPass::P_BASEPASS: if (p_instancesLists != NULL && p_cbuf != NULL) { m_deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); setBlendState(BlendState::NORMAL); setRasterizerStateSettings(RasterizerState::DEFAULT, true); setRenderTarget(RT_MRT); p_cbuf->apply(); setShader(SI_MESHBASESHADER); unsigned int instancesListSize = (unsigned int)p_instancesLists->size(); // fallback if no mesh list has been supplied if (p_meshList == NULL) p_meshList = &m_meshFallbackBoxList; unsigned int meshListSize = (unsigned int)p_meshList->size(); // for each mesh as defined by the instance list for (unsigned int i = 0; i < instancesListSize; i++) { // Fetch the mesh, fall back to fallback meshes // if not enough meshes have been defined Mesh* mesh = NULL; if (i < meshListSize) mesh = (*p_meshList)[i]; else mesh = m_meshFallbackBoxList[0]; //for each copy of a mesh // issue a render using the instance buffer in the // instanceslist for that index BufferBase* instances = (*p_instancesLists)[i]; if (instances != NULL && mesh!=NULL) { drawInstancedIndexedMesh(mesh, instances->getElementCount(), instances->getElementSize(), instances->getBufferPointer()); } } } break; case RenderPass::P_COMPOSEPASS: m_deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); setBlendState(BlendState::NORMAL); setRasterizerStateSettings(RasterizerState::DEFAULT,false); setRenderTarget(RT_BACKBUFFER_NODEPTHSTENCIL); setShader(SI_COMPOSESHADER); drawFullscreen(); break; case RenderPass::P_BOUNDINGBOX_WIREFRAMEPASS: if (p_instancesLists != NULL && p_cbuf != NULL) { m_deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST); setBlendState(BlendState::ADDITIVE); setRasterizerStateSettings(RasterizerState::WIREFRAME, false); setRenderTarget(RT_BACKBUFFER_NODEPTHSTENCIL); p_cbuf->apply(); setShader(SI_WIREFRAMESHADER); // loop through all instance lists in the vector // not really necessary as it will almost always be of size 1 here // for simple bounding boxes for (int i = 0; i < p_instancesLists->size(); i++) { BufferBase* instances = (*p_instancesLists)[i]; if (instances != NULL) { drawInstancedLineOBB(instances->getElementCount(), instances->getElementSize(), instances->getBufferPointer()); } } } break; } }