Beispiel #1
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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();
}
Beispiel #5
0
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());
		}
	}
Beispiel #7
0
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;
}
Beispiel #8
0
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);
}
Beispiel #9
0
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);

}
Beispiel #10
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;
}
Beispiel #11
0
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);
}
Beispiel #12
0
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();
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
	}

}
Beispiel #15
0
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;
}
Beispiel #16
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;
}
Beispiel #20
0
// 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);
}
Beispiel #23
0
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();
}
Beispiel #24
0
    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
}
Beispiel #26
0
    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;
}
Beispiel #29
0
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();
}