Ifc::symbol implementation  |  <<  Home  >>


To display symbols it's first necessary to convert their internal representation into the form suitable for OpenGL.
      
☜    












Geometry Buffers:
Vertex Buffer (VB) stores point positions,
Index Buffer (IB) stores triples of VB indices that define triangles.


















This conversion is performed once on startup, when Draw::Ifc implementation is initialized.
init_font() function in draw_simple_ogl.cpp is intended to perform this task.
The function is currently empty and can be implemented like this: static void init_font() { Draw::Font* pFont = s_pFont; if (pFont != nullptr) { glGenBuffers(1, &s_fontVBO); glGenBuffers(1, &s_fontIBO); if (s_fontVBO && s_fontIBO) { glBindBuffer(GL_ARRAY_BUFFER, s_fontVBO); glBufferData(GL_ARRAY_BUFFER, pFont->numPnts * sizeof(xt_float2), pFont->pPnts, GL_STATIC_DRAW ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_fontIBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, pFont->numTris * 3 * sizeof(uint16_t), pFont->pTris, GL_STATIC_DRAW ); } } }
The entire set of symbol shapes is represented by Draw::Font structure.
When init_font() is called, the pointer to this data is already assigned to static variable s_pFont.
Font vertices are stored as pairs of floating-point (x, y) coordinates, represented by xt_float2 type.
Triangles stored as an array of uint16_t indices.
Overall Draw::Font structure is this: // needed for initalization pPnts -> vertex coordinates numPnts: how many vertices pTris -> triangles numTris: how many triagles // needed for drawing pSyms -> info about individual symbols
Working with a buffer in OpenGL starts with assigning a handle (also known as "name") to it.
This is done with a call to glGenBuffers. Ths function can assign several handles at once,
for simplicity this implementation uses separate calls for VB (stored in s_fontVBO) and IB (s_fontIBO).
Such named entities are commonly known as Buffer Objects, hence VBO for VB, IBO for IB.

To populate a buffer with data, it must first be activated at a particular binding point,
by calling glBindBuffer.
For VB the binding point is GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER for IB.
glBufferData is then used to transfer font geometry to GL-accessible memory.
GL_STATIC_DRAW specifies here that this data will be created once and then used
without modifications.


TODO: !! -> VS !!
symbol.vert attribute vec2 vtx_pos; uniform vec4 prm_xform; void main() { vec2 pos = vtx_pos; vec2 offs = prm_xform.xy; vec2 scl = prm_xform.zw; pos *= scl; pos += offs; gl_Position = vec4(pos.x, pos.y, 0.0, 1.0); }
TODO: !! Explain vtx_pos, prm_xform !!



draw_simple_ogl.cpp void symbol_impl(const Draw::Symbol* pSym) { Draw::Font* pFont = s_pFont; GPUProgram* pProg = &s_progSymbol; if (pFont != nullptr && pSym && pProg->is_valid()) { int sym = pSym->sym; Draw::Font::SymInfo* pInfo = &pFont->pSyms[sym]; /* set geometry buffers and vertex description */ glBindBuffer(GL_ARRAY_BUFFER, s_fontVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_fontIBO); pProg->enable_vertex_vec2("vtx_pos", sizeof(xt_float2), 0); /* set parameters */ float ox = pSym->ox*2.0f - 1.0f; float oy = pSym->oy*2.0f - 1.0f; float sx = pSym->sx*2.0f; float sy = pSym->sy*2.0f; pProg->set_vector("prm_xform", ox, oy, sx, sy); pProg->draw_triangles(pInfo->numTris, pInfo->idxOrg); pProg->disable_vertex_inputs(); } }


TODO: !! enable_vertex_*, set_vector !!

./run.sh -draw:simple_ogl


symbol.frag uniform vec4 prm_color; void main() { gl_FragColor = prm_color; }


draw_simple_ogl.cpp void symbol_impl(const Draw::Symbol* pSym) { Draw::Font* pFont = s_pFont; GPUProgram* pProg = &s_progSymbol; if (pFont != nullptr && pSym && pProg->is_valid()) { int sym = pSym->sym; Draw::Font::SymInfo* pInfo = &pFont->pSyms[sym]; /* set rendering options */ /* enable semi-transparency */ glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* backface culling, frontfacing triangles defined clockwise */ glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CW); /* disable depth-buffer */ glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); /* set geometry buffers and vertex description */ glBindBuffer(GL_ARRAY_BUFFER, s_fontVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_fontIBO); pProg->enable_vertex_vec2("vtx_pos", sizeof(xt_float2), 0); /* set parameters */ float ox = pSym->ox*2.0f - 1.0f; float oy = pSym->oy*2.0f - 1.0f; float sx = pSym->sx*2.0f; float sy = pSym->sy*2.0f; pProg->set_vector("prm_xform", ox, oy, sx, sy); pProg->set_color("prm_color", pSym->clr); pProg->draw_triangles(pInfo->numTris, pInfo->idxOrg); pProg->disable_vertex_inputs(); } }
./run.sh -draw:simple_ogl


Ifc::symbol implementation  |  <<  Home  >>