void drawText(const string* text, float x, float y, const string* font_name, int font_size) { text = (string*)wstrdup(text); HDC hdc = CreateCompatibleDC(0); string* font_face = wstrdup(font_name); int font_height = -MulDiv(font_size, GetDeviceCaps(hdc, LOGPIXELSY), 72); HFONT hfont = CreateFontW(font_height, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, font_face); free(font_face); SelectObject(hdc, hfont); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(255, 0, 0)); RECT rect = { 0 }; DrawTextW(hdc, text, -1, &rect, DT_CALCRECT | DT_NOCLIP); int width = rect.right - rect.left + 2, height = rect.bottom - rect.top + 2; rect.left++; rect.top++; void* bitmap_data = calloc(width*height, sizeof(uint32_t)); for (int i = 3; i < width*height*4; i+= 4) *((uint8_t*)bitmap_data+i) = 0xff; HBITMAP hbitmap = CreateBitmap(width, height, 1, 32, bitmap_data); SelectObject(hdc, hbitmap); DrawTextW(hdc, text, -1, &rect, DT_TOP | DT_LEFT); DeleteObject(hfont); free(text); GetBitmapBits(hbitmap, width*height*4, bitmap_data); DeleteObject(hbitmap); DeleteDC(hdc); for (int i = 0; i < width*height*4; i += 4) { *((uint8_t*)bitmap_data+i+3) = *((uint8_t*)bitmap_data+i+2); *((uint8_t*)bitmap_data+i ) = 0x10; *((uint8_t*)bitmap_data+i+1) = 0x10; *((uint8_t*)bitmap_data+i+2) = 0x10; } textureT* tex = createTexture(); textureT* old_tex = useTexture(tex, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, bitmap_data); free(bitmap_data); triMeshT* text_quad = createQuad(2.0f, 2.0f); if (!text_shader) initTextShader(); shaderT* old_shader = useShader(text_shader); setShaderParam("ScreenSize", &(vec2) { (float)screenWidth(), (float)screenHeight() }); setShaderParam("TextRect" , &(vec4) { (float)x, (float)y, (float)width, (float)height }); GLint depth_mask; glGetIntegerv(GL_DEPTH_WRITEMASK, &depth_mask); GLboolean cull_face, depth_test; glGetBooleanv(GL_CULL_FACE, &cull_face); glGetBooleanv(GL_DEPTH_TEST, &depth_test); glDepthMask(GL_FALSE); glDisable (GL_CULL_FACE); glDisable (GL_DEPTH_TEST); drawMesh(text_quad); glDepthMask(depth_mask); if (cull_face) glEnable(GL_CULL_FACE); if (depth_test) glEnable(GL_DEPTH_TEST); useTexture (old_tex, 0); useShader (old_shader); freeTexture(tex); freeMesh (text_quad); }
void drawText(const std::string &s,double x,double y,double z,const float *modelview,const float *projection) { // init textures and shader (shaders are made the first time only; texture is built each time) int width,height; GLuint texId=toTexture(s,&width,&height); initTextShader(); // compute the square vertices GLint viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); float fwidth=2.0*width/viewport[2]; // width in NDC float fheight=2.0*height/viewport[3]; // height in NDC float posx=x; float posy=y; float posz=z; if (modelview) { // transform by modelview float posw=modelview[3]*x+modelview[7]*y+modelview[11]*z+modelview[15]; posx=(modelview[0]*x+modelview[4]*y+modelview[8]*z+modelview[12])/posw; posy=(modelview[1]*x+modelview[5]*y+modelview[9]*z+modelview[13])/posw; posz=(modelview[2]*x+modelview[6]*y+modelview[10]*z+modelview[14])/posw; } vector<float> vertex= {posx,posy+fheight,posz,0,0, posx,posy,posz,0,1, posx+fwidth,posy+fheight,posz,1,0, posx+fwidth,posy,posz,1,1 }; // vertex to gl : TODO : generate once (then SubBufferData) GLuint vbuffer; glGenVertexArrays(1,&_textVAO); glBindVertexArray(_textVAO); glGenBuffers(1,&vbuffer); glBindBuffer(GL_ARRAY_BUFFER,vbuffer); glBufferData(GL_ARRAY_BUFFER,vertex.size()*sizeof(float),vertex.data(),GL_STREAM_DRAW); // draw (uniform setup) glUseProgram(_textShaderP); glUniform1i(glGetUniformLocation(_textShaderP,"texture0"),0); if (projection) { glUniformMatrix4fv(glGetUniformLocation(_textShaderP,"projection"),1,GL_FALSE,projection); } else { float identity[]= {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}; glUniformMatrix4fv(glGetUniformLocation(_textShaderP,"projection"),1,GL_FALSE,identity); } // draw (attribute setup) glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,5*sizeof(GLfloat),NULL); glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,5*sizeof(GLfloat),(GLvoid *)(3*sizeof(GLfloat))); // draw glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDrawArrays(GL_TRIANGLE_STRIP,0,4); glDisable(GL_BLEND); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDeleteBuffers(1,&vbuffer); glUseProgram(0); glBindVertexArray(0); glDeleteTextures(1,&texId); glDeleteVertexArrays(1,&_textVAO); }