void RenderableParticleEffectEntityItem::createPipelines() { if (!_untexturedPipeline) { auto state = std::make_shared<gpu::State>(); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); auto vertShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(untextured_particle_vert))); auto fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(untextured_particle_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vertShader, fragShader)); _untexturedPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); } if (!_texturedPipeline) { auto state = std::make_shared<gpu::State>(); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); auto vertShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(textured_particle_vert))); auto fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vertShader, fragShader)); _texturedPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); } }
gpu::PipelinePointer DeferredLightingEffect::getPipeline(SimpleProgramKey config) { auto it = _simplePrograms.find(config); if (it != _simplePrograms.end()) { return it.value(); } auto state = std::make_shared<gpu::State>(); if (config.isCulled()) { state->setCullMode(gpu::State::CULL_BACK); } else { state->setCullMode(gpu::State::CULL_NONE); } state->setDepthTest(true, true, gpu::LESS_EQUAL); if (config.hasDepthBias()) { state->setDepthBias(1.0f); state->setDepthBiasSlopeScale(1.0f); } state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader; gpu::PipelinePointer pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); _simplePrograms.insert(config, pipeline); return pipeline; }
const gpu::PipelinePointer ParabolaPointer::RenderState::ParabolaRenderItem::getParabolaPipeline() { if (!_parabolaPipeline || !_transparentParabolaPipeline) { { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::parabola); auto state = std::make_shared<gpu::State>(); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); PrepareStencil::testMaskDrawShape(*state); state->setCullMode(gpu::State::CULL_NONE); _parabolaPipeline = gpu::Pipeline::create(program, state); } { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::parabola_translucent); auto state = std::make_shared<gpu::State>(); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); PrepareStencil::testMask(*state); state->setCullMode(gpu::State::CULL_NONE); _transparentParabolaPipeline = gpu::Pipeline::create(program, state); } } return (_parabolaData.color.a < 1.0f ? _transparentParabolaPipeline : _parabolaPipeline); }
void ModelRender::RenderPipelineLib::addRenderPipeline(ModelRender::RenderKey key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), ModelRender::SKINNING_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), ModelRender::MATERIAL_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), ModelRender::DIFFUSE_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), ModelRender::NORMAL_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), ModelRender::SPECULAR_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), ModelRender::LIGHTMAP_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ModelRender::LIGHT_BUFFER_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT)); gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); gpu::Shader::makeProgram(*program, slotBindings); auto locations = std::make_shared<Locations>(); initLocations(program, *locations); auto state = std::make_shared<gpu::State>(); // Backface on shadow if (key.isShadow()) { state->setCullMode(gpu::State::CULL_FRONT); state->setDepthBias(1.0f); state->setDepthBiasSlopeScale(4.0f); } else { state->setCullMode(gpu::State::CULL_BACK); } // Z test depends if transparent or not state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); // Blend on transparent state->setBlendFunction(key.isTranslucent(), gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, // For transparent only, this keep the highlight intensity gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); // Good to go add the brand new pipeline auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations))); if (!key.isWireFrame()) { RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME); auto wireframeState = std::make_shared<gpu::State>(state->getValues()); wireframeState->setFillMode(gpu::State::FILL_LINE); // create a new RenderPipeline with the same shader side and the wireframe state auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); } }
//------------------------------------------------------------------------------ //## CullMode TEST_F(Test_Visual_VisualComponent, CullMode) { auto texture1 = Texture2D::create(32, 32); auto texture2 = Texture2D::create(32, 32); texture1->clear(Color::Red); texture2->clear(Color::Green); //* [ ] CullMode { // Back(default), FrontFace -> Visible auto sprite1 = Sprite::create(texture1, 3, 3); sprite1->setShadingModel(ShadingModel::UnLighting); sprite1->setPosition(-1.5, 3, 0); // 裏面は Sprite と Mesh で異なるのでここではテストしない // Front, FrontFace -> Hide auto sprite3 = Sprite::create(texture1, 3, 3); sprite3->setShadingModel(ShadingModel::UnLighting); sprite3->setPosition(-1.5, 0, 0); sprite3->setCullMode(CullMode::Front); // Front, BackFace -> Hide auto sprite4 = Sprite::create(texture2, 3, 3); sprite4->setShadingModel(ShadingModel::UnLighting); sprite4->setPosition(1.5, 0, 0); sprite4->setCullMode(CullMode::Front); sprite4->setEulerAngles(0, Math::PI, 0); // None, FrontFace -> Visible auto sprite5 = Sprite::create(texture1, 3, 3); sprite5->setShadingModel(ShadingModel::UnLighting); sprite5->setPosition(-1.5, -3, 0); sprite5->setCullMode(CullMode::None); // None, BackFace -> Visible auto sprite6 = Sprite::create(texture2, 3, 3); sprite6->setShadingModel(ShadingModel::UnLighting); sprite6->setCullMode(CullMode::None); sprite6->setPosition(1.5, -3, 0); sprite6->setEulerAngles(0, Math::PI, 0); TestEnv::updateFrame(); ASSERT_SCREEN(LN_ASSETFILE("Visual/Result/Test_Visual_VisualComponent-CullMode-1.png")); LN_TEST_CLEAN_SCENE; } }
AnimDebugDraw::AnimDebugDraw() : _itemID(0) { auto state = std::make_shared<gpu::State>(); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); auto vertShader = gpu::Shader::createVertex(std::string(animdebugdraw_vert)); auto fragShader = gpu::Shader::createPixel(std::string(animdebugdraw_frag)); auto program = gpu::Shader::createProgram(vertShader, fragShader); _pipeline = gpu::Pipeline::create(program, state); _animDebugDrawData = std::make_shared<AnimDebugDrawData>(); _animDebugDrawPayload = std::make_shared<AnimDebugDrawPayload>(_animDebugDrawData); _animDebugDrawData->_pipeline = _pipeline; render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene) { _itemID = scene->allocateID(); render::PendingChanges pendingChanges; pendingChanges.resetItem(_itemID, _animDebugDrawPayload); scene->enqueuePendingChanges(pendingChanges); } // HACK: add red, green and blue axis at (1,1,1) _animDebugDrawData->_vertexBuffer->resize(sizeof(Vertex) * 6); Vertex* data = (Vertex*)_animDebugDrawData->_vertexBuffer->editData(); data[0].pos = glm::vec3(1.0, 1.0f, 1.0f); data[0].rgba = toRGBA(255, 0, 0, 255); data[1].pos = glm::vec3(2.0, 1.0f, 1.0f); data[1].rgba = toRGBA(255, 0, 0, 255); data[2].pos = glm::vec3(1.0, 1.0f, 1.0f); data[2].rgba = toRGBA(0, 255, 0, 255); data[3].pos = glm::vec3(1.0, 2.0f, 1.0f); data[3].rgba = toRGBA(0, 255, 0, 255); data[4].pos = glm::vec3(1.0, 1.0f, 1.0f); data[4].rgba = toRGBA(0, 0, 255, 255); data[5].pos = glm::vec3(1.0, 1.0f, 2.0f); data[5].rgba = toRGBA(0, 0, 255, 255); _animDebugDrawData->_indexBuffer->resize(sizeof(uint16_t) * 6); uint16_t* indices = (uint16_t*)_animDebugDrawData->_indexBuffer->editData(); for (int i = 0; i < 6; i++) { indices[i] = i; } }
void RenderableProceduralItem::ProceduralInfo::prepare(gpu::Batch& batch) { if (_shaderUrl.isLocalFile()) { auto lastModified = QFileInfo(_shaderPath).lastModified().toMSecsSinceEpoch(); if (lastModified > _shaderModified) { QFile file(_shaderPath); file.open(QIODevice::ReadOnly); _shaderSource = QTextStream(&file).readAll(); _pipelineDirty = true; _shaderModified = lastModified; } } else if (_networkShader && _networkShader->isLoaded()) { _shaderSource = _networkShader->_source; } if (!_pipeline || _pipelineDirty) { _pipelineDirty = false; if (!_vertexShader) { _vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert))); } QString framentShaderSource = SHADER_TEMPLATE.arg(_shaderSource); _fragmentShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(framentShaderSource.toLocal8Bit().data()))); _shader = gpu::ShaderPointer(gpu::Shader::createProgram(_vertexShader, _fragmentShader)); gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT)); gpu::Shader::makeProgram(*_shader, slotBindings); auto state = std::make_shared<gpu::State>(); state->setCullMode(gpu::State::CULL_NONE); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(_shader, state)); _timeSlot = _shader->getUniforms().findLocation(UNIFORM_TIME_NAME); _scaleSlot = _shader->getUniforms().findLocation(UNIFORM_SCALE_NAME); _start = usecTimestampNow(); } batch.setPipeline(_pipeline); float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND; batch._glUniform1f(_timeSlot, time); auto scale = _entity->getDimensions(); batch._glUniform3f(_scaleSlot, scale.x, scale.y, scale.z); batch.setResourceTexture(DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT, DependencyManager::get<TextureCache>()->getNormalFittingTexture()); }
AnimDebugDraw::AnimDebugDraw() : _itemID(0) { auto state = std::make_shared<gpu::State>(); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); auto vertShader = animdebugdraw_vert::getShader(); auto fragShader = animdebugdraw_frag::getShader(); auto program = gpu::Shader::createProgram(vertShader, fragShader); _pipeline = gpu::Pipeline::create(program, state); _animDebugDrawData = std::make_shared<AnimDebugDrawData>(); _animDebugDrawPayload = std::make_shared<AnimDebugDrawPayload>(_animDebugDrawData); _animDebugDrawData->_pipeline = _pipeline; render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene) { _itemID = scene->allocateID(); render::Transaction transaction; transaction.resetItem(_itemID, _animDebugDrawPayload); scene->enqueueTransaction(transaction); } // HACK: add red, green and blue axis at (1,1,1) _animDebugDrawData->_vertexBuffer->resize(sizeof(AnimDebugDrawData::Vertex) * 6); static std::vector<AnimDebugDrawData::Vertex> vertices({ AnimDebugDrawData::Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) }, AnimDebugDrawData::Vertex { glm::vec3(2.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) }, AnimDebugDrawData::Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(0, 255, 0, 255) }, AnimDebugDrawData::Vertex { glm::vec3(1.0, 2.0f, 1.0f), toRGBA(0, 255, 0, 255) }, AnimDebugDrawData::Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(0, 0, 255, 255) }, AnimDebugDrawData::Vertex { glm::vec3(1.0, 1.0f, 2.0f), toRGBA(0, 0, 255, 255) }, }); static std::vector<uint16_t> indices({ 0, 1, 2, 3, 4, 5 }); _animDebugDrawData->_vertexBuffer->setSubData<AnimDebugDrawData::Vertex>(0, vertices); _animDebugDrawData->_indexBuffer->setSubData<uint16_t>(0, indices); }
//----------------------------------------------------------------------------- //* Initialize //! Initializes OpenGL. // //! @param fullscreen will render scene in fullscreen if true //! @param width width of window or width of screen resolution //! @param height height of window or height of screen resolution //! @param bitDepth bitDepth to use //! @param refreshRate refresh frequency to use //! @param vSync limits frame rate to the monitor's refresh frequency //! @param hideCursor hides mouse coursor if true //----------------------------------------------------------------------------- bool OpenGLManager::initialize(bool fullscreen, int width, int height, int bitDepth, int refreshRate, bool vSync, bool hideCursor) { m_width = width; m_height = height; m_bitDepth = bitDepth; m_refreshRate = refreshRate; m_fullscreen = fullscreen; m_renderingCallback = NULL; //Set OpenGL Settings setClearColor(0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //Set render states setCullMode(false, true); setTextureing2D(false); setLighting(false); return true; }
MGLContext::MGLContext(void): m_currentFrameBuffer(0) { // version const char * version = (const char *)glGetString(GL_VERSION); if(version) { sscanf(version, "%d", &g_GLversion); printf("GL_VERSION : %s\n", version); } // init cull face (back) enableCullFace(); setCullMode(M_CULL_BACK); // normalize glEnable(GL_NORMALIZE); // fog glHint(GL_FOG_HINT, GL_NICEST); glFogf(GL_FOG_MODE, GL_LINEAR); // depth enableDepthTest(); setDepthMode(M_DEPTH_LEQUAL); glClearDepth(1.0f); // line glLineWidth(1); // stencil glClearStencil(0); // pixel pack/unpack glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); // anisotropic filtering glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); }
MES2Context::MES2Context(void): m_currentFrameBuffer(0) { m_matrixStep = 0; m_matrixMode = M_MATRIX_MODELVIEW; // version const char * version = (const char *)glGetString(GL_VERSION); if(version) { m_gl_version=version; sscanf(version, "%d", &g_GLversion); } // init cull face (back) enableCullFace(); setCullMode(M_CULL_BACK); // depth enableDepthTest(); setDepthMode(M_DEPTH_LEQUAL); glClearDepthf(1.0f); // line glLineWidth(1); // stencil glClearStencil(0); // pixel pack/unpack glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); // anisotropic filtering glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); }
gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask) { const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); const gl::BlendState &blendState = glState.getBlendState(); const gl::ColorF &blendColor = glState.getBlendColor(); const gl::RasterizerState &rasterState = glState.getRasterizerState(); const auto &depthStencilState = glState.getDepthStencilState(); bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW); unsigned int maxStencil = (1 << mCurStencilSize) - 1; // All the depth stencil states depends on the front face ccw variable if (frontFaceCCW != mCurFrontFaceCCW) { forceSetDepthStencilState(); mCurFrontFaceCCW = frontFaceCCW; } for (auto dirtyBit : angle::IterateBitSet(mDirtyBits)) { switch (dirtyBit) { case DIRTY_BIT_BLEND_ENABLED: setBlendEnabled(blendState.blend); break; case DIRTY_BIT_BLEND_COLOR: setBlendColor(blendState, blendColor); break; case DIRTY_BIT_BLEND_FUNCS_EQUATIONS: setBlendFuncsEquations(blendState); break; case DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(blendState.sampleAlphaToCoverage); break; case DIRTY_BIT_COLOR_MASK: setColorMask(framebuffer, blendState.colorMaskRed, blendState.colorMaskBlue, blendState.colorMaskGreen, blendState.colorMaskAlpha); break; case DIRTY_BIT_DITHER: setDither(blendState.dither); break; case DIRTY_BIT_CULL_MODE: setCullMode(rasterState.cullFace, rasterState.cullMode, rasterState.frontFace); break; case DIRTY_BIT_DEPTH_BIAS: setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor, rasterState.polygonOffsetUnits); break; case DIRTY_BIT_STENCIL_DEPTH_MASK: setDepthMask(depthStencilState.depthMask); break; case DIRTY_BIT_STENCIL_DEPTH_FUNC: setDepthFunc(depthStencilState.depthTest, depthStencilState.depthFunc); break; case DIRTY_BIT_STENCIL_TEST_ENABLED: setStencilTestEnabled(depthStencilState.stencilTest); break; case DIRTY_BIT_STENCIL_FUNCS_FRONT: setStencilFuncsFront(depthStencilState.stencilFunc, depthStencilState.stencilMask, glState.getStencilRef(), frontFaceCCW, maxStencil); break; case DIRTY_BIT_STENCIL_FUNCS_BACK: setStencilFuncsBack(depthStencilState.stencilBackFunc, depthStencilState.stencilBackMask, glState.getStencilBackRef(), frontFaceCCW, maxStencil); break; case DIRTY_BIT_STENCIL_WRITEMASK_FRONT: setStencilWriteMask(depthStencilState.stencilWritemask, frontFaceCCW); break; case DIRTY_BIT_STENCIL_WRITEMASK_BACK: setStencilBackWriteMask(depthStencilState.stencilBackWritemask, frontFaceCCW); break; case DIRTY_BIT_STENCIL_OPS_FRONT: setStencilOpsFront(depthStencilState.stencilFail, depthStencilState.stencilPassDepthFail, depthStencilState.stencilPassDepthPass, frontFaceCCW); break; case DIRTY_BIT_STENCIL_OPS_BACK: setStencilOpsBack(depthStencilState.stencilBackFail, depthStencilState.stencilBackPassDepthFail, depthStencilState.stencilBackPassDepthPass, frontFaceCCW); break; default: break; } } if (sampleMask != mCurSampleMask) { setSampleMask(sampleMask); } return gl::Error(GL_NO_ERROR); }
void CubewallScene::_draw(float time) { int textBitmapWidthL = min(textBitmapWidth, (int)(time*30.f)); time -= SceneTime::outStorm2cubewall; float fadeIn = min(1.0f, 1.f+time*0.33f); bool fadeActive = (fadeIn < 1.0); if (!fadeActive) { fboOverlay->bind(); } float fade2 = max(0.f, min(1.f, time)); setBlendMode(NO_BLEND); setCullMode(NO_CULL); setDepthMode(NO_DEPTH); glClearDepth(1.0f); glClearColor(56.f/256.f * fade2, 60.f/256.f * fade2, 50.f/256.f * fade2, 1.0f); glClear((fadeActive ? 0 : GL_COLOR_BUFFER_BIT) | GL_DEPTH_BUFFER_BIT); float ctime = max(0.f, time); int cctime = clamp((int)(gMusic->getBeat() / 16) - int(SceneTime::cubewallStart / BEAT / 16), 0, 6); //6 Teile,Schluß vec3 eye(-1.5*((cctime & 2) ? -1.f : 1.f), 0.5, (cctime & 1) ? 1. : (2. + 0.95*cos(ctime*0.2) + ctime*ctime*0.005)); vec3 center(0, -0.1 + 0.2*sin(time*0.15) + 0.5*atan(time*0.1), 0); vec3 up(0, 1, 0); mat4 view = lookAt(eye, center, up); mat4 proj = perspective<float>(30.f + 10.f*(float)cos(time*0.1), demo.aspect, 0.001f, 100.f); mat4 projView = proj*view; floorClearShader->bind(); setBlendMode(BLEND_ALPHA); floorClearShader->uniform("u_fade", fadeIn); floorClearShader->uniform("u_matrix", projView); drawArray(GL_TRIANGLE_FAN, floorVerts, NULL, NULL, NULL, NULL, sizeof(floorVerts) / (3 * sizeof(float))); floorClearShader->unbind(); setDepthMode(DEPTH_FULL); setBlendMode(NO_BLEND); cubeShader->bind(); cubeShader->uniform("u_eye", eye); cubeShader->uniform("u_matrix", projView); float cubeScaleFade = clamp((Duration() - time - 4.0f) / 1.0f, 0.0f, 1.0f); //ab 179: Kötzchen weg float explosionTime = max(0.f, time - (179.f - SceneTime::cubewallStart)); float explosionY = explosionTime*explosionTime; float cubeScale = 16.f / (float)textBitmapWidth; int cubeInstanceIndex = 0; for (int x = 0; x < textBitmapWidthL; x++) { for (int y = 0; y < textBitmapHeight; y++) { int cubeIndex = ((textBitmapHeight - 1) - y)*textBitmapWidth + x; int pixelPos = cubeIndex * 4; int a = textBitmap[pixelPos + 3]; if (a == 0) continue; float r = (textBitmap[pixelPos] * a) * (1.f/(255.f*255.f)); float g = (textBitmap[pixelPos+1] * a) * (1.f/(255.f*255.f)); float b = (textBitmap[pixelPos+2] * a) * (1.f/(255.f*255.f)); float random = randomValues[cubeIndex]; float cubeShiftAmp = 1.f - fract(gMusic->getBeat());// fmod(time * 2 * 1.2f, 1.f); float cubeShift = (0.5f - random) * cubeShiftAmp * 2; vec4 color(r, g, b, 1.f); color *= (1. - (0.5*cubeShift) + cubeShift*random); float highlightRandom = randomValues[((textBitmapHeight - 1) - y)*textBitmapWidth + (x / 3 + (int)(gMusic->getBeat() / 4)) % (textBitmapWidth*textBitmapHeight)]; float highlight = pow(highlightRandom, 10) * 10; color *= 1. + highlight; for (int mirror = 0; mirror < 2; mirror++) { vec3 pos(x*cubeScale + time*-0.65f + 1.5f, (y*cubeScale + 0.05f) * (mirror ? -1 : 1), cubeShift*0.5f*cubeScale); pos.y -= explosionY*(1.f+0.1f*random); pos.x += explosionTime*sin(10.f*random); cubePosScale[cubeInstanceIndex] = vec4(pos, cubeScaleFade * 0.4f*cubeScale); cubeCol [cubeInstanceIndex] = color; cubeInstanceIndex++; if (cubeInstanceIndex == 510) //TODO: allokierter Buffer für alle Werte statt der nur 1024 Konstanten-Register { cubeShader->uniform("u_posScale", cubePosScale, cubeInstanceIndex); cubeShader->uniform("u_color", cubeCol, cubeInstanceIndex); drawArray(GL_TRIANGLE_STRIP, semicube, NULL, NULL, NULL, NULL, sizeof(semicube) / (3 * sizeof(float)), cubeInstanceIndex); cubeInstanceIndex = 0; } } } } cubeShader->uniform("u_posScale", cubePosScale, cubeInstanceIndex); cubeShader->uniform("u_color", cubeCol, cubeInstanceIndex); drawArray(GL_TRIANGLE_STRIP, semicube, NULL, NULL, NULL, NULL, sizeof(semicube) / (3 * sizeof(float)), cubeInstanceIndex); cubeShader->unbind(); floorShader->bind(); setBlendMode(BLEND_ALPHA); floorShader->uniform("u_eye", eye); floorShader->uniform("u_matrix", projView); floorShader->uniform("u_fade", fadeIn); drawArray(GL_TRIANGLE_FAN, floorVerts, NULL, NULL, NULL, NULL, sizeof(floorVerts) / (3 * sizeof(float))); floorShader->unbind(); if (!fadeActive) { fboOverlay->unbind(); setBlendMode(NO_BLEND); setCullMode(NO_CULL); setDepthMode(NO_DEPTH); kratzerShader->bind(); kratzerShader->bindFbo("src", fboOverlay, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); kratzerShader->bindTexture("tex", kratzer, 1); kratzerShader->uniform("u_fade", fade2); drawFullscreenQuad(); kratzerShader->unbind(); } setDepthMode(NO_DEPTH); setBlendMode(BLEND_ALPHA); setCullMode(NO_CULL); if (fadeIn >= 1.0f) { float creditsStart = 3.f; float creditsDuration = (SceneTime::lazorsStart - SceneTime::cubewallStart) - creditsStart; float creditTime = (time - creditsStart - 1.f) * 3.f / creditsDuration; float pos = floor(creditTime); creditsShader->bind(); creditsShader->bindTexture("tex", credits, 0); creditsShader->uniform("fade", 2 * (creditTime - pos)); drawRect(vec2(-1, -1 + 0.1185), vec2(1, -1 + 2 * 0.1185), vec2(0, (1. / 3.)*(pos + 1)), vec2(1, (1. / 3.)*pos)); creditsShader->unbind(); } }