@@ -66,7 +66,10 @@ render(Rocket::Core::Context* context, CullTraverser *trav) {
6666// Description: Called internally to make a Geom from Rocket data.
6767// //////////////////////////////////////////////////////////////////
6868PT (Geom) RocketRenderInterface::
69- make_geom(Rocket::Core::Vertex* vertices, int num_vertices, int * indices, int num_indices, GeomEnums::UsageHint uh) {
69+ make_geom(Rocket::Core::Vertex* vertices,
70+ int num_vertices, int * indices, int num_indices,
71+ GeomEnums::UsageHint uh, const LVecBase2 &tex_scale) {
72+
7073 PT (GeomVertexData) vdata = new GeomVertexData (" " , GeomVertexFormat::get_v3c4t2 (), uh);
7174 vdata->unclean_set_num_rows (num_vertices);
7275 {
@@ -81,7 +84,8 @@ make_geom(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int nu
8184 vwriter.add_data3f (LVector3f::right () * vertex.position .x + LVector3f::up () * vertex.position .y );
8285 cwriter.add_data4i (vertex.colour .red , vertex.colour .green ,
8386 vertex.colour .blue , vertex.colour .alpha );
84- twriter.add_data2f (vertex.tex_coord .x , 1 .0f - vertex.tex_coord .y );
87+ twriter.add_data2f (vertex.tex_coord .x * tex_scale[0 ],
88+ (1 .0f - vertex.tex_coord .y ) * tex_scale[1 ]);
8589 }
8690 }
8791
@@ -140,12 +144,24 @@ render_geom(const Geom* geom, const RenderState* state, const Rocket::Core::Vect
140144// that the application does not wish to optimize.
141145// //////////////////////////////////////////////////////////////////
142146void RocketRenderInterface::
143- RenderGeometry (Rocket::Core::Vertex* vertices, int num_vertices, int * indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation) {
144- PT (Geom) geom = make_geom (vertices, num_vertices, indices, num_indices, GeomEnums::UH_stream);
147+ RenderGeometry (Rocket::Core::Vertex* vertices,
148+ int num_vertices, int * indices, int num_indices,
149+ Rocket::Core::TextureHandle thandle,
150+ const Rocket::Core::Vector2f& translation) {
151+
152+ Texture *texture = (Texture *)thandle;
153+
154+ LVecBase2 tex_scale (1 , 1 );
155+ if (texture != (Texture *)NULL ) {
156+ tex_scale = texture->get_tex_scale ();
157+ }
158+
159+ PT (Geom) geom = make_geom (vertices, num_vertices, indices, num_indices,
160+ GeomEnums::UH_stream, tex_scale);
145161
146162 CPT (RenderState) state;
147- if ((Texture*) texture != (Texture*) NULL ) {
148- state = RenderState::make (TextureAttrib::make ((Texture*) texture));
163+ if (texture != (Texture *) NULL ) {
164+ state = RenderState::make (TextureAttrib::make (texture));
149165 } else {
150166 state = RenderState::make_empty ();
151167 }
@@ -160,30 +176,40 @@ RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, i
160176// it believes will be static for the forseeable future.
161177// //////////////////////////////////////////////////////////////////
162178Rocket::Core::CompiledGeometryHandle RocketRenderInterface::
163- CompileGeometry (Rocket::Core::Vertex* vertices, int num_vertices, int * indices, int num_indices, Rocket::Core::TextureHandle texture) {
179+ CompileGeometry (Rocket::Core::Vertex* vertices,
180+ int num_vertices, int * indices, int num_indices,
181+ Rocket::Core::TextureHandle thandle) {
182+
183+ Texture *texture = (Texture *)thandle;
164184
165185 CompiledGeometry *c = new CompiledGeometry;
166- c->_geom = make_geom (vertices, num_vertices, indices, num_indices, GeomEnums::UH_static);
186+ LVecBase2 tex_scale (1 , 1 );
187+
188+ if (texture != (Texture *)NULL ) {
189+ rocket_cat.debug ()
190+ << " Compiling geom " << c->_geom << " with texture '"
191+ << texture->get_name () << " '\n " ;
192+
193+ tex_scale = texture->get_tex_scale ();
167194
168- if ((Texture*) texture != (Texture*) NULL ) {
169195 PT (TextureStage) stage = new TextureStage (" " );
170196 stage->set_mode (TextureStage::M_modulate);
171197
172198 CPT (TextureAttrib) attr = DCAST (TextureAttrib, TextureAttrib::make ());
173- attr = DCAST (TextureAttrib, attr->add_on_stage (stage, (Texture*) texture));
199+ attr = DCAST (TextureAttrib, attr->add_on_stage (stage, (Texture *) texture));
174200
175201 c->_state = RenderState::make (attr);
176202
177- rocket_cat.debug ()
178- << " Compiled geom " << c->_geom << " with texture '"
179- << ((Texture*) texture)->get_name () << " '\n " ;
180203 } else {
181- c->_state = RenderState::make_empty ();
182-
183204 rocket_cat.debug ()
184- << " Compiled geom " << c->_geom << " without texture\n " ;
205+ << " Compiling geom " << c->_geom << " without texture\n " ;
206+
207+ c->_state = RenderState::make_empty ();
185208 }
186209
210+ c->_geom = make_geom (vertices, num_vertices, indices, num_indices,
211+ GeomEnums::UH_static, tex_scale);
212+
187213 return (Rocket::Core::CompiledGeometryHandle) c;
188214}
189215
@@ -222,7 +248,16 @@ LoadTexture(Rocket::Core::TextureHandle& texture_handle,
222248 Rocket::Core::Vector2i& texture_dimensions,
223249 const Rocket::Core::String& source) {
224250
225- PT (Texture) tex = TexturePool::load_texture (Filename::from_os_specific (source.CString ()));
251+ // Prefer padding over scaling to avoid blurring people's pixel art.
252+ LoaderOptions options;
253+ if (Texture::get_textures_power_2 () == ATS_none) {
254+ options.set_auto_texture_scale (ATS_none);
255+ } else {
256+ options.set_auto_texture_scale (ATS_pad);
257+ }
258+
259+ Filename fn = Filename::from_os_specific (source.CString ());
260+ PT (Texture) tex = TexturePool::load_texture (fn, 0 , false , options);
226261 if (tex == NULL ) {
227262 texture_handle = 0 ;
228263 texture_dimensions.x = 0 ;
@@ -233,8 +268,12 @@ LoadTexture(Rocket::Core::TextureHandle& texture_handle,
233268 tex->set_minfilter (SamplerState::FT_nearest);
234269 tex->set_magfilter (SamplerState::FT_nearest);
235270
236- texture_dimensions.x = tex->get_x_size ();
237- texture_dimensions.y = tex->get_y_size ();
271+ // Since libRocket may make layout decisions based on the size of
272+ // the image, it's important that we give it the original size of
273+ // the image file in order to produce consistent results.
274+ texture_dimensions.x = tex->get_orig_file_x_size ();
275+ texture_dimensions.y = tex->get_orig_file_y_size ();
276+
238277 tex->ref ();
239278 texture_handle = (Rocket::Core::TextureHandle) tex.p ();
240279
@@ -255,18 +294,26 @@ GenerateTexture(Rocket::Core::TextureHandle& texture_handle,
255294 PT (Texture) tex = new Texture;
256295 tex->setup_2d_texture (source_dimensions.x , source_dimensions.y ,
257296 Texture::T_unsigned_byte, Texture::F_rgba);
297+
298+ // Pad to nearest power of two if necessary. It may not be necessary
299+ // as libRocket seems to give power-of-two sizes already, but can't hurt.
300+ tex->set_size_padded (source_dimensions.x , source_dimensions.y );
301+
258302 PTA_uchar image = tex->modify_ram_image ();
259303
260304 // Convert RGBA to BGRA
261- size_t row_size = source_dimensions.x * 4 ;
262- size_t y2 = image.size ();
263- for (size_t y = 0 ; y < image.size (); y += row_size) {
264- y2 -= row_size;
265- for (size_t i = 0 ; i < row_size; i += 4 ) {
266- image[y2 + i + 0 ] = source[y + i + 2 ];
267- image[y2 + i + 1 ] = source[y + i + 1 ];
268- image[y2 + i + 2 ] = source[y + i];
269- image[y2 + i + 3 ] = source[y + i + 3 ];
305+ size_t src_stride = source_dimensions.x * 4 ;
306+ size_t dst_stride = tex->get_x_size () * 4 ;
307+ const unsigned char *src_ptr = source + (src_stride * source_dimensions.y );
308+ unsigned char *dst_ptr = &image[0 ];
309+
310+ for (; src_ptr >= source; dst_ptr += dst_stride) {
311+ src_ptr -= src_stride;
312+ for (size_t i = 0 ; i < src_stride; i += 4 ) {
313+ dst_ptr[i + 0 ] = src_ptr[i + 2 ];
314+ dst_ptr[i + 1 ] = src_ptr[i + 1 ];
315+ dst_ptr[i + 2 ] = src_ptr[i];
316+ dst_ptr[i + 3 ] = src_ptr[i + 3 ];
270317 }
271318 }
272319
@@ -289,9 +336,9 @@ GenerateTexture(Rocket::Core::TextureHandle& texture_handle,
289336// //////////////////////////////////////////////////////////////////
290337void RocketRenderInterface::
291338ReleaseTexture (Rocket::Core::TextureHandle texture_handle) {
292- Texture* tex = (Texture*) texture_handle;
293- if (tex != (Texture*) NULL ) {
294- tex-> unref ( );
339+ Texture * tex = (Texture *) texture_handle;
340+ if (tex != (Texture *) NULL ) {
341+ unref_delete (tex );
295342 }
296343}
297344
0 commit comments