Ejemplo n.º 1
0
void Renderer::RemovePrimitive( const Primitive::Ptr& primitive ) {
	std::vector<Primitive::Ptr>::iterator iter( std::find( m_primitives.begin(), m_primitives.end(), primitive ) );

	if( iter != m_primitives.end() ) {
		m_primitives.erase( iter );
	}

	InvalidateVBO();
}
Ejemplo n.º 2
0
	void VertexBuffer::InnerDispose()
	{
		InvalidateVBO();

		vector<VertexAttribute> attribs = GetAttributes();
		for(unsigned int i = 0; i < attribs.size(); ++i)
			RemoveAttribute(attribs[i].name);

		SetNumVerts(0);
	}
Ejemplo n.º 3
0
	void VertexBuffer::BuildVBO()
	{
		GLDEBUG();

		vector<VertexAttribute> attribs = GetAttributes();
		int total_size = GetVertexSize();

		InvalidateVBO();					// just in case...

		// generate a vbo
		glGenBuffers(1, &vbo_id);
		glBindBuffer(GL_ARRAY_BUFFER, vbo_id);

		// set the total size (based on the value we computed earlier)
		glBufferData(GL_ARRAY_BUFFER, total_size * num_verts, NULL, GL_STATIC_DRAW);

		int offset = 0;
		for(unsigned int i = 0; i < attribs.size(); ++i)
		{
			VertexAttribute attrib = attribs[i];

			int attrib_size = 0;
			if(attrib.type == Float)
				attrib_size = sizeof(float) * attrib.n_per_vertex;

			if(attrib_size > 0)
			{
				if(attrib.type == Float)
					glBufferSubData(GL_ARRAY_BUFFER, offset * num_verts, attrib_size * num_verts, attribute_data[attrib.name].floats);

				offset += attrib_size;
			}
		}

		glBindBuffer(GL_ARRAY_BUFFER, 0);						// don't leave hardware vbo on

		GLDEBUG();
	}
Ejemplo n.º 4
0
void Renderer::AddPrimitive( const Primitive::Ptr& primitive ) {
	m_primitives.push_back( primitive );

	InvalidateVBO();
}
Ejemplo n.º 5
0
sf::Vector2f Renderer::LoadImage( const sf::Image& image, sf::Color background_color_hint, sf::Color foreground_color_hint, bool force_insert ) {
	const sf::Uint8* pixels_ptr = image.getPixelsPtr();

	if( !force_insert ) {
		std::map<const sf::Uint8*, sf::Vector2f>::iterator iter( m_atlas_offsets.find( pixels_ptr ) );

		if( iter != m_atlas_offsets.end() ) {
			return iter->second;
		}
	}

	sf::Image preblended_image;

	preblended_image.create( image.getWidth(), image.getHeight(), image.getPixelsPtr() );

	// If we get a proper background color hint and preblend is enabled,
	// precompute blended color with ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ).
	if( m_preblend ) {
		if( background_color_hint.a == 255 ) {
			float foreground_r_factor = 1.f;
			float foreground_g_factor = 1.f;
			float foreground_b_factor = 1.f;

			if( foreground_color_hint.a == 255 ) {
				foreground_r_factor = static_cast<float>( foreground_color_hint.r ) / 255.f;
				foreground_g_factor = static_cast<float>( foreground_color_hint.g ) / 255.f;
				foreground_b_factor = static_cast<float>( foreground_color_hint.b ) / 255.f;
			}

			std::size_t pixel_count = preblended_image.getWidth() * preblended_image.getHeight();

			sf::Uint8* bytes = new sf::Uint8[pixel_count * 4];

			memcpy( bytes, preblended_image.getPixelsPtr(), pixel_count * 4 );

			for( std::size_t index = 0; index < pixel_count; ++index ) {
				// Alpha
				float alpha = static_cast<float>( bytes[index * 4 + 3] ) / 255.f;

				// Red
				bytes[index * 4 + 0] = static_cast<sf::Uint8>( static_cast<float>( bytes[index * 4 + 0] ) * foreground_r_factor * alpha + static_cast<float>( background_color_hint.r ) * ( 1.f - alpha ) );

				// Green
				bytes[index * 4 + 1] = static_cast<sf::Uint8>( static_cast<float>( bytes[index * 4 + 1] ) * foreground_g_factor * alpha + static_cast<float>( background_color_hint.g ) * ( 1.f - alpha ) );

				// Blue
				bytes[index * 4 + 2] = static_cast<sf::Uint8>( static_cast<float>( bytes[index * 4 + 2] ) * foreground_b_factor * alpha + static_cast<float>( background_color_hint.b ) * ( 1.f - alpha ) );
			}

			preblended_image.create( preblended_image.getWidth(), preblended_image.getHeight(), bytes );

			delete[] bytes;
		}
		else {
			m_preblend = false;

#ifdef SFGUI_DEBUG
			std::cerr << "Detected alpha value " << static_cast<int>( background_color_hint.a ) << " in background color hint. Disabling preblend.\n";
#endif
		}
	}

	const sf::Uint8* bytes = preblended_image.getPixelsPtr();
	std::size_t byte_count = preblended_image.getWidth() * preblended_image.getHeight() * 4;

	// Disable this check for now.
	static sf::Uint8 alpha_threshold = 255;

	for ( ; byte_count; --byte_count ) {
		// Check if the image makes intentional use of the alpha channel.
		if( m_depth_clear_strategy && !( byte_count % 4 ) && ( bytes[ byte_count - 1 ] > alpha_threshold ) && ( bytes[ byte_count - 1 ] < 255 ) ) {
#ifdef SFGUI_DEBUG
			std::cerr << "Detected alpha value " << static_cast<int>( bytes[ byte_count - 1 ]  ) << " in texture, disabling depth test.\n";
#endif
			m_depth_clear_strategy = NO_DEPTH;
		}
	}

	// Image needs to be loaded into atlas.
	sf::Image old_image = m_texture_atlas.copyToImage();
	sf::Image new_image;

	// We insert padding between atlas elements to prevent
	// texture filtering from screwing up our images.
	// If 1 pixel isn't enough, increase.
	const static unsigned int padding = 1;

	new_image.create( std::max( old_image.getWidth(), preblended_image.getWidth() ), old_image.getHeight() + preblended_image.getHeight() + padding, sf::Color::White );
	new_image.copy( old_image, 0, 0 );

	new_image.copy( preblended_image, 0, old_image.getHeight() + padding );

	m_texture_atlas.loadFromImage( new_image );

	sf::Vector2f offset = sf::Vector2f( 0.f, static_cast<float>( old_image.getHeight() + padding ) );

	InvalidateVBO();

	if( !force_insert ) {
		m_atlas_offsets[pixels_ptr] = offset;
	}

	return offset;
}