Skip to content

Commit 267b9da

Browse files
author
bsherwood
committed
Thanks to a diagnosis by David Scherer, get rid of random pixels surrounding a label, by making sure the label texture is accurately positioned on a pixel location
1 parent 991aeed commit 267b9da

3 files changed

Lines changed: 49 additions & 23 deletions

File tree

‎src/core/label.cpp‎

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ label::gl_render( const view& scene)
323323
// Compute the positions of the text in the text box, and the height of the
324324
// text box. The text positions are relative to the lower left corner of
325325
// the text box.
326-
double box_height = border*2.0 + extents.y;
326+
double box_height = extents.y + 2.0*border;
327327

328328
vector text_pos( border, box_height - border);
329329

@@ -336,6 +336,24 @@ label::gl_render( const view& scene)
336336
lst = lst * translate;
337337
}
338338
vector origin = (lst * vertex(vector(), 1.0)).project();
339+
340+
// It is very important to make sure that the texture is positioned
341+
// accurately at a screen pixel location, to avoid artifacts around the texture.
342+
double kx = scene.view_width/2.0;
343+
double ky = scene.view_height/2.0;
344+
if (origin.x >= 0) {
345+
origin.x = ((int)(kx*origin.x+0.5))/kx;
346+
} else {
347+
origin.x = -((int)(-kx*origin.x+0.5))/kx;
348+
}
349+
if (origin.y >= 0) {
350+
origin.y = ((int)(ky*origin.y+0.5))/ky;
351+
} else {
352+
origin.y = -((int)(-ky*origin.y+0.5))/ky;
353+
}
354+
double halfwidth = (int)(0.5*box_width+0.5);
355+
double halfheight = (int)(0.5*box_height+0.5);
356+
339357
rgb stereo_linecolor = linecolor;
340358
if (scene.anaglyph)
341359
if (scene.coloranaglyph)
@@ -356,9 +374,8 @@ label::gl_render( const view& scene)
356374
identity.gl_load();
357375

358376
glTranslated( origin.x, origin.y, origin.z);
359-
glScaled( 2.0/scene.view_width, 2.0/scene.view_height, 1.0);
360-
// At this point, all furthur translations are in direction of label
361-
// space.
377+
glScaled( 1.0/kx, 1.0/ky, 1.0);
378+
// At this point, all further translations are in direction of label space.
362379
if (space && (xoffset || yoffset)) {
363380
// Move the origin away from the body.
364381
vector space_offset = vector(xoffset, yoffset).norm() * std::fabs(space);
@@ -375,45 +392,46 @@ label::gl_render( const view& scene)
375392
}
376393
if (std::fabs(xoffset) > std::fabs(yoffset)) {
377394
glTranslated(
378-
xoffset + ((xoffset > 0) ? 0 : -box_width),
379-
yoffset - box_height*0.5,
395+
xoffset + ((xoffset > 0) ? 0 : -2.0*halfwidth),
396+
yoffset - halfheight,
380397
0);
381398
}
382399
else {
383400
glTranslated(
384-
xoffset - box_width*0.5,
385-
yoffset + ((yoffset > 0) ? 0 : -box_height),
401+
xoffset - halfwidth,
402+
yoffset + ((yoffset > 0) ? 0 : -2.0*halfheight),
386403
0);
387404
}
388405
}
389406
else {
390-
glTranslated( -box_width*0.5, -box_height*0.5, 0.0);
407+
glTranslated( -halfwidth, -halfheight, 0.0);
391408
}
409+
392410
if (opacity) {
393411
// Occlude objects behind the label.
394412
rgba( background[0], background[1], background[2], opacity).gl_set();
395413
glBegin( GL_QUADS);
396414
vector().gl_render();
397-
vector( box_width, 0).gl_render();
398-
vector( box_width, box_height).gl_render();
399-
vector( 0, box_height).gl_render();
415+
vector( 2.0*halfwidth, 0).gl_render();
416+
vector( 2.0*halfwidth, 2.0*halfheight).gl_render();
417+
vector( 0, 2.0*halfheight).gl_render();
400418
glEnd();
401419
}
402420
if (box_enabled) {
403421
// Draw a box around the text.
404422
stereo_linecolor.gl_set(1.0f);
405423
glBegin( GL_LINE_LOOP);
406424
vector().gl_render();
407-
vector( box_width, 0).gl_render();
408-
vector( box_width, box_height).gl_render();
409-
vector( 0, box_height).gl_render();
425+
vector( 2.0*halfwidth, 0).gl_render();
426+
vector( 2.0*halfwidth, 2.0*halfheight).gl_render();
427+
vector( 0, 2.0*halfheight).gl_render();
410428
glEnd();
411429
}
412430

413431
// Render the text itself.
414432
color.gl_set(1.0f);
415433
text_layout->gl_render(scene, text_pos);
416-
} glMatrixMode( GL_MODELVIEW); } // Pops the matricies back off the stack
434+
} glMatrixMode( GL_MODELVIEW); } // Pops the matrices back off the stack
417435
list.gl_compile_end();
418436
check_gl_error();
419437
scene.screen_objects.insert( std::make_pair(pos, list));

‎src/core/text.cpp‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,7 @@ void layout_texture::set_image( int width, int height, int gl_internal_format, i
178178

179179
glTexImage2D( type, 0, gl_internal_format, tx_width, tx_height, 0, gl_format, gl_type, NULL );
180180
check_gl_error();
181-
glTexSubImage2D(type, 0,
182-
0, 0, width, height,
183-
gl_format, gl_type, data);
181+
glTexSubImage2D(type, 0, 0, 0, width, height, gl_format, gl_type, data);
184182
check_gl_error();
185183

186184
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
@@ -195,8 +193,6 @@ void layout_texture::set_image( int width, int height, int gl_internal_format, i
195193
coord[2] = vector(width, -height);
196194
coord[3] = vector(width, 0);
197195

198-
for(int i=0; i<4; i++) coord[i] -= vector(.001, .001); // mask artifacts when rendering origin is exactly at a pixel center
199-
200196
tcoord[0^bottom_up] = vector();
201197
tcoord[1^bottom_up] = vector(0, tc_y);
202198
tcoord[2^bottom_up] = vector(tc_x, tc_y);

‎src/win32/font_renderer.cpp‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ void font_renderer::gl_render_to_texture( const view&, const wstring& text, layo
104104
bmp = CreateDIBSection( dc, (BITMAPINFO*)&hdr, DIB_RGB_COLORS, &bits, NULL, 0 );
105105
if (!bmp) throw win32_exception("CreateDIBSection failed.");
106106

107-
int biPitch = (hdr.biWidth*3 + ((-hdr.biWidth*3)&3));
107+
int databytes = hdr.biWidth*3; // the actual BGR data
108+
int padbytes = (-hdr.biWidth*3)&3; // row is padded to have multiple of 4 bytes
109+
int biPitch = databytes + padbytes;
108110
memset(bits, 0, biPitch * hdr.biHeight);
109111

110112
SetTextColor(dc, 0xFFFFFF);
@@ -114,6 +116,16 @@ void font_renderer::gl_render_to_texture( const view&, const wstring& text, layo
114116
DrawTextW( dc, text.c_str(), text.size(), &rect, 0 );
115117
SelectObject(dc, prevBmp);
116118

119+
/*
120+
for (int row=0; row<hdr.biHeight; row++) {
121+
memset((char *)bits+(biPitch*row), 0xFF, 3); // Clear left edge of texture
122+
memset((char *)bits+(biPitch*(row+1)-3-padbytes), 0, 3); // Clear right edge of texture
123+
}
124+
*/
125+
126+
//memset((char *)bits, 0, biPitch); // Clear bottom edge of texture
127+
//memset((char *)bits+biPitch*(hdr.biHeight-1), 0, biPitch); // Clear top edge of texture
128+
117129
SelectObject(dc, prevFont);
118130
DeleteDC( dc ); dc = NULL;
119131

@@ -128,4 +140,4 @@ void font_renderer::gl_render_to_texture( const view&, const wstring& text, layo
128140
}
129141
}
130142

131-
} // namespace cvisual
143+
} // namespace cvisual

0 commit comments

Comments
 (0)