Prechádzať zdrojové kódy

Add repeat fit mode to image decorator (#493)

Daniel Mircea 2 rokov pred
rodič
commit
14a393a33b

+ 2 - 2
Backends/RmlUi_Renderer_GL2.cpp

@@ -297,8 +297,8 @@ bool RenderInterface_GL2::GenerateTexture(Rml::TextureHandle& texture_handle, co
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
 	texture_handle = (Rml::TextureHandle)texture_id;
 

+ 2 - 2
Backends/RmlUi_Renderer_GL3.cpp

@@ -731,8 +731,8 @@ bool RenderInterface_GL3::GenerateTexture(Rml::TextureHandle& texture_handle, co
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
 	texture_handle = (Rml::TextureHandle)texture_id;
 

BIN
Samples/assets/alien_small.tga


+ 11 - 0
Samples/basic/demo/data/demo.rml

@@ -199,6 +199,9 @@ p.title
 	border: 1dp #777;
 	font-effect: shadow( 1dp 1dp #333 );
 }
+.image-mode.repeat > div {
+	height: 120dp;
+}
 #decorators .image-mode > div > p
 {
 	margin: -2em 0 0 0;
@@ -223,6 +226,9 @@ p.title
 .fit-cover      { decorator: image( icon-invader cover      ); }
 .fit-scale-none { decorator: image( icon-invader scale-none ); }
 .fit-scale-down { decorator: image( icon-invader scale-down ); }
+.fit-repeat   { decorator: image( /assets/alien_small.tga repeat ); }
+.fit-repeat-x { decorator: image( /assets/alien_small.tga repeat-x ); }
+.fit-repeat-y { decorator: image( /assets/alien_small.tga repeat-y ); }
 .orientation-vertical   { decorator: image( icon-invader flip-vertical   scale-none ); }
 .orientation-horizontal { decorator: image( icon-invader flip-horizontal scale-none ); }
 .orientation-rotate     { decorator: image( icon-invader rotate-180      scale-none ); }
@@ -709,6 +715,11 @@ progress {
 			<div class="fit-scale-none"></div>
 			<div class="fit-scale-down"></div>
 		</div>
+		<div class="image-mode repeat">
+			<div class="fit-repeat"><p>repeat</p></div>
+			<div class="fit-repeat-x"><p>repeat-x</p></div>
+			<div class="fit-repeat-y"><p>repeat-y</p></div>
+		</div>
 		<h1>Image decorator alignment modes</h1>
 		<div class="image-mode">
 			<div class="align-default"><p style="font-style: italic;">default</p></div>

+ 18 - 0
Source/Core/DecoratorTiled.cpp

@@ -120,6 +120,7 @@ void DecoratorTiled::Tile::GenerateGeometry(Vector<Vertex>& vertices, Vector<int
 
 	Vector2f final_tile_dimensions;
 	bool offset_and_clip_tile = false;
+	Vector2f repeat_factor = Vector2f(1);
 
 	switch (fit_mode)
 	{
@@ -165,6 +166,20 @@ void DecoratorTiled::Tile::GenerateGeometry(Vector<Vertex>& vertices, Vector<int
 		offset_and_clip_tile = true;
 	}
 	break;
+	case REPEAT:
+		final_tile_dimensions = surface_dimensions;
+		repeat_factor = surface_dimensions / tile_dimensions;
+	break;
+	case REPEAT_X:
+		final_tile_dimensions = Vector2f(surface_dimensions.x, tile_dimensions.y);
+		repeat_factor.x = surface_dimensions.x / tile_dimensions.x;
+		offset_and_clip_tile = true;
+	break;
+	case REPEAT_Y:
+		final_tile_dimensions = Vector2f(tile_dimensions.x, surface_dimensions.y);
+		repeat_factor.y = surface_dimensions.y / tile_dimensions.y;
+		offset_and_clip_tile = true;
+	break;
 	}
 
 	Vector2f tile_offset(0, 0);
@@ -206,6 +221,9 @@ void DecoratorTiled::Tile::GenerateGeometry(Vector<Vertex>& vertices, Vector<int
 		}
 	}
 
+	scaled_texcoords[0] *= repeat_factor;
+	scaled_texcoords[1] *= repeat_factor;
+
 	// Resize the vertex and index arrays to fit the new geometry.
 	int index_offset = (int)vertices.size();
 	vertices.resize(vertices.size() + 4);

+ 3 - 0
Source/Core/DecoratorTiled.h

@@ -66,6 +66,9 @@ public:
 		COVER,      // Tile is stretched to cover the boundaries, keeping aspect ratio fixed.
 		SCALE_NONE, // Tile is never scaled.
 		SCALE_DOWN, // Tile acts like 'scale-none' if smaller than boundaries, or like 'contain' otherwise.
+		REPEAT,     // Tile is repeated on both x and y axis
+		REPEAT_X,   // Tile is repeated on the x axis
+		REPEAT_Y,   // Tile is repeated on the y axis
 	};
 
 	/**

+ 11 - 2
Source/Core/DecoratorTiledInstancer.cpp

@@ -48,7 +48,7 @@ void DecoratorTiledInstancer::RegisterTileProperty(const String& name, bool regi
 	if (register_fit_modes)
 	{
 		String fit_name = CreateString(32, "%s-fit", name.c_str());
-		ids.fit = RegisterProperty(fit_name, "fill").AddParser("keyword", "fill, contain, cover, scale-none, scale-down").GetId();
+		ids.fit = RegisterProperty(fit_name, "fill").AddParser("keyword", "fill, contain, cover, scale-none, scale-down, repeat, repeat-x, repeat-y").GetId();
 
 		String align_x_name = CreateString(32, "%s-align-x", name.c_str());
 		ids.align_x = RegisterProperty(align_x_name, "center").AddParser("keyword", "left, center, right").AddParser("length_percent").GetId();
@@ -99,8 +99,9 @@ bool DecoratorTiledInstancer::GetTileProperties(DecoratorTiled::Tile* tiles, Tex
 		DecoratorTiled::Tile& tile = tiles[i];
 		Texture& texture = textures[i];
 
+		const Sprite* sprite = instancer_interface.GetSprite(texture_name);
 		// A tile is always either a sprite or an image.
-		if (const Sprite* sprite = instancer_interface.GetSprite(texture_name))
+		if (sprite)
 		{
 			tile.position = sprite->rectangle.Position();
 			tile.size = sprite->rectangle.Size();
@@ -134,6 +135,14 @@ bool DecoratorTiledInstancer::GetTileProperties(DecoratorTiled::Tile* tiles, Tex
 			const Property& fit_property = *properties.GetProperty(ids.fit);
 			tile.fit_mode = (DecoratorTiled::TileFitMode)fit_property.value.Get<int>();
 
+			if (sprite && (tile.fit_mode == DecoratorTiled::TileFitMode::REPEAT ||
+				tile.fit_mode == DecoratorTiled::TileFitMode::REPEAT_X ||
+				tile.fit_mode == DecoratorTiled::TileFitMode::REPEAT_Y)) {
+				Log::Message(Log::LT_WARNING, "Decorator fit value is '%s', which is incompatible with a spritesheet",
+						fit_property.ToString().c_str());
+				return false;
+			}
+
 			const Property* align_properties[2] = {properties.GetProperty(ids.align_x), properties.GetProperty(ids.align_y)};
 
 			for (int dimension = 0; dimension < 2; dimension++)