c++ - The easiest way to draw strings in QGLWidget -
i'm creating qglwidget
subclass initializegl
. resizegl
, paintg
l. fine, can draw 2d graphivcs gluortho2d , 3d too. fine.
now need draw text, no text rotation, no text deformations, no particular fonts. first trial glut engine program kept on crashing thought qglwidget glut not work in context.
i've tried qpainter
, remember use end()
method , swapbuffers
too, but.. nothing, text rendered opengl stuff no..
what easiest way draw text on qglwidget?
i first rendering text qimage contents copy texture using gltexsubimage2d. draw textured quad.
code actual project
void displaytext(qstring const &text, bool render_text) { if(!text_texture) { glgentextures(1, &text_texture); } glactivetexture(gl_texture0); gltprintmultierror("glactivetexture"); glbindtexture(gl_texture_2d, text_texture); gltprintmultierror("glbindtexture"); int tex_width, tex_height; glgettexlevelparameteriv(gl_texture_2d, 0, gl_texture_width, &tex_width); gltprintmultierror("glgettexlevelparameteriv gl_texture_width"); glgettexlevelparameteriv(gl_texture_2d, 0, gl_texture_height, &tex_height); gltprintmultierror("glgettexlevelparameter gl_texture_height"); if(tex_width != text_width || tex_height != text_height ) { render_text = true; tex_width = text_width; tex_height = text_height; glteximage2d( gl_texture_2d, 0, gl_rgb8, tex_width, tex_height, 0, gl_rgb, gl_unsigned_byte, null); gltprintmultierror("glteximage2d"); 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); } if(render_text) { qimage textimg(tex_width, tex_height, qimage::format_rgb888); { qpainter painter(&textimg); painter.fillrect(0, 0, tex_width, tex_height, qcolor(0,0,0)); painter.setbrush(qcolor(255, 255, 255)); painter.setpen(qcolor(255, 255, 255)); painter.setfont(qfont("sans", 15)); painter.drawtext(5, 20, text); } glpixelstorei(gl_unpack_swap_bytes, gl_false); glpixelstorei(gl_unpack_lsb_first, gl_false); glpixelstorei(gl_unpack_row_length, 0); glpixelstorei(gl_unpack_image_height, 0); glpixelstorei(gl_unpack_skip_rows, 0); glpixelstorei(gl_unpack_skip_pixels, 0); glpixelstorei(gl_unpack_skip_images, 0); glpixelstorei(gl_unpack_alignment, 4); gltexsubimage2d( gl_texture_2d, 0, 0, 0, tex_width, tex_height, gl_rgb, gl_unsigned_byte, textimg.constbits() ); } static glfloat const pos[] = { 0, 1, 1, 1, 1, 0, 0, 0 }; static glfloat const tex[] = { 0, 0, 1, 0, 1, 1, 0, 1 }; gluseprogram(frame2d.program); /* frame2d program consisting of following vertex , fragment shaders: // vertex shader #version 330 in vec2 position; in vec2 texcoord; out vec2 vert_tex; void main() { vert_tex = texcoord; gl_position = vec4(position*2 - 1., 0, 1); } // fragment shader #version 330 uniform sampler2d frame; in vec2 vert_tex; void main() { gl_fragcolor = texture(frame, vert_tex); } */ glenablevertexattribarray(frame2d.attrib_position); glenablevertexattribarray(frame2d.attrib_texcoord); glvertexattribpointer(frame2d.attrib_position, 2, gl_float, gl_false, 0, pos); gltprintmultierror("glvertexattribpointer(attrib_position, ...)"); glvertexattribpointer(frame2d.attrib_texcoord, 2, gl_float, gl_false, 0, tex); gltprintmultierror("glvertexattribpointer(attrib_texcoord, ...)"); gluniform1i(frame2d.uniform_sampler_frame, 0); gltprintmultierror("gluniform1i(frame2d.uniform_sampler_frame)"); glenable(gl_blend); glblendfunc(gl_src_color, gl_one_minus_src_color); glviewport(0, 0, tex_width, tex_height); gldisable(gl_depth_test); gldepthmask(0); glcolormask(1,1,1,1); gldrawarrays(gl_quads, 0, 4); gldisablevertexattribarray(frame2d.attrib_position); gldisablevertexattribarray(frame2d.attrib_texcoord); gluseprogram(0); glbindtexture(gl_texture_2d, 0); }
Comments
Post a Comment