Esempio n. 1
0
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);
}