Example #1
0
// For each Direct3D sampler of either the pixel or vertex stage,
// looks up the corresponding OpenGL texture image unit and texture type,
// and sets the texture and its addressing/filtering state (or NULL when inactive).
// Sampler mapping needs to be up-to-date on the program object before this is called.
gl::Error RendererD3D::applyTextures(GLImplFactory *implFactory,
                                     const gl::ContextState &data,
                                     gl::SamplerType shaderType,
                                     const FramebufferTextureArray &framebufferTextures,
                                     size_t framebufferTextureCount)
{
    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());

    ASSERT(!programD3D->isSamplerMappingDirty());

    unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType);
    for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
    {
        GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex);
        GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, *data.caps);
        if (textureUnit != -1)
        {
            gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
            ASSERT(texture);

            gl::Sampler *samplerObject = data.state->getSampler(textureUnit);

            const gl::SamplerState &samplerState =
                samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();

            // TODO: std::binary_search may become unavailable using older versions of GCC
            if (texture->getTextureState().isSamplerComplete(samplerState, data) &&
                !std::binary_search(framebufferTextures.begin(),
                                    framebufferTextures.begin() + framebufferTextureCount, texture))
            {
                ANGLE_TRY(setSamplerState(shaderType, samplerIndex, texture, samplerState));
                ANGLE_TRY(setTexture(shaderType, samplerIndex, texture));
            }
            else
            {
                // Texture is not sampler complete or it is in use by the framebuffer.  Bind the incomplete texture.
                gl::Texture *incompleteTexture = getIncompleteTexture(implFactory, textureType);

                ANGLE_TRY(setSamplerState(shaderType, samplerIndex, incompleteTexture,
                                          incompleteTexture->getSamplerState()));
                ANGLE_TRY(setTexture(shaderType, samplerIndex, incompleteTexture));
            }
        }
        else
        {
            // No texture bound to this slot even though it is used by the shader, bind a NULL texture
            ANGLE_TRY(setTexture(shaderType, samplerIndex, nullptr));
        }
    }

    // Set all the remaining textures to NULL
    size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
                                                            : data.caps->maxVertexTextureImageUnits;
    clearTextures(shaderType, samplerRange, samplerCount);

    return gl::NoError();
}
Example #2
0
// attach attaches the api texture to sampling stage i
//
void APITexture::attach(unsigned flags) {

	if (!tex) setup(0, 0, 0);

    if (tex) {
        d3dd->SetTexture(0, tex);
		setSamplerState(0, flags);
    }
}
Example #3
0
//------------------------------------------------------------------------------
//## Basic
TEST_F(Test_Shader_Shader, IndependentSamplerState)
{
    auto shader1 = Shader::create(LN_ASSETFILE("Shader/IndependentSamplerState.fx"));

    auto vertexDecl1 = newObject<VertexLayout>();
    vertexDecl1->addElement(0, VertexElementType::Float3, VertexElementUsage::Position, 0);
    vertexDecl1->addElement(0, VertexElementType::Float2, VertexElementUsage::TexCoord, 0);

    struct Vertex
    {
        Vector3 pos;
        Vector2 uv;
    };
    Vertex v[] = {
        { { -1, 1, 0 }, { 0, 0 }, },	// 0.5 で中央の face からサンプリングする
        { { 0, 1, 0 }, { 1, 0 }, },
        { { -1, 0, 0 }, { 0, 1 }, },
        { { 0, 0, 0 }, { 1, 1 }, },
    };
    auto vb1 = newObject<VertexBuffer>(sizeof(v), v, GraphicsResourceUsage::Static);

    auto tex1 = newObject<Texture2D>(2, 2, TextureFormat::RGBA8);
    auto bmp1 = tex1->map(MapMode::Write);
    bmp1->setPixel32(0, 0, ColorI(255, 0, 0, 255));
    bmp1->setPixel32(1, 0, ColorI(255, 0, 255, 255));
    bmp1->setPixel32(0, 1, ColorI(0, 255, 0, 255));
    bmp1->setPixel32(1, 1, ColorI(0, 0, 255, 255));

    // TODO: まだ SamplerState 直接指定をサポートしていないので Texture に対してセットする方法でテストケースだけ用意しておく。
    // 後でサポートするとき、shader1->findParameter("mySamplerState")->setSamplerState(samplerState); とかに書き換える。
    auto samplerState = newObject<SamplerState>();
    samplerState->setFilterMode(TextureFilterMode::Linear);
    tex1->setSamplerState(samplerState);

    shader1->findParameter("_Texture")->setTexture(tex1);

    auto ctx = Engine::graphicsContext();
    TestEnv::resetGraphicsContext(ctx);
    ctx->setVertexLayout(vertexDecl1);
    ctx->setVertexBuffer(0, vb1);
    ctx->setIndexBuffer(nullptr);
    ctx->setShaderPass(shader1->techniques()[0]->passes()[0]);

    // * [ ] default
    {
        ctx->clear(ClearFlags::All, Color::White, 1.0f, 0);
		ctx->setPrimitiveTopology(PrimitiveTopology::TriangleStrip);
        ctx->drawPrimitive(0, 2);

        ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-IndependentSamplerState-1.png"));
    }
}
Example #4
0
// For each Direct3D sampler of either the pixel or vertex stage,
// looks up the corresponding OpenGL texture image unit and texture type,
// and sets the texture and its addressing/filtering state (or NULL when inactive).
gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
                                     const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount)
{
    gl::Program *program = data.state->getProgram();

    unsigned int samplerRange = program->getUsedSamplerRange(shaderType);
    for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
    {
        GLenum textureType = program->getSamplerTextureType(shaderType, samplerIndex);
        GLint textureUnit = program->getSamplerMapping(shaderType, samplerIndex, *data.caps);
        if (textureUnit != -1)
        {
            gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
            ASSERT(texture);
            gl::SamplerState sampler = texture->getSamplerState();

            gl::Sampler *samplerObject = data.state->getSampler(textureUnit);
            if (samplerObject)
            {
                samplerObject->getState(&sampler);
            }

            // TODO: std::binary_search may become unavailable using older versions of GCC
            if (texture->isSamplerComplete(sampler, data) &&
                    !std::binary_search(framebufferTextures.begin(), framebufferTextures.begin() + framebufferTextureCount, texture))
            {
                gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler);
                if (error.isError())
                {
                    return error;
                }

                error = setTexture(shaderType, samplerIndex, texture);
                if (error.isError())
                {
                    return error;
                }
            }
            else
            {
                // Texture is not sampler complete or it is in use by the framebuffer.  Bind the incomplete texture.
                gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
                gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture);
                if (error.isError())
                {
                    return error;
                }
            }
        }
        else
        {
            // No texture bound to this slot even though it is used by the shader, bind a NULL texture
            gl::Error error = setTexture(shaderType, samplerIndex, NULL);
            if (error.isError())
            {
                return error;
            }
        }
    }

    // Set all the remaining textures to NULL
    size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
                          : data.caps->maxVertexTextureImageUnits;
    clearTextures(shaderType, samplerRange, samplerCount);

    return gl::Error(GL_NO_ERROR);
}
Example #5
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();
}