void VertexBuffer::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) { ProgramObject *p = rc->GetCurProgram(); if (p) p->updateMatrices(); Bind(); glDrawArraysInstanced(mode, first, count, instanceCount); }
bool csShaderGLCGCommon::WriteToCache (iHierarchicalCache* cache, const ProfileLimits& limits, const ProfileLimitsPair& limitsPair, const char* tag) { csString objectCode; if (program != 0) objectCode = cgGetProgramString (program, CG_COMPILED_PROGRAM); ProgramObject programObj (objectCode, programPositionInvariant ? ProgramObject::flagPositionInvariant : 0, unusedParams); const char* preprocSource (cgGetProgramString (program, CG_PROGRAM_SOURCE)); csString failReason; ProgramObjectID progId; if (!shaderPlug->progCache.WriteObject (preprocSource, limits, programObj, progId, failReason)) { if (shaderPlug->doVerbose) { csReport (objectReg, CS_REPORTER_SEVERITY_WARNING, "crystalspace.graphics3d.shader.glcg", "Error writing %s program for %s to compile cache: %s", GetProgramType(), tag, failReason.GetData()); } return false; } programObj.SetID (progId); return WriteToCache (cache, limits, limitsPair, tag, programObj); }
void VertexBuffer::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLsizei instanceCount, int offset) { ProgramObject *p = rc->GetCurProgram(); if (p) p->updateMatrices(); Bind(); glDrawElementsInstanced(mode, count, type, (void *)offset, instanceCount); }
int main(int /*argc*/, char ** /*argv*/) { BaseApp app; ProgramObject program; auto mainWindow = app.getMainWindow(); std::string prefix = app.getResourceDir() + "Shaders/Examples/e06_ModelLoader/"; PerspectiveCamera cam; OrbitManipulator manipulator(&cam); manipulator.setupCallbacks(app); NodeShared root; GLuint query[2]; app.addInitCallback([&]() { auto vs = compileShader(GL_VERTEX_SHADER, Loader::text(prefix + "phong.vert")); auto fs = compileShader(GL_FRAGMENT_SHADER, Loader::text(prefix + "phong.frag")); program = createProgram(vs, fs); root = Loader::scene(app.getResourceDir() + "Models/sponza/sponza.fbx"); glCreateQueries(GL_TIMESTAMP, 2, query); SDL_GL_SetSwapInterval(0); }); app.addResizeCallback([&](int w, int h) { glViewport(0, 0, w, h); cam.setAspect(float(w) / float(h)); }); app.addDrawCallback([&]() { glQueryCounter(query[0], GL_TIMESTAMP); glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); //bunny program.use(); program.setMatrix4fv("p", value_ptr(cam.getProjection())); program.setMatrix4fv("v", value_ptr(cam.getView())); drawNode(program, root); glQueryCounter(query[1], GL_TIMESTAMP); GLuint64 time1, time2; glGetQueryObjectui64v(query[0], GL_QUERY_RESULT, &time1); glGetQueryObjectui64v(query[1], GL_QUERY_RESULT, &time2); std::string s = "fps: " + std::to_string(1e9 / (time2 - time1)) + " (" + std::to_string(ImGui::GetIO().Framerate) + ")"; label(s, 0, 0, 300, 100); }); return app.run(); }
void VertexBuffer::DrawElements(GLenum mode, GLsizei count, GLenum type, int offset) { ProgramObject *p = rc->GetCurProgram(); if (p) p->updateMatrices(); if (GLEW_ARB_vertex_buffer_object) { Bind(); glDrawElements(mode, count, type, (void *)offset); } else { glDrawElements(mode, count, type, ptr->data + offset); } }
void GL3GraphicContextProvider::set_program_object(const ProgramObject &program) { OpenGL::set_active(this); if (glUseProgram == nullptr) return; if (program.is_null()) glUseProgram(0); else { glUseProgram(program.get_handle()); } }
ProgramObject HSV::create_shader_program(GraphicContext &gc) { ProgramObject program = ProgramObject::load(gc, "Resources/vertex.glsl", "Resources/fragment.glsl"); program.bind_attribute_location(0, "Position"); program.bind_attribute_location(1, "TexCoord0"); program.set_uniform_buffer_index("ProgramUniforms", 0); if (!program.link()) throw Exception("Unable to link program"); return program; }
void CubeBlock::DrawWhiteBorders(GLRenderingContext *rc, bool whiteBorders) { if (whiteBorders) { borderAmbient = Color3f(0.8f); borderDiffuse = Color3f(0.85f); } else { borderAmbient = Color3f(0.0f); borderDiffuse = Color3f(0.35f); } ProgramObject *p = rc->GetCurProgram(); p->Uniform("BorderMaterial.ambient", 1, borderAmbient.data); p->Uniform("BorderMaterial.diffuse", 1, borderDiffuse.data); }
void App::draw_image(GraphicContext &gc, Texture &image, float xpos, float ypos, ProgramObject &program_object, Vec4f &draw_color_offset) { program_object.set_uniform1i("SourceTexture", 0); program_object.set_uniform4f("color_offset", draw_color_offset); gc.set_texture(0, image); gc.set_program_object(program_object, cl_program_matrix_modelview_projection); draw_texture(gc, Rectf(xpos, ypos, Sizef(image.get_width(), image.get_height())), Colorf::white, Rectf(0.0f, 0.0f, 1.0f, 1.0f)); gc.reset_program_object(); gc.reset_texture(0); }
void GLRC_Text2DModule::Initialize(GLRenderingContext *rc) { if (GLEW_ARB_shader_objects) { prog = new ProgramObject(rc); Shader vshader(GL_VERTEX_SHADER); Shader fshader(GL_FRAGMENT_SHADER); vshader.CompileSource(shaderSource[0]); fshader.CompileSource(shaderSource[1]); prog->AttachShader(vshader); prog->AttachShader(fshader); prog->Link(); prog->Uniform("ColorMap", 0); } else prog = NULL; }
UniformBuffer::UniformBuffer(GraphicContext &gc, ProgramObject &program, const std::string &name, int num_blocks, BufferUsage usage) : impl(std::make_shared<UniformBuffer_Impl>()) { GraphicContextProvider *gc_provider = gc.get_provider(); impl->provider = gc_provider->alloc_uniform_buffer(); impl->provider->create(program.get_uniform_buffer_size(name) * num_blocks, usage); }
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations) { program.bind(); locations.clusterMatrices = program.uniformLocation("clusterMatrices"); locations.clusterIndices = program.attributeLocation("clusterIndices"); locations.clusterWeights = program.attributeLocation("clusterWeights"); locations.tangent = program.attributeLocation("tangent"); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); program.release(); }
static ProgramObject* createProgram(const QString& name) { ProgramObject* program = new ProgramObject(); program->addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/" + name + ".frag"); program->link(); program->bind(); program->setUniformValue("originalTexture", 0); program->release(); return program; }
void ShaderEffect_Impl::create_shaders(GraphicContext &gc, const ShaderEffectDescription_Impl *description) { std::string vertex_shader_code = add_defines(gc, description->vertex_shader_code, description); std::string fragment_shader_code = add_defines(gc, description->fragment_shader_code, description); std::string compute_shader_code = add_defines(gc, description->compute_shader_code, description); if (!vertex_shader_code.empty()) { ShaderObject vertex_shader(gc, shadertype_vertex, vertex_shader_code); if(!vertex_shader.compile()) throw Exception(string_format("Unable to compile vertex shader: %1", vertex_shader.get_info_log())); program.attach(vertex_shader); } if (!fragment_shader_code.empty()) { ShaderObject fragment_shader(gc, shadertype_fragment, fragment_shader_code); if(!fragment_shader.compile()) throw Exception(string_format("Unable to compile fragment shader: %1", fragment_shader.get_info_log())); program.attach(fragment_shader); } if (!compute_shader_code.empty()) { ShaderObject compute_shader(gc, shadertype_compute, compute_shader_code); if(!compute_shader.compile()) throw Exception(string_format("Unable to compile compute shader: %1", compute_shader.get_info_log())); program.attach(compute_shader); } int index = 0; for(const auto & elem : description->attributes) { program.bind_attribute_location(index++, elem.first); } index = 0; for(const auto & elem : description->frag_data) { program.bind_frag_data_location(index++, elem.first); } if (!program.link()) throw Exception(string_format("Link failed: %1", program.get_info_log())); index = 0; for(auto it = description->uniform_buffers.begin(); it != description->uniform_buffers.end(); ++it, index++) { program.set_uniform_buffer_index(it->first, index); uniform_bindings[index] = it->second; } index = 0; for(auto it = description->textures.begin(); it != description->textures.end(); ++it, index++) { program.set_uniform1i(it->first, index); texture_bindings[index] = it->second; } index = 0; for(auto it = description->images.begin(); it != description->images.end(); ++it, index++) { program.set_uniform1i(it->first, index); image_bindings[index] = it->second; } index = 0; for(auto it = description->storage_buffers.begin(); it != description->storage_buffers.end(); ++it, index++) { program.set_uniform1i(it->first, index); storage_bindings[index] = it->second; } }
int App::start(const std::vector<std::string> &args) { OpenGLWindowDescription description; description.set_title("UniformBlock Shader"); //description.set_version(3, 1, false); description.set_size(Size(1024, 768), true); DisplayWindow window(description); InputDevice keyboard = window.get_ic().get_keyboard(); GraphicContext gc = window.get_gc(); Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &App::on_input_up); Slot slot_window_close = window.sig_window_close().connect(this, &App::window_close); // Load and link shaders ProgramObject shader = ProgramObject::load(gc, "Resources/vertex_shader.glsl", "Resources/fragment_shader.glsl"); shader.bind_attribute_location(0, "Position"); if (!shader.link()) throw Exception("Unable to link shader program: Error:" + shader.get_info_log()); int block_size = shader.get_uniform_block_size("TestBlock"); const int num_blocks = 16; ProgramUniformBlock block(gc, block_size * num_blocks); std::vector<float> data_to_upload; data_to_upload.resize((num_blocks * block_size) / sizeof(float) ); float test_colour = 1.0f; for (int cnt=0; cnt<num_blocks; cnt++) { int offset = cnt * block_size / sizeof(float) ; data_to_upload[offset + 0] = test_colour; data_to_upload[offset + 1] = 0.5f; data_to_upload[offset + 2] = 1.0f; test_colour -= 0.05f; } block.upload_data(0, &data_to_upload[0], block_size * num_blocks); quit = false; Font font(gc, "tahoma", 32); clan::ubyte64 startTime = System::get_time(); //// Test code //GLuint uniform_index = -1; //const char *names[] = {"src_color"}; //glGetUniformIndices(handle, 1, names, &uniform_index); //if (uniform_index >=0) //{ // GLint offset; // GLint singleSize; // GLint uniform_type; // glGetActiveUniformsiv(handle, 1, &uniform_index, GL_UNIFORM_TYPE, &uniform_type); // glGetActiveUniformsiv(handle, 1, &uniform_index, GL_UNIFORM_OFFSET, &offset); // glGetActiveUniformsiv(handle, 1, &uniform_index, GL_UNIFORM_SIZE, &singleSize); // if ((uniform_type != GL_FLOAT_VEC3) || (offset !=0) || (singleSize != 1)) // { // throw Exception("well it seems it does not work"); // } //} while (!quit) { gc.clear(Colorf(0.1f, 0.1f, 0.2f)); OpenGL::check_error(); for (int test_run_y=0; test_run_y < 16; test_run_y++) { shader.set_uniform_block("TestBlock", block, test_run_y*block_size); for (int test_run_x=0; test_run_x < 16; test_run_x++) { Vec2f positions[3]; float size = 32.0f; positions[0].x = test_run_x * size; positions[0].y = test_run_y * size + size; positions[1].x = test_run_x * size + size; positions[1].y = test_run_y * size + size; positions[2].x = test_run_x * size + size; positions[2].y = test_run_y * size; PrimitivesArray prim_array(gc); prim_array.set_attributes(0, positions); gc.set_program_object(shader, cl_program_matrix_modelview_projection); gc.draw_primitives(cl_triangles, 3, prim_array); gc.reset_program_object(); } } font.draw_text(gc, 32, 200, "Hello World"); window.flip(1); KeepAlive::process(); } return 0; }
void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& data){ ProgramObject* programObject = getActivatedProgramWithTileData( _globalRenderingShaderProvider.get(), _globalProgramUniformHandler, chunk); if (programObject == nullptr) { return; } const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); bool performAnyBlending = false; for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; ++i) { LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory)i; if(_tileProviderManager->getTileProviderGroup(i).levelBlendingEnabled && _tileProviderManager->getTileProviderGroup(category).getActiveTileProviders().size() > 0){ performAnyBlending = true; break; } } if (performAnyBlending) { // Calculations are done in the reference frame of the globe. Hence, the camera // position needs to be transformed with the inverse model matrix glm::dmat4 inverseModelTransform = chunk.owner()->inverseModelTransform(); glm::dvec3 cameraPosition = glm::dvec3(inverseModelTransform * glm::dvec4(data.camera.positionVec3(), 1)); float distanceScaleFactor = chunk.owner()->lodScaleFactor * ellipsoid.minimumRadius(); programObject->setUniform("cameraPosition", vec3(cameraPosition)); programObject->setUniform("distanceScaleFactor", distanceScaleFactor); programObject->setUniform("chunkLevel", chunk.index().level); } // Calculate other uniform variables needed for rendering Geodetic2 swCorner = chunk.surfacePatch().getCorner(Quad::SOUTH_WEST); auto patchSize = chunk.surfacePatch().size(); dmat4 modelTransform = chunk.owner()->modelTransform(); dmat4 viewTransform = data.camera.combinedViewMatrix(); mat4 modelViewTransform = mat4(viewTransform * modelTransform); mat4 modelViewProjectionTransform = data.camera.projectionMatrix() * modelViewTransform; // Upload the uniform variables programObject->setUniform("modelViewProjectionTransform", modelViewProjectionTransform); programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2())); programObject->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2())); programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared())); if (_tileProviderManager->getTileProviderGroup( LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || _tileProviderManager->getTileProviderGroup( LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = (viewTransform * glm::dvec4(directionToSunWorldSpace, 0)); data.modelTransform.translation; programObject->setUniform("modelViewTransform", modelViewTransform); programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace); } // OpenGL rendering settings glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // render _grid->geometry().drawUsingActiveProgram(); // disable shader programObject->deactivate(); }
void StandardPrograms::link(ProgramObject &program, const std::string &error_message) { if (!program.link()) throw Exception(string_format("%1: %2", error_message, program.get_info_log())); }
void DeferredLightingEffect::render() { // perform deferred lighting, rendering to free fbo glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_COLOR_MATERIAL); glDepthMask(false); QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); primaryFBO->release(); QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); freeFBO->bind(); glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimarySpecularTextureID()); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); // get the viewport side (left, right, both) int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); const int VIEWPORT_X_INDEX = 0; const int VIEWPORT_Y_INDEX = 1; const int VIEWPORT_WIDTH_INDEX = 2; const int VIEWPORT_HEIGHT_INDEX = 3; float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); float tMin = viewport[VIEWPORT_Y_INDEX] / (float)primaryFBO->height(); float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)primaryFBO->height(); ProgramObject* program = &_directionalLight; const LightLocations* locations = &_directionalLightLocations; bool shadowsEnabled = Menu::getInstance()->getShadowsEnabled(); if (shadowsEnabled) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); program = &_directionalLightShadowMap; locations = &_directionalLightShadowMapLocations; if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { program = &_directionalLightCascadedShadowMap; locations = &_directionalLightCascadedShadowMapLocations; _directionalLightCascadedShadowMap.bind(); _directionalLightCascadedShadowMap.setUniform(locations->shadowDistances, Application::getInstance()->getShadowDistances()); } else { program->bind(); } program->setUniformValue(locations->shadowScale, 1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width()); } else { program->bind(); } float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; Application::getInstance()->computeOffAxisFrustum( left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); program->setUniformValue(locations->nearLocation, nearVal); float depthScale = (farVal - nearVal) / farVal; program->setUniformValue(locations->depthScale, depthScale); float nearScale = -1.0f / nearVal; float depthTexCoordScaleS = (right - left) * nearScale / sWidth; float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; program->setUniformValue(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); program->release(); if (shadowsEnabled) { glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE3); } // additive blending glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_CULL_FACE); glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients); glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients); // enlarge the scales slightly to account for tesselation const float SCALE_EXPANSION = 0.05f; const glm::vec3& eyePoint = Application::getInstance()->getDisplayViewFrustum()->getPosition(); float nearRadius = glm::distance(eyePoint, Application::getInstance()->getDisplayViewFrustum()->getNearTopLeft()); if (!_pointLights.isEmpty()) { _pointLight.bind(); _pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal); _pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); foreach (const PointLight& light, _pointLights) { _pointLight.setUniformValue(_pointLightLocations.radius, light.radius); glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position); glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (light.constantAttenuation > 0.0f ? light.constantAttenuation : 0.0f)); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, (light.linearAttenuation > 0.0f ? light.linearAttenuation : 0.0f)); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (light.quadraticAttenuation > 0.0f ? light.quadraticAttenuation : 0.0f)); glPushMatrix(); float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION); if (glm::distance(eyePoint, glm::vec3(light.position)) < expandedRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); renderFullscreenQuad(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } else { glTranslatef(light.position.x, light.position.y, light.position.z); Application::getInstance()->getGeometryCache()->renderSphere(expandedRadius, 32, 32); } glPopMatrix(); }
bool csShaderGLCGCommon::WriteToCacheWorker (iHierarchicalCache* cache, const ProfileLimits& limits, const ProfileLimitsPair& limitsPair, const char* tag, const ProgramObject& program, csString& failReason) { if (!cache) return false; csMemFile cacheFile; uint32 diskMagic = csLittleEndian::UInt32 (cacheFileMagic); if (cacheFile.Write ((char*)&diskMagic, sizeof (diskMagic)) != sizeof (diskMagic)) { failReason = "write error (magic)"; return false; } csRef<iDataBuffer> programBuffer = GetProgramData(); CS::Utility::Checksum::MD5::Digest progHash = CS::Utility::Checksum::MD5::Encode ( programBuffer->GetData(), programBuffer->GetSize()); if (cacheFile.Write ((char*)&progHash, sizeof (progHash)) != sizeof (progHash)) { failReason = "write error (hash)"; return false; } if (!program.IsValid()) { uint32 diskState = csLittleEndian::UInt32 (cpsInvalid); if (cacheFile.Write ((char*)&diskState, sizeof (diskState)) != sizeof (diskState)) { failReason = "write error (state-invalid)"; return false; } } else { { uint32 diskState = csLittleEndian::UInt32 (cpsValid); if (cacheFile.Write ((char*)&diskState, sizeof (diskState)) != sizeof (diskState)) { failReason = "write error (state-valid)"; return false; } } CS::PluginCommon::ShaderCacheHelper::WriteString (&cacheFile, description); CS_ASSERT(!program.GetID().archive.IsEmpty()); CS::PluginCommon::ShaderCacheHelper::WriteString (&cacheFile, program.GetID().archive); CS_ASSERT(!program.GetID().item.IsEmpty()); CS::PluginCommon::ShaderCacheHelper::WriteString (&cacheFile, program.GetID().item); } csString cacheName ("/"); cacheName += tag; if (!cache->CacheData (cacheFile.GetData(), cacheFile.GetSize(), cacheName)) { failReason = "failed writing to cache"; return false; } return true; }
// The start of the Application int App::start(const std::vector<std::string> &args) { try { DisplayWindowDescription win_desc; win_desc.set_allow_resize(true); win_desc.set_title("HDR Example"); win_desc.set_size(Size( 600, 630 ), false); DisplayWindow window(win_desc); Slot slot_quit = window.sig_window_close().connect(this, &App::on_window_close); Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &App::on_input_up); GraphicContext gc = window.get_gc(); // Load and link shaders ProgramObject shader = ProgramObject::load(gc, "Resources/vertex_shader.glsl", "Resources/fragment_shader.glsl"); shader.bind_attribute_location(0, "Position"); shader.bind_attribute_location(2, "TexCoord0"); if (!shader.link()) throw Exception("Unable to link shader program: Error:" + shader.get_info_log()); const float dynamic_range_start = -1.5f; const float dynamic_range_end = 1.5f; const Size image_size(gc.get_width() - 64, 128); Texture image_rgb32f = create_rgb32f(gc, image_size, dynamic_range_start, dynamic_range_end); Font font(gc, "Tahoma", 20); clan::ubyte64 time_last = System::get_time(); bool direction = false; while (!quit) { clan::ubyte64 time_now = System::get_time(); time_delta = ((float) time_now - time_last) / 1000.0f; time_last = time_now; if (direction) { color_offset.r += time_delta * 1.0f; if (color_offset.r > 2.0f) { color_offset.r = 2.0f; direction = false; } } else { color_offset.r -= time_delta * 1.0f; if (color_offset.r < -2.0f) { color_offset.r = -2.0f; direction = true; } } color_offset.g = color_offset.r; color_offset.b = color_offset.r; gc.clear(Colorf(0.2f,0.2f,0.5f)); font.draw_text(gc, 32, 50, "Showing Texture RGB values from " + StringHelp::float_to_text(dynamic_range_start) + " to " + StringHelp::float_to_text(dynamic_range_end)); draw_image(gc, image_rgb32f, 32.0f, 100.0f, shader, Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); font.draw_text(gc, 32, 350, "Showing Texture with an offset to the floating point color component"); draw_image(gc, image_rgb32f, 32.0f, 400.0f, shader, color_offset); KeepAlive::process(0); window.flip(1); } } catch(Exception &exception) { // Create a console window for text-output if not available ConsoleWindow console("Console", 80, 160); Console::write_line("Exception caught: " + exception.get_message_and_stack_trace()); console.display_close_message(); return -1; } return 0; }
ProgramObject LightsourceSimplePass::compile_and_link(GraphicContext &gc, const std::string &shader_path, const std::string &type) { ProgramObject program; std::string vertex_filename = PathHelp::combine(shader_path, string_format("LightsourceSimple/vertex_%1.%2", type, gc.get_shader_language() == shader_glsl ? "glsl" : "hlsl")); std::string fragment_filename = PathHelp::combine(shader_path, string_format("LightsourceSimple/fragment_light.%1", gc.get_shader_language() == shader_glsl ? "glsl" : "hlsl")); program = ShaderSetup::compile(gc, "", vertex_filename, fragment_filename, type == "rect" ? "RECT_PASS" : ""); program.bind_frag_data_location(0, "FragColor"); if (!program.link()) throw Exception("Shader linking failed!"); program.bind_attribute_location(0, "AttrPositionInObject"); program.set_uniform_buffer_index("Uniforms", 0); program.set_uniform1i("InstanceTexture", 0); program.set_uniform1i("NormalZTexture", 1); program.set_uniform1i("DiffuseColorTexture", 2); program.set_uniform1i("SpecularColorTexture", 3); program.set_uniform1i("SpecularLevelTexture", 4); program.set_uniform1i("ShadowMapsTexture", 5); program.set_uniform1i("ShadowMapsTextureSampler", 5); program.set_uniform1i("SelfIlluminationTexture", 6); return program; }
void D3DGraphicContextProvider::set_program_object(const ProgramObject &program) { D3DProgramObjectProvider *new_program_provider = static_cast<D3DProgramObjectProvider *>(program.get_provider()); if (new_program_provider == current_program_provider) return; if (current_program_provider) unit_map.unbind_program(this, current_program_provider); current_program_provider = new_program_provider; clear_input_layout(); for (int j = 0; j < shadertype_num_types; j++) { D3DShaderObjectProvider *shader_provider = current_program_provider->get_shader_provider((ShaderType)j); if (shader_provider) { switch (j) { case shadertype_vertex: window->get_device_context()->VSSetShader(shader_provider->get_vertex(), 0, 0); break; case shadertype_tess_control: window->get_device_context()->HSSetShader(shader_provider->get_hull(), 0, 0); break; case shadertype_tess_evaluation: window->get_device_context()->DSSetShader(shader_provider->get_domain(), 0, 0); break; case shadertype_geometry: window->get_device_context()->GSSetShader(shader_provider->get_geometry(), 0, 0); break; case shadertype_fragment: window->get_device_context()->PSSetShader(shader_provider->get_pixel(), 0, 0); break; case shadertype_compute: window->get_device_context()->CSSetShader(shader_provider->get_compute(), 0, 0); break; } shader_bound[j] = true; } else if (shader_bound[j]) { switch (j) { case shadertype_vertex: window->get_device_context()->VSSetShader(0, 0, 0); break; case shadertype_tess_control: window->get_device_context()->HSSetShader(0, 0, 0); break; case shadertype_tess_evaluation: window->get_device_context()->DSSetShader(0, 0, 0); break; case shadertype_geometry: window->get_device_context()->GSSetShader(0, 0, 0); break; case shadertype_fragment: window->get_device_context()->PSSetShader(0, 0, 0); break; case shadertype_compute: window->get_device_context()->CSSetShader(0, 0, 0); break; } shader_bound[j] = false; } } unit_map.bind_program(this, current_program_provider); }
int main(int /*argc*/, char ** /*argv*/) { BaseApp app; ProgramObject programPlanet; ProgramObject programAtmosphere; ProgramObject programStars; auto mainWindow = app.getMainWindow(); PerspectiveCamera cam; OrbitManipulator manipulator(&cam); manipulator.setupCallbacks(app); GLuint vao; GLuint vbo; bool wireframe = false; int starCount = 20000; int seed = 0; app.addInitCallback([&]() { string prefix = app.getResourceDir() + "shaders/Nei/n01_Planet/"; auto vert = compileShader(GL_VERTEX_SHADER, Loader::text(prefix + "empty.vert")); auto tesc = compileShader(GL_TESS_CONTROL_SHADER, Loader::text(prefix + "planet.tesc")); auto tese = compileShader(GL_TESS_EVALUATION_SHADER, Loader::text(prefix + "planet.tese")); auto frag = compileShader(GL_FRAGMENT_SHADER, Loader::text(prefix + "planet.frag")); programPlanet = createProgram(vert, tesc, tese, frag); vert = compileShader(GL_VERTEX_SHADER, Loader::text(prefix + "empty.vert")); tesc = compileShader(GL_TESS_CONTROL_SHADER, Loader::text(prefix + "atmosphere.tesc")); tese = compileShader(GL_TESS_EVALUATION_SHADER, Loader::text(prefix + "atmosphere.tese")); frag = compileShader(GL_FRAGMENT_SHADER, Loader::text(prefix + "atmosphere.frag")); programAtmosphere = createProgram(vert, tesc, tese, frag); vert = compileShader(GL_VERTEX_SHADER, Loader::text(prefix + "stars.vert")); frag = compileShader(GL_FRAGMENT_SHADER, Loader::text(prefix + "stars.frag")); programStars = createProgram(vert, frag); glCreateVertexArrays(1, &vao); float distance = 400; vector<vec4> vec; vec.reserve(starCount); for (int i = 0; i<starCount; i++) { float a = ((float)rand() / RAND_MAX - 0.5); float b = ((float)rand() / RAND_MAX - 0.5); float c = ((float)rand() / RAND_MAX - 0.5); float d = (float)rand() / RAND_MAX * 5 + 1; vec4 v(a, b, c, 0); v = normalize(v); v *= distance; v.w = d; vec.push_back(v); } glCreateBuffers(1, &vbo); glNamedBufferData(vbo, sizeof(vec4)*vec.size(), vec.data(), GL_STATIC_DRAW); glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(vec4)); glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, 0, 0); glEnableVertexArrayAttrib(vao, 0); glBindVertexArray(vao); }); app.addUpdateCallback([&](float dt) { manipulator.update(dt); }); app.addDrawCallback([&]() { int w = mainWindow->getWidth(); int h = mainWindow->getHeight(); glViewport(0, 0, w, h); glClearColor(0, 0, 0, 1); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL); programStars.use(); programStars.setMatrix4fv("v", value_ptr(cam.getView())); programStars.setMatrix4fv("p", value_ptr(cam.getProjection())); glEnable(GL_PROGRAM_POINT_SIZE); glDrawArrays(GL_POINTS, 0, starCount); programPlanet.use(); programPlanet.setMatrix4fv("v", value_ptr(cam.getView())); programPlanet.setMatrix4fv("p", value_ptr(cam.getProjection())); programPlanet.set3fv("camPos", value_ptr(cam.getEye())); programPlanet.set1i("seed", seed); programPlanet.set1f("time", app.getTimeFromStart()); glPatchParameteri(GL_PATCH_VERTICES, 1); glDrawArraysInstanced(GL_PATCHES, 0, 1, 16); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); programAtmosphere.use(); programAtmosphere.setMatrix4fv("v", value_ptr(cam.getView())); programAtmosphere.setMatrix4fv("p", value_ptr(cam.getProjection())); programAtmosphere.set3fv("camPos", value_ptr(cam.getEye())); programAtmosphere.set1ui("seed", seed); programAtmosphere.set1f("time", app.getTimeFromStart()); glPatchParameteri(GL_PATCH_VERTICES, 1); glDrawArrays(GL_PATCHES, 0, 1); }); return app.run(); }
ProgramObject* ChunkRenderer::getActivatedProgramWithTileData( LayeredTextureShaderProvider* layeredTextureShaderProvider, std::shared_ptr<LayeredTextureShaderUniformIdHandler> programUniformHandler, const Chunk& chunk) { const ChunkIndex& chunkIndex = chunk.index(); std::array<std::vector<std::shared_ptr<TileProvider> >, LayeredTextures::NUM_TEXTURE_CATEGORIES> tileProviders; LayeredTexturePreprocessingData layeredTexturePreprocessingData; for (size_t category = 0; category < LayeredTextures::NUM_TEXTURE_CATEGORIES; category++) { tileProviders[category] = _tileProviderManager->getTileProviderGroup(category).getActiveTileProviders(); LayeredTextureInfo layeredTextureInfo; layeredTextureInfo.lastLayerIdx = tileProviders[category].size() - 1; layeredTextureInfo.layerBlendingEnabled = _tileProviderManager->getTileProviderGroup(category).levelBlendingEnabled; layeredTexturePreprocessingData.layeredTextureInfo[category] = layeredTextureInfo; } layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair<std::string, std::string>( "useAtmosphere", std::to_string(chunk.owner()->atmosphereEnabled))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair<std::string, std::string>( "showChunkEdges", std::to_string(chunk.owner()->debugOptions.showChunkEdges))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair<std::string, std::string>( "showHeightResolution", std::to_string(chunk.owner()->debugOptions.showHeightResolution))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair<std::string, std::string>( "showHeightIntensities", std::to_string(chunk.owner()->debugOptions.showHeightIntensities))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair<std::string, std::string>( "defaultHeight", std::to_string(Chunk::DEFAULT_HEIGHT))); // Now the shader program can be accessed ProgramObject* programObject = layeredTextureShaderProvider->getUpdatedShaderProgram( layeredTexturePreprocessingData); programUniformHandler->updateIdsIfNecessary(layeredTextureShaderProvider); // Activate the shader program programObject->activate(); // Initialize all texture units struct BlendTexUnits { ghoul::opengl::TextureUnit blendTexture0; ghoul::opengl::TextureUnit blendTexture1; ghoul::opengl::TextureUnit blendTexture2; }; std::array<std::vector<BlendTexUnits>, LayeredTextures::NUM_TEXTURE_CATEGORIES> texUnits; for (size_t category = 0; category < LayeredTextures::NUM_TEXTURE_CATEGORIES; category++) { texUnits[category].resize(tileProviders[category].size()); } // Go through all the categories for (size_t category = 0; category < LayeredTextures::NUM_TEXTURE_CATEGORIES; category++) { // Go through all the providers in this category int i = 0; for (auto it = tileProviders[category].begin(); it != tileProviders[category].end(); it++) { auto tileProvider = it->get(); // Get the texture that should be used for rendering TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex); if (tileAndTransform.tile.status == Tile::Status::Unavailable) { tileAndTransform.tile = tileProvider->getDefaultTile(); tileAndTransform.uvTransform.uvOffset = { 0, 0 }; tileAndTransform.uvTransform.uvScale = { 1, 1 }; } activateTileAndSetTileUniforms( programUniformHandler, LayeredTextures::TextureCategory(category), LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::none, i, texUnits[category][i].blendTexture0, tileAndTransform); // If blending is enabled, two more textures are needed if (layeredTexturePreprocessingData.layeredTextureInfo[category].layerBlendingEnabled) { TileAndTransform tileAndTransformParent1 = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex, 1); if (tileAndTransformParent1.tile.status == Tile::Status::Unavailable) { tileAndTransformParent1 = tileAndTransform; } activateTileAndSetTileUniforms( programUniformHandler, LayeredTextures::TextureCategory(category), LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::Parent1, i, texUnits[category][i].blendTexture1, tileAndTransformParent1); TileAndTransform tileAndTransformParent2 = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex, 2); if (tileAndTransformParent2.tile.status == Tile::Status::Unavailable) { tileAndTransformParent2 = tileAndTransformParent1; } activateTileAndSetTileUniforms( programUniformHandler, LayeredTextures::TextureCategory(category), LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::Parent2, i, texUnits[category][i].blendTexture2, tileAndTransformParent2); } /* if (category == LayeredTextures::HeightMaps && tileAndTransform.tile.preprocessData) { //auto preprocessingData = tileAndTransform.tile.preprocessData; //float noDataValue = preprocessingData->noDataValues[0]; programObject->setUniform( "minimumValidHeight[" + std::to_string(i) + "]", -100000); } */ i++; } } // Go through all the height maps and set depth tranforms int i = 0; auto it = tileProviders[LayeredTextures::HeightMaps].begin(); auto end = tileProviders[LayeredTextures::HeightMaps].end(); for (; it != end; it++) { auto tileProvider = *it; TileDepthTransform depthTransform = tileProvider->depthTransform(); setDepthTransformUniforms( programUniformHandler, LayeredTextures::TextureCategory::HeightMaps, LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::none, i, depthTransform); i++; } // The length of the skirts is proportional to its size programObject->setUniform("skirtLength", min(static_cast<float>(chunk.surfacePatch().halfSize().lat * 1000000), 8700.0f)); programObject->setUniform("xSegments", _grid->xSegments()); if (chunk.owner()->debugOptions.showHeightResolution) { programObject->setUniform("vertexResolution", glm::vec2(_grid->xSegments(), _grid->ySegments())); } return programObject; }
void DeferredLightingEffect::render(RenderArgs* args) { // perform deferred lighting, rendering to free fbo glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_COLOR_MATERIAL); glDepthMask(false); auto textureCache = DependencyManager::get<TextureCache>(); glBindFramebuffer(GL_FRAMEBUFFER, 0 ); QSize framebufferSize = textureCache->getFrameBufferSize(); // binding the first framebuffer auto freeFBO = DependencyManager::get<GlowEffect>()->getFreeFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(freeFBO)); glClear(GL_COLOR_BUFFER_BIT); // glEnable(GL_FRAMEBUFFER_SRGB); // glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryColorTextureID()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryNormalTextureID()); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textureCache->getPrimarySpecularTextureID()); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryDepthTextureID()); // get the viewport side (left, right, both) int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); const int VIEWPORT_X_INDEX = 0; const int VIEWPORT_Y_INDEX = 1; const int VIEWPORT_WIDTH_INDEX = 2; const int VIEWPORT_HEIGHT_INDEX = 3; float sMin = viewport[VIEWPORT_X_INDEX] / (float)framebufferSize.width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)framebufferSize.width(); float tMin = viewport[VIEWPORT_Y_INDEX] / (float)framebufferSize.height(); float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)framebufferSize.height(); bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); // Fetch the ViewMatrix; glm::mat4 invViewMat; _viewState->getViewTransform().getMatrix(invViewMat); ProgramObject* program = &_directionalLight; const LightLocations* locations = &_directionalLightLocations; bool shadowsEnabled = _viewState->getShadowsEnabled(); if (shadowsEnabled) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, textureCache->getShadowDepthTextureID()); program = &_directionalLightShadowMap; locations = &_directionalLightShadowMapLocations; if (_viewState->getCascadeShadowsEnabled()) { program = &_directionalLightCascadedShadowMap; locations = &_directionalLightCascadedShadowMapLocations; if (useSkyboxCubemap) { program = &_directionalSkyboxLightCascadedShadowMap; locations = &_directionalSkyboxLightCascadedShadowMapLocations; } else if (_ambientLightMode > -1) { program = &_directionalAmbientSphereLightCascadedShadowMap; locations = &_directionalAmbientSphereLightCascadedShadowMapLocations; } program->bind(); program->setUniform(locations->shadowDistances, _viewState->getShadowDistances()); } else { if (useSkyboxCubemap) { program = &_directionalSkyboxLightShadowMap; locations = &_directionalSkyboxLightShadowMapLocations; } else if (_ambientLightMode > -1) { program = &_directionalAmbientSphereLightShadowMap; locations = &_directionalAmbientSphereLightShadowMapLocations; } program->bind(); } program->setUniformValue(locations->shadowScale, 1.0f / textureCache->getShadowFramebuffer()->getWidth()); } else { if (useSkyboxCubemap) { program = &_directionalSkyboxLight; locations = &_directionalSkyboxLightLocations; } else if (_ambientLightMode > -1) { program = &_directionalAmbientSphereLight; locations = &_directionalAmbientSphereLightLocations; } program->bind(); } { auto globalLight = _allocatedLights[_globalLights.front()]; if (locations->ambientSphere >= 0) { gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { sh = (*_skybox->getCubemap()->getIrradiance()); } for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) { program->setUniformValue(locations->ambientSphere + i, *(((QVector4D*) &sh) + i)); } } if (useSkyboxCubemap) { glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_CUBE_MAP, gpu::GLBackend::getTextureID(_skybox->getCubemap())); } if (locations->lightBufferUnit >= 0) { gpu::Batch batch; batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { gpu::Batch batch; batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); gpu::GLBackend::renderBatch(batch); } glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); } float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; _viewState->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); program->setUniformValue(locations->nearLocation, nearVal); float depthScale = (farVal - nearVal) / farVal; program->setUniformValue(locations->depthScale, depthScale); float nearScale = -1.0f / nearVal; float depthTexCoordScaleS = (right - left) * nearScale / sWidth; float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; program->setUniformValue(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); program->release(); if (useSkyboxCubemap) { glBindTexture(GL_TEXTURE_CUBE_MAP, 0); if (!shadowsEnabled) { glActiveTexture(GL_TEXTURE3); } } if (shadowsEnabled) { glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE3); } // additive blending glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_CULL_FACE); glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients); glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients); // enlarge the scales slightly to account for tesselation const float SCALE_EXPANSION = 0.05f; const glm::vec3& eyePoint = _viewState->getCurrentViewFrustum()->getPosition(); float nearRadius = glm::distance(eyePoint, _viewState->getCurrentViewFrustum()->getNearTopLeft()); auto geometryCache = DependencyManager::get<GeometryCache>(); if (!_pointLights.empty()) { _pointLight.bind(); _pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal); _pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); for (auto lightID : _pointLights) { auto light = _allocatedLights[lightID]; if (_pointLightLocations.lightBufferUnit >= 0) { gpu::Batch batch; batch.setUniformBuffer(_pointLightLocations.lightBufferUnit, light->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } glUniformMatrix4fv(_pointLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); glPushMatrix(); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); renderFullscreenQuad(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } else { glTranslatef(light->getPosition().x, light->getPosition().y, light->getPosition().z); geometryCache->renderSphere(expandedRadius, 32, 32, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); } glPopMatrix(); } _pointLights.clear(); _pointLight.release(); } if (!_spotLights.empty()) { _spotLight.bind(); _spotLight.setUniformValue(_spotLightLocations.nearLocation, nearVal); _spotLight.setUniformValue(_spotLightLocations.depthScale, depthScale); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); for (auto lightID : _spotLights) { auto light = _allocatedLights[lightID]; if (_spotLightLocations.lightBufferUnit >= 0) { gpu::Batch batch; batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } glUniformMatrix4fv(_spotLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); glPushMatrix(); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); float edgeRadius = expandedRadius / glm::cos(light->getSpotAngle()); if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < edgeRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); renderFullscreenQuad(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } else { glTranslatef(light->getPosition().x, light->getPosition().y, light->getPosition().z); glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light->getDirection()); glm::vec3 axis = glm::axis(spotRotation); glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z); glTranslatef(0.0f, 0.0f, -light->getMaximumRadius() * (1.0f + SCALE_EXPANSION * 0.5f)); geometryCache->renderCone(expandedRadius * glm::tan(light->getSpotAngle()), expandedRadius, 32, 1); } glPopMatrix(); } _spotLights.clear(); _spotLight.release(); } glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); // glDisable(GL_FRAMEBUFFER_SRGB); // End of the Lighting pass }
void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& data) { ProgramObject* programObject = getActivatedProgramWithTileData( _localRenderingShaderProvider.get(), _localProgramUniformHandler, chunk); if (programObject == nullptr) { return; } using namespace glm; const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); bool performAnyBlending = false; for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; ++i) { LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory)i; if (_tileProviderManager->getTileProviderGroup(i).levelBlendingEnabled && _tileProviderManager->getTileProviderGroup(category).getActiveTileProviders().size() > 0) { performAnyBlending = true; break; } } if (performAnyBlending) { float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius(); programObject->setUniform("distanceScaleFactor", distanceScaleFactor); programObject->setUniform("chunkLevel", chunk.index().level); } // Calculate other uniform variables needed for rendering dmat4 modelTransform = chunk.owner()->modelTransform(); dmat4 viewTransform = data.camera.combinedViewMatrix(); dmat4 modelViewTransform = viewTransform * modelTransform; std::vector<std::string> cornerNames = { "p01", "p11", "p00", "p10" }; std::vector<Vec3> cornersCameraSpace(4); for (int i = 0; i < 4; ++i) { Quad q = (Quad)i; Geodetic2 corner = chunk.surfacePatch().getCorner(q); Vec3 cornerModelSpace = ellipsoid.cartesianSurfacePosition(corner); Vec3 cornerCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(cornerModelSpace, 1)); cornersCameraSpace[i] = cornerCameraSpace; programObject->setUniform(cornerNames[i], vec3(cornerCameraSpace)); } vec3 patchNormalCameraSpace = normalize( cross(cornersCameraSpace[Quad::SOUTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST], cornersCameraSpace[Quad::NORTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST])); programObject->setUniform("patchNormalCameraSpace", patchNormalCameraSpace); programObject->setUniform("projectionTransform", data.camera.projectionMatrix()); if (_tileProviderManager->getTileProviderGroup( LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || _tileProviderManager->getTileProviderGroup( LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = (viewTransform * glm::dvec4(directionToSunWorldSpace, 0)); data.modelTransform.translation; programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace); } // OpenGL rendering settings glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // render _grid->geometry().drawUsingActiveProgram(); // disable shader programObject->deactivate(); }
void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations) { program.addShaderFromSourceCode(QGLShader::Vertex, (limited ? deferred_light_limited_vert : deferred_light_vert)); program.addShaderFromSourceCode(QGLShader::Fragment, fragSource); program.link(); program.bind(); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); program.setUniformValue("specularMap", 2); program.setUniformValue("depthMap", 3); program.setUniformValue("shadowMap", 4); program.setUniformValue("skyboxMap", 5); locations.shadowDistances = program.uniformLocation("shadowDistances"); locations.shadowScale = program.uniformLocation("shadowScale"); locations.nearLocation = program.uniformLocation("near"); locations.depthScale = program.uniformLocation("depthScale"); locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset"); locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); locations.radius = program.uniformLocation("radius"); locations.ambientSphere = program.uniformLocation("ambientSphere.L00"); locations.invViewMat = program.uniformLocation("invViewMat"); GLint loc = -1; #if (GPU_FEATURE_PROFILE == GPU_CORE) const GLint LIGHT_GPU_SLOT = 3; loc = glGetUniformBlockIndex(program.programId(), "lightBuffer"); if (loc >= 0) { glUniformBlockBinding(program.programId(), loc, LIGHT_GPU_SLOT); locations.lightBufferUnit = LIGHT_GPU_SLOT; } else { locations.lightBufferUnit = -1; } #else loc = program.uniformLocation("lightBuffer"); if (loc >= 0) { locations.lightBufferUnit = loc; } else { locations.lightBufferUnit = -1; } #endif #if (GPU_FEATURE_PROFILE == GPU_CORE) const GLint ATMOSPHERE_GPU_SLOT = 4; loc = glGetUniformBlockIndex(program.programId(), "atmosphereBufferUnit"); if (loc >= 0) { glUniformBlockBinding(program.programId(), loc, ATMOSPHERE_GPU_SLOT); locations.atmosphereBufferUnit = ATMOSPHERE_GPU_SLOT; } else { locations.atmosphereBufferUnit = -1; } #else loc = program.uniformLocation("atmosphereBufferUnit"); if (loc >= 0) { locations.atmosphereBufferUnit = loc; } else { locations.atmosphereBufferUnit = -1; } #endif program.release(); }
iShaderProgram::CacheLoadResult csShaderGLCGCommon::LoadFromCache ( iHierarchicalCache* cache, iBase* previous, iDocumentNode* node, csRef<iString>* failReason, csRef<iString>* tag, ProfileLimitsPair* cacheLimits) { if (!cache) return iShaderProgram::loadFail; csRef<iShaderProgramCG> prevCG (scfQueryInterfaceSafe<iShaderProgramCG> ( previous)); csRef<iStringArray> allCachedPrograms; if ((programType == progVP) && prevCG.IsValid()) { csShaderGLCGFP* prevFP = static_cast<csShaderGLCGFP*> ( (iShaderProgramCG*)prevCG); csString tagStr ("CG"); tagStr += prevFP->cacheLimits.ToString(); if (failReason) failReason->AttachNew ( new scfString ("paired cached programs not found")); allCachedPrograms.AttachNew (new scfStringArray); allCachedPrograms->Push (tagStr); } else allCachedPrograms = cache->GetSubItems ("/"); if (!allCachedPrograms.IsValid() || (allCachedPrograms->GetSize() == 0)) { if (failReason) failReason->AttachNew ( new scfString ("no cached programs found")); return iShaderProgram::loadFail; } if (!GetProgramNode (node)) return iShaderProgram::loadFail; csRef<iDataBuffer> programBuffer = GetProgramData(); CS::Utility::Checksum::MD5::Digest progHash = CS::Utility::Checksum::MD5::Encode ( programBuffer->GetData(), programBuffer->GetSize()); csArray<CachedShaderWrapper> cachedProgWrappers; for (size_t i = 0; i < allCachedPrograms->GetSize(); i++) { const char* tag = allCachedPrograms->Get (i); if ((tag[0] != 'C') || (tag[1] != 'G')) continue; CachedShaderWrapper wrapper; if (!wrapper.limits.FromString (tag+2)) continue; wrapper.name = tag; csString cachePath ("/"); cachePath.Append (tag); csRef<iDataBuffer> cacheBuf = cache->ReadCache (cachePath); if (!cacheBuf.IsValid()) continue; csRef<iFile> cacheFile; cacheFile.AttachNew (new csMemFile (cacheBuf, true)); wrapper.cacheFile = cacheFile; uint32 diskMagic; if (cacheFile->Read ((char*)&diskMagic, sizeof (diskMagic)) != sizeof (diskMagic)) continue; if (csLittleEndian::UInt32 (diskMagic) != cacheFileMagic) continue; CS::Utility::Checksum::MD5::Digest diskHash; if (cacheFile->Read ((char*)&diskHash, sizeof (diskHash)) != sizeof (diskHash)) continue; if (diskHash != progHash) continue; cachedProgWrappers.Push (wrapper); } if (cachedProgWrappers.GetSize() == 0) { if (failReason && !*failReason) failReason->AttachNew ( new scfString ("all cached programs failed to read")); return iShaderProgram::loadFail; } cachedProgWrappers.Sort (); ProfileLimits currentLimits ( (programType == progVP) ? shaderPlug->currentLimits.vp : shaderPlug->currentLimits.fp); bool strictMatch = (programType == progVP) ? shaderPlug->strictMatchVP : shaderPlug->strictMatchFP; const char* progTypeNode = 0; switch (programType) { case progVP: progTypeNode = "cgvp"; break; case progFP: progTypeNode = "cgfp"; break; } csString allReasons; bool oneReadCorrectly = false; ProfileLimits bestLimits ( CS::PluginCommon::ShaderProgramPluginGL::Other, CG_PROFILE_UNKNOWN); bool bestLimitsSet = false; for (size_t i = cachedProgWrappers.GetSize(); i-- > 0;) { const CachedShaderWrapper& wrapper = cachedProgWrappers[i]; const ProfileLimits& limits = (programType == progVP) ? wrapper.limits.vp : wrapper.limits.fp; if (!bestLimitsSet) { bestLimits = limits; bestLimitsSet = true; } if (strictMatch && (limits != currentLimits)) { allReasons += wrapper.name; allReasons += ": strict mismatch; "; continue; } bool profileSupported = (shaderPlug->ProfileNeedsRouting (limits.profile) && shaderPlug->IsRoutedProfileSupported (limits.profile)) || cgGLIsProfileSupported (limits.profile); if (!profileSupported) { allReasons += wrapper.name; allReasons += ": Profile unsupported; "; continue; } if ((limits.vendor != currentLimits.vendor) && (limits.vendor != CS::PluginCommon::ShaderProgramPluginGL::Other)) { allReasons += wrapper.name; allReasons += ": vendor mismatch; "; continue; } bool limitsSupported = currentLimits >= limits; if (!limitsSupported) { allReasons += wrapper.name; allReasons += ": Limits exceeded; "; continue; } iFile* cacheFile = wrapper.cacheFile; { uint32 diskState; if (cacheFile->Read ((char*)&diskState, sizeof (diskState)) != sizeof (diskState)) continue; if (csLittleEndian::UInt32 (diskState) != cpsValid) { oneReadCorrectly = true; continue; } } description = CS::PluginCommon::ShaderCacheHelper::ReadString (cacheFile); bool breakFail = false; csRef<iDocumentNode> cgNode = node->GetNode (progTypeNode); if (!cgNode.IsValid()) continue; csRef<iDocumentNodeIterator> nodes = cgNode->GetNodes(); while(nodes->HasNext() && !breakFail) { csRef<iDocumentNode> child = nodes->Next(); if(child->GetType() != CS_NODE_ELEMENT) continue; const char* value = child->GetValue (); csStringID id = xmltokens.Request (value); switch(id) { case XMLTOKEN_VARIABLEMAP: if (!ParseVmap (child)) breakFail = true; break; case XMLTOKEN_CLIP: if (!ParseClip (child)) breakFail = true; break; default: /* Ignore unknown nodes. Invalid nodes would have been caught by the first (not from cache) parsing */ break; } } if (breakFail) continue; csString objectCodeCachePathArc = CS::PluginCommon::ShaderCacheHelper::ReadString (cacheFile); if (objectCodeCachePathArc.IsEmpty()) continue; csString objectCodeCachePathItem = CS::PluginCommon::ShaderCacheHelper::ReadString (cacheFile); if (objectCodeCachePathItem.IsEmpty()) continue; ProgramObjectID progId (objectCodeCachePathArc, objectCodeCachePathItem); ProgramObject programObj; //if (!LoadObjectCodeFromCompileCache (limits, cache)) if (!shaderPlug->progCache.LoadObject (progId, programObj)) continue; oneReadCorrectly = true; if (program) { cgDestroyProgram (program); program = 0; } if (!programObj.IsValid()) continue; cgGetError(); // Clear error program = cgCreateProgram (shaderPlug->context, CG_OBJECT, programObj.GetObjectCode(), limits.profile, 0, 0); if (!program) continue; CGerror err = cgGetError(); if (err != CG_NO_ERROR) { const char* errStr = cgGetErrorString (err); shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "Cg error %s", errStr); continue; } programProfile = limits.profile; programPositionInvariant = programObj.GetFlags() & ProgramObject::flagPositionInvariant; unusedParams = programObj.GetUnusedParams(); ClipsToVmap(); GetParamsFromVmap(); bool doLoadToGL = !shaderPlug->ProfileNeedsRouting (programProfile); cgGetError(); // Clear error if (doLoadToGL) { cgGLLoadProgram (program); } else { cgCompileProgram (program); } shaderPlug->PrintAnyListing(); err = cgGetError(); if ((err != CG_NO_ERROR) || (doLoadToGL && !cgGLIsProgramLoaded (program))) { //if (shaderPlug->debugDump) //DoDebugDump(); const char* errStr = cgGetErrorString (err); shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "Cg error %s", errStr); if (shaderPlug->doVerbose && (((programType == progVP) && (programProfile >= CG_PROFILE_ARBVP1)) || ((programType == progFP) && (programProfile >= CG_PROFILE_ARBFP1)))) { const char* err = (char*)glGetString (GL_PROGRAM_ERROR_STRING_ARB); shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "OpenGL error string: %s", err); } shaderPlug->SetCompiledSource (0); continue; } GetPostCompileParamProps (); if (shaderPlug->debugDump) DoDebugDump(); tag->AttachNew (new scfString (wrapper.name)); if (cacheLimits != 0) *cacheLimits = wrapper.limits; bool loaded = !shaderPlug->ProfileNeedsRouting (programProfile) || LoadProgramWithPS1 (); if (loaded && (bestLimits < currentLimits)) { /* The best found program is worse than the current limits, so pretend that the shader program failed (instead just being 'invalid') - that will make xmlshader try to load the program from scratch, ie with current limits, which may just work. */ if (failReason) failReason->AttachNew (new scfString ("Provoking clean load with current limits")); return iShaderProgram::loadFail; } return loaded ? iShaderProgram::loadSuccessShaderValid : iShaderProgram::loadSuccessShaderInvalid; } if (oneReadCorrectly) { if (bestLimits < currentLimits) { /* The 'invalid' programs may compile with the current limits - so again, provoke clean load */ if (failReason) failReason->AttachNew (new scfString ("Provoking clean load with current limits")); return iShaderProgram::loadFail; } else return iShaderProgram::loadSuccessShaderInvalid; } else return iShaderProgram::loadFail; }
void CubeBlock::Render() { rc->PushModelView(); this->ApplyTransform(); if (!GLEW_ARB_shader_objects) { RenderFixed(); rc->PopModelView(); return; } ProgramObject *program = rc->GetCurProgram(); for (int i = 0; i < 6; i++) { if (!fRenderPickMode) { Color3f *c = GetSideColor(i); if (c == &borderDiffuse) program->Uniform("RenderBackSide", 1); program->Uniform("Mode", 0); program->Uniform("FrontMaterial.ambient", 1, Color3f(1).data); program->Uniform("FrontMaterial.diffuse", 1, c->data); program->Uniform("FrontMaterial.shininess", 70); rc->PushModelView(); rc->MultModelView(face_transform[i]); face->Draw(); rc->PopModelView(); if (c == &borderDiffuse) program->Uniform("RenderBackSide", 0); } else { int id = pickId | (1 << (i+10)); GLubyte r = id & 0xff; GLubyte g = id >> 8; program->Uniform("Mode", 2); program->Uniform("FrontMaterial.diffuse", r/255.0f, g/255.0f, 1/255.0f); rc->PushModelView(); rc->MultModelView(face_transform[i]); face_pickMode->Draw(); rc->PopModelView(); } } if (!fRenderPickMode) { program->Uniform("Mode", 1); program->Uniform("FrontMaterial.ambient", 1, borderAmbient.data); program->Uniform("FrontMaterial.diffuse", 1, borderDiffuse.data); if (fUseReducedModel) { program->Uniform("UseSpecularMap", 0); program->Uniform("FrontMaterial.shininess", 70); border_reduced->Draw(); } else { program->Uniform("UseSpecularMap", 1); program->Uniform("FrontMaterial.shininess", 200); border->Draw(); } } rc->PopModelView(); }