669 lines · 29.5 KB · C++
RawDownload
    if (lightBufferUnit >= 0) {        batch.setUniformBuffer(lightBufferUnit, keyLight->getSchemaBuffer());    }     if (keyLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {        batch.setResourceTexture(skyboxCubemapUnit, keyLight->getAmbientMap());    }} static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {    auto VS = gpu::Shader::createVertex(std::string(vertSource));    auto PS = gpu::Shader::createPixel(std::string(fragSource));        gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS);     gpu::Shader::BindingSet slotBindings;    slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), DEFERRED_BUFFER_COLOR_UNIT));    slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT));    slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_UNIT));    slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DEFERRED_BUFFER_DEPTH_UNIT));    slotBindings.insert(gpu::Shader::Binding(std::string("obscuranceMap"), DEFERRED_BUFFER_OBSCURANCE_UNIT));    slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), SHADOW_MAP_UNIT));    slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), SKYBOX_MAP_UNIT));     static const int LIGHT_GPU_SLOT = 3;    static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2;    slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));    slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), DEFERRED_TRANSFORM_BUFFER_SLOT));     gpu::Shader::makeProgram(*program, slotBindings);     locations->radius = program->getUniforms().findLocation("radius");    locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00");     locations->texcoordMat = program->getUniforms().findLocation("texcoordMat");    locations->coneParam = program->getUniforms().findLocation("coneParam");     locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");    locations->deferredTransformBuffer = program->getBuffers().findLocation("deferredTransformBuffer");    locations->shadowTransformBuffer = program->getBuffers().findLocation("shadowTransformBuffer");     auto state = std::make_shared<gpu::State>();    state->setColorWriteMask(true, true, true, false);     // Stencil test all the light passes for objects pixels only, not the background    state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));        if (lightVolume) {        state->setCullMode(gpu::State::CULL_BACK);        state->setDepthTest(true, false, gpu::LESS_EQUAL);         // TODO: We should use DepthClamp and avoid changing geometry for inside /outside cases         // additive blending        state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE);    } else {        state->setCullMode(gpu::State::CULL_BACK);    }    pipeline = gpu::Pipeline::create(program, state); } void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) {    auto globalLight = _allocatedLights.front();    globalLight->setDirection(light->getDirection());    globalLight->setColor(light->getColor());    globalLight->setIntensity(light->getIntensity());    globalLight->setAmbientIntensity(light->getAmbientIntensity());    globalLight->setAmbientSphere(light->getAmbientSphere());    globalLight->setAmbientMap(light->getAmbientMap());} model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {    if (!_spotLightMesh) {        _spotLightMesh = std::make_shared<model::Mesh>();         int slices = 32;        int rings = 3;        int vertices = 2 + rings * slices;        int originVertex = vertices - 2;        int capVertex = vertices - 1;        int verticesSize = vertices * 3 * sizeof(float);        int indices = 3 * slices * (1 + 1 + 2 * (rings -1));        int ringFloatOffset = slices * 3;          float* vertexData = new float[verticesSize];        float* vertexRing0 = vertexData;        float* vertexRing1 = vertexRing0 + ringFloatOffset;        float* vertexRing2 = vertexRing1 + ringFloatOffset;                for (int i = 0; i < slices; i++) {            float theta = TWO_PI * i / slices;            auto cosin = glm::vec2(cosf(theta), sinf(theta));             *(vertexRing0++) = cosin.x;            *(vertexRing0++) = cosin.y;            *(vertexRing0++) = 0.0f;             *(vertexRing1++) = cosin.x;            *(vertexRing1++) = cosin.y;            *(vertexRing1++) = 0.33f;             *(vertexRing2++) = cosin.x;            *(vertexRing2++) = cosin.y;            *(vertexRing2++) = 0.66f;        }                *(vertexRing2++) = 0.0f;        *(vertexRing2++) = 0.0f;        *(vertexRing2++) = -1.0f;                *(vertexRing2++) = 0.0f;        *(vertexRing2++) = 0.0f;        *(vertexRing2++) = 1.0f;                _spotLightMesh->setVertexBuffer(gpu::BufferView(new gpu::Buffer(verticesSize, (gpu::Byte*) vertexData), gpu::Element::VEC3F_XYZ));        delete[] vertexData;         gpu::uint16* indexData = new gpu::uint16[indices];        gpu::uint16* index = indexData;        for (int i = 0; i < slices; i++) {            *(index++) = originVertex;                        int s0 = i;            int s1 = ((i + 1) % slices);            *(index++) = s0;            *(index++) = s1;             int s2 = s0 + slices;            int s3 = s1 + slices;            *(index++) = s1;            *(index++) = s0;            *(index++) = s2;             *(index++) = s1;            *(index++) = s2;            *(index++) = s3;             int s4 = s2 + slices;            int s5 = s3 + slices;            *(index++) = s3;            *(index++) = s2;            *(index++) = s4;             *(index++) = s3;            *(index++) = s4;            *(index++) = s5;              *(index++) = s5;            *(index++) = s4;            *(index++) = capVertex;        }         _spotLightMesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(sizeof(unsigned short) * indices, (gpu::Byte*) indexData), gpu::Element::INDEX_UINT16));        delete[] indexData;                 std::vector<model::Mesh::Part> parts;        parts.push_back(model::Mesh::Part(0, indices, 0, model::Mesh::TRIANGLES));        parts.push_back(model::Mesh::Part(0, indices, 0, model::Mesh::LINE_STRIP)); // outline version                 _spotLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));    }    return _spotLightMesh;} 

Lines 501–669 of 669. Previous lines