void histogram_impl::render(const int pWindowId, const int pX, const int pY, const int pVPW, const int pVPH, const glm::mat4& pView, const glm::mat4& pOrient) { CheckGL("Begin histogram_impl::render"); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); mProgram.bind(); glUniform1f(mYMaxIndex, mRange[3]); glUniform1f(mNBinsIndex, (GLfloat)mNBins); glUniformMatrix4fv(mMatIndex, 1, GL_FALSE, glm::value_ptr(pView)); glUniform1i(mPVCIndex, mIsPVCOn); glUniform1i(mPVAIndex, mIsPVAOn); glUniform4fv(mBColorIndex, 1, mColor); /* render a rectangle for each bin. Same * rectangle is scaled and translated accordingly * for each bin. OpenGL instanced rendering is used to do it.*/ histogram_impl::bindResources(pWindowId); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, mNBins); histogram_impl::unbindResources(); mProgram.unbind(); glDisable(GL_BLEND); glDepthMask(GL_TRUE); CheckGL("End histogram_impl::render"); }
AbstractChart::AbstractChart(int pLeftMargin, int pRightMargin, int pTopMargin, int pBottomMargin) : mTickCount(9), mTickSize(10), mLeftMargin(pLeftMargin), mRightMargin(pRightMargin), mTopMargin(pTopMargin), mBottomMargin(pBottomMargin), mXMax(1), mXMin(0), mYMax(1), mYMin(0), mZMax(1), mZMin(0), mXTitle("X-Axis"), mYTitle("Y-Axis"), mZTitle("Z-Axis"), mDecorVBO(-1), mBorderProgram(-1), mSpriteProgram(-1), mBorderAttribPointIndex(-1), mBorderUniformColorIndex(-1), mBorderUniformMatIndex(-1), mSpriteUniformMatIndex(-1), mSpriteUniformTickcolorIndex(-1), mSpriteUniformTickaxisIndex(-1) { CheckGL("Begin AbstractChart::AbstractChart"); /* load font Vera font for chart text * renderings, below function actually returns a constant * reference to font object used by Chart objects, we are * calling it here just to make sure required font glyphs * are loaded into the shared Font object */ getChartFont(); mBorderProgram = initShaders(gChartVertexShaderSrc, gChartFragmentShaderSrc); mSpriteProgram = initShaders(gChartVertexShaderSrc, gChartSpriteFragmentShaderSrc); mBorderAttribPointIndex = glGetAttribLocation (mBorderProgram, "point"); mBorderUniformColorIndex = glGetUniformLocation(mBorderProgram, "color"); mBorderUniformMatIndex = glGetUniformLocation(mBorderProgram, "transform"); mSpriteUniformTickcolorIndex = glGetUniformLocation(mSpriteProgram, "tick_color"); mSpriteUniformMatIndex = glGetUniformLocation(mSpriteProgram, "transform"); mSpriteUniformTickaxisIndex = glGetUniformLocation(mSpriteProgram, "isYAxis"); CheckGL("End AbstractChart::AbstractChart"); }
image_impl::~image_impl() { CheckGL("Begin image_impl::~image_impl"); glDeleteBuffers(1, &mPBO); glDeleteTextures(1, &mTex); glDeleteProgram(mProgram); CheckGL("End image_impl::~image_impl"); }
AbstractChart2D::~AbstractChart2D() { CheckGL("Begin Chart::~Chart"); glDeleteBuffers(1, &mDecorVBO); glDeleteProgram(mBorderProgram); glDeleteProgram(mSpriteProgram); CheckGL("End Chart::~Chart"); }
void image_impl::render(int pWindowId, int pX, int pY, int pViewPortWidth, int pViewPortHeight) { float xscale = 1.f; float yscale = 1.f; if (mKeepARatio) { if (mWidth > mHeight) { float trgtH = pViewPortWidth * float(mHeight)/float(mWidth); float trgtW = trgtH * float(mWidth)/float(mHeight); xscale = trgtW/pViewPortWidth; yscale = trgtH/pViewPortHeight; } else { float trgtW = pViewPortHeight * float(mWidth)/float(mHeight); float trgtH = trgtW * float(mHeight)/float(mWidth); xscale = trgtW/pViewPortWidth; yscale = trgtH/pViewPortHeight; } } glm::mat4 strans = glm::scale(glm::mat4(1.0f), glm::vec3(xscale, yscale, 1)); glUseProgram(mProgram); // get uniform locations int mat_loc = glGetUniformLocation(mProgram, "matrix"); int tex_loc = glGetUniformLocation(mProgram, "tex"); int chn_loc = glGetUniformLocation(mProgram, "isGrayScale"); int cml_loc = glGetUniformLocation(mProgram, "cmaplen"); int ubo_idx = glGetUniformBlockIndex(mProgram, "ColorMap"); glUniform1i(chn_loc, mFormat==1); // load texture from PBO glActiveTexture(GL_TEXTURE0); glUniform1i(tex_loc, 0); glBindTexture(GL_TEXTURE_2D, mTex); // bind PBO to load data into texture glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth, mHeight, mGLformat, mGLType, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glUniformMatrix4fv(mat_loc, 1, GL_FALSE, glm::value_ptr(strans)); glUniform1f(cml_loc, (GLfloat)mUBOSize); glBindBufferBase(GL_UNIFORM_BUFFER, 0, mColorMapUBO); glUniformBlockBinding(mProgram, ubo_idx, 0); CheckGL("Before render"); // Draw to screen bindResources(pWindowId); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); unbindResources(); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); // ubind the shader program glUseProgram(0); CheckGL("After render"); }
void copy_histogram(const Array<T> &data, const fg::Histogram* hist) { CheckGL("Begin copy_histogram"); glBindBuffer(GL_ARRAY_BUFFER, hist->vbo()); glBufferSubData(GL_ARRAY_BUFFER, 0, hist->size(), data.get()); glBindBuffer(GL_ARRAY_BUFFER, 0); CheckGL("End copy_histogram"); }
hist_impl::~hist_impl() { CheckGL("Begin hist_impl::~hist_impl"); for (auto it = mVAOMap.begin(); it!=mVAOMap.end(); ++it) { GLuint vao = it->second; glDeleteVertexArrays(1, &vao); } glDeleteBuffers(1, &mHistogramVBO); glDeleteProgram(mHistBarProgram); CheckGL("End hist_impl::~hist_impl"); }
AbstractChart::~AbstractChart() { CheckGL("Begin AbstractChart::~AbstractChart"); for (auto it = mVAOMap.begin(); it!=mVAOMap.end(); ++it) { GLuint vao = it->second; glDeleteVertexArrays(1, &vao); } glDeleteBuffers(1, &mDecorVBO); glDeleteProgram(mBorderProgram); glDeleteProgram(mSpriteProgram); CheckGL("End AbstractChart::~AbstractChart"); }
image_impl::image_impl(unsigned pWidth, unsigned pHeight, fg::ChannelFormat pFormat, fg::dtype pDataType) : mWidth(pWidth), mHeight(pHeight), mFormat(pFormat), mGLformat(gl_ctype(mFormat)), mGLiformat(gl_ictype(mFormat)), mDataType(pDataType), mGLType(gl_dtype(mDataType)) { CheckGL("Begin image_impl::image_impl"); // Initialize OpenGL Items glGenTextures(1, &(mTex)); glBindTexture(GL_TEXTURE_2D, mTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, mGLiformat, mWidth, mHeight, 0, mGLformat, mGLType, NULL); CheckGL("Before PBO Initialization"); glGenBuffers(1, &mPBO); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO); size_t typeSize = 0; switch(mGLType) { case GL_INT: typeSize = sizeof(int ); break; case GL_UNSIGNED_INT: typeSize = sizeof(unsigned int); break; case GL_SHORT: typeSize = sizeof(short ); break; case GL_UNSIGNED_SHORT: typeSize = sizeof(unsigned short); break; case GL_BYTE: typeSize = sizeof(char ); break; case GL_UNSIGNED_BYTE: typeSize = sizeof(unsigned char); break; default: typeSize = sizeof(float); break; } size_t formatSize = 0; switch(mFormat) { case fg::FG_GRAYSCALE: formatSize = 1; break; case fg::FG_RG: formatSize = 2; break; case fg::FG_RGB: formatSize = 3; break; case fg::FG_BGR: formatSize = 3; break; case fg::FG_RGBA: formatSize = 4; break; case fg::FG_BGRA: formatSize = 4; break; default: formatSize = 1; break; } mPBOsize = mWidth * mHeight * formatSize * typeSize; glBufferData(GL_PIXEL_UNPACK_BUFFER, mPBOsize, NULL, GL_STREAM_COPY); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); CheckGL("After PBO Initialization"); mProgram = initShaders(vertex_shader_code, fragment_shader_code); CheckGL("End image_impl::image_impl"); }
void image_impl::render(const void* pWnd, int pX, int pY, int pViewPortWidth, int pViewPortHeight) { static const float matrix[16] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; glUseProgram(mProgram); // get uniform locations int mat_loc = glGetUniformLocation(mProgram, "matrix"); int tex_loc = glGetUniformLocation(mProgram, "tex"); int chn_loc = glGetUniformLocation(mProgram, "isGrayScale"); int cml_loc = glGetUniformLocation(mProgram, "cmaplen"); int ubo_idx = glGetUniformBlockIndex(mProgram, "ColorMap"); glUniform1i(chn_loc, mFormat==1); // load texture from PBO glActiveTexture(GL_TEXTURE0); glUniform1i(tex_loc, 0); glBindTexture(GL_TEXTURE_2D, mTex); // bind PBO to load data into texture glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth, mHeight, mGLformat, mDataType, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glUniformMatrix4fv(mat_loc, 1, GL_FALSE, matrix); glUniform1f(cml_loc, (GLfloat)mUBOSize); glBindBufferBase(GL_UNIFORM_BUFFER, 0, mColorMapUBO); glUniformBlockBinding(mProgram, ubo_idx, 0); CheckGL("Before render"); // Draw to screen bindResources(pWnd); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); unbindResources(); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); // ubind the shader program glUseProgram(0); CheckGL("After render"); }
void EsDirector::init() { _vao.make_and_bind(); //~ glEnable(GL_DEPTH_TEST); CheckGL() glDepthFunc(GL_LESS); CheckGL() glEnable(GL_BLEND); CheckGL() glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); CheckGL() glEnable(GL_ALPHA_TEST); CheckGL() }
histogram_impl::histogram_impl(const uint pNBins, const forge::dtype pDataType) : mDataType(pDataType), mGLType(dtype2gl(mDataType)), mNBins(pNBins), mProgram(glsl::histogram_vs.c_str(), glsl::histogram_fs.c_str()), mYMaxIndex(-1), mNBinsIndex(-1), mMatIndex(-1), mPointIndex(-1), mFreqIndex(-1), mColorIndex(-1), mAlphaIndex(-1), mPVCIndex(-1), mPVAIndex(-1), mBColorIndex(-1) { CheckGL("Begin histogram_impl::histogram_impl"); setColor(0.8f, 0.6f, 0.0f, 1.0f); mYMaxIndex = mProgram.getUniformLocation("ymax" ); mNBinsIndex = mProgram.getUniformLocation("nbins" ); mMatIndex = mProgram.getUniformLocation("transform"); mPVCIndex = mProgram.getUniformLocation("isPVCOn" ); mPVAIndex = mProgram.getUniformLocation("isPVAOn" ); mBColorIndex = mProgram.getUniformLocation("barColor" ); mPointIndex = mProgram.getAttributeLocation("point"); mFreqIndex = mProgram.getAttributeLocation("freq" ); mColorIndex = mProgram.getAttributeLocation("color"); mAlphaIndex = mProgram.getAttributeLocation("alpha"); mVBOSize = mNBins; mCBOSize = 3*mVBOSize; mABOSize = mNBins; #define HIST_CREATE_BUFFERS(type) \ mVBO = createBuffer<type>(GL_ARRAY_BUFFER, mVBOSize, NULL, GL_DYNAMIC_DRAW); \ mCBO = createBuffer<float>(GL_ARRAY_BUFFER, mCBOSize, NULL, GL_DYNAMIC_DRAW); \ mABO = createBuffer<float>(GL_ARRAY_BUFFER, mABOSize, NULL, GL_DYNAMIC_DRAW); \ mVBOSize *= sizeof(type); \ mCBOSize *= sizeof(float); \ mABOSize *= sizeof(float); switch(mGLType) { case GL_FLOAT : HIST_CREATE_BUFFERS(float) ; break; case GL_INT : HIST_CREATE_BUFFERS(int) ; break; case GL_UNSIGNED_INT : HIST_CREATE_BUFFERS(uint) ; break; case GL_SHORT : HIST_CREATE_BUFFERS(short) ; break; case GL_UNSIGNED_SHORT : HIST_CREATE_BUFFERS(ushort); break; case GL_UNSIGNED_BYTE : HIST_CREATE_BUFFERS(float) ; break; default: TYPE_ERROR(1, mDataType); } #undef HIST_CREATE_BUFFERS CheckGL("End histogram_impl::histogram_impl"); }
hist_impl::hist_impl(unsigned pNBins, fg::dtype pDataType) : Chart2D(), mDataType(pDataType), mGLType(gl_dtype(mDataType)), mNBins(pNBins), mHistogramVBO(0), mHistogramVBOSize(0), mHistBarProgram(0), mHistBarMatIndex(0), mHistBarColorIndex(0), mHistBarYMaxIndex(0), mPointIndex(0), mFreqIndex(0) { CheckGL("Begin hist_impl::hist_impl"); mHistBarProgram = initShaders(gHistBarVertexShaderSrc, gHistBarFragmentShaderSrc); mPointIndex = glGetAttribLocation (mHistBarProgram, "point"); mFreqIndex = glGetAttribLocation (mHistBarProgram, "freq"); mHistBarColorIndex = glGetUniformLocation(mHistBarProgram, "barColor"); mHistBarMatIndex = glGetUniformLocation(mHistBarProgram, "transform"); mHistBarNBinsIndex = glGetUniformLocation(mHistBarProgram, "nbins"); mHistBarYMaxIndex = glGetUniformLocation(mHistBarProgram, "ymax"); switch(mGLType) { case GL_FLOAT: mHistogramVBO = createBuffer<float>(GL_ARRAY_BUFFER, mNBins, NULL, GL_DYNAMIC_DRAW); mHistogramVBOSize = mNBins*sizeof(float); break; case GL_INT: mHistogramVBO = createBuffer<int>(GL_ARRAY_BUFFER, mNBins, NULL, GL_DYNAMIC_DRAW); mHistogramVBOSize = mNBins*sizeof(int); break; case GL_UNSIGNED_INT: mHistogramVBO = createBuffer<unsigned>(GL_ARRAY_BUFFER, mNBins, NULL, GL_DYNAMIC_DRAW); mHistogramVBOSize = mNBins*sizeof(unsigned); break; case GL_SHORT: mHistogramVBO = createBuffer<short>(GL_ARRAY_BUFFER, mNBins, NULL, GL_DYNAMIC_DRAW); mHistogramVBOSize = mNBins*sizeof(short); break; case GL_UNSIGNED_SHORT: mHistogramVBO = createBuffer<unsigned short>(GL_ARRAY_BUFFER, mNBins, NULL, GL_DYNAMIC_DRAW); mHistogramVBOSize = mNBins*sizeof(unsigned short); break; case GL_UNSIGNED_BYTE: mHistogramVBO = createBuffer<unsigned char>(GL_ARRAY_BUFFER, mNBins, NULL, GL_DYNAMIC_DRAW); mHistogramVBOSize = mNBins*sizeof(unsigned char); break; default: fg::TypeError("Plot::Plot", __LINE__, 1, mDataType); } CheckGL("End hist_impl::hist_impl"); }
void hist_impl::render(const void* pWnd, int pX, int pY, int pVPW, int pVPH) { float w = float(pVPW - (leftMargin()+rightMargin()+tickSize())); float h = float(pVPH - (bottomMargin()+topMargin()+tickSize())); float offset_x = (2.0f * (leftMargin()+tickSize()) + (w - pVPW)) / pVPW; float offset_y = (2.0f * (bottomMargin()+tickSize()) + (h - pVPH)) / pVPH; float scale_x = w / pVPW; float scale_y = h / pVPH; CheckGL("Begin Histogram::render"); /* Enavle scissor test to discard anything drawn beyond viewport. * Set scissor rectangle to clip fragments outside of viewport */ glScissor(pX+leftMargin()+tickSize(), pY+bottomMargin()+tickSize(), pVPW - (leftMargin()+rightMargin()+tickSize()), pVPH - (bottomMargin()+topMargin()+tickSize())); glEnable(GL_SCISSOR_TEST); glm::mat4 trans = glm::translate(glm::scale(glm::mat4(1), glm::vec3(scale_x, scale_y, 1)), glm::vec3(offset_x, offset_y, 0)); glUseProgram(mHistBarProgram); glUniformMatrix4fv(mHistBarMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); glUniform4fv(mHistBarColorIndex, 1, mBarColor); glUniform1f(mHistBarNBinsIndex, (GLfloat)mNBins); glUniform1f(mHistBarYMaxIndex, ymax()); /* render a rectangle for each bin. Same * rectangle is scaled and translated accordingly * for each bin. This is done by OpenGL feature of * instanced rendering */ bindResources(pWnd); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, mNBins); unbindResources(); glUseProgram(0); /* Stop clipping */ glDisable(GL_SCISSOR_TEST); renderChart(pWnd, pX, pY, pVPW, pVPH); CheckGL("End Histogram::render"); }
void font_impl::loadFont(const char* const pFile, int pFontSize) { if (mIsFontLoaded) { if (pFile==mTTFfile) return; else { destroyGLResources(); mIsFontLoaded = false; } } mLoadedPixelSize = pFontSize; CheckGL("Begin Font::loadFont"); // Initialize freetype font library FT_Error bError = FT_Init_FreeType(&gFTLib); bError = FT_New_Face(gFTLib, pFile, 0, &gFTFace); if(bError) { FT_Done_FreeType(gFTLib); FT_THROW_ERROR("font face creation failed", fg::FG_ERR_FREETYPE_ERROR); } bError = FT_Set_Pixel_Sizes(gFTFace, 0, pFontSize); if (bError) { FT_Done_Face(gFTFace); FT_Done_FreeType(gFTLib); FT_THROW_ERROR("set font size failed", fg::FG_ERR_FREETYPE_ERROR); } // read font glyphs for only characters // from ' ' to '~' for (int i=START_CHAR; i<END_CHAR; ++i) extractGlyph(i); FT_Done_Face(gFTFace); FT_Done_FreeType(gFTLib); mVBO = createBuffer<float>(GL_ARRAY_BUFFER, mVertexData.size(), &(mVertexData.front()), GL_STATIC_DRAW); mIsFontLoaded = true; mTTFfile = pFile; CheckGL("End Font::loadFont"); }
void Chart3D::bindResources(int pWindowId) { CheckGL("Begin Chart3D::bindResources"); if (mVAOMap.find(pWindowId) == mVAOMap.end()) { GLuint vao = 0; /* create a vertex array object * with appropriate bindings */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(mBorderAttribPointIndex); glBindBuffer(GL_ARRAY_BUFFER, mDecorVBO); glVertexAttribPointer(mBorderAttribPointIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindVertexArray(0); /* store the vertex array object corresponding to * the window instance in the map */ mVAOMap[pWindowId] = vao; } glBindVertexArray(mVAOMap[pWindowId]); CheckGL("End Chart3D::bindResources"); }
image_impl::image_impl(unsigned pWidth, unsigned pHeight, fg::ColorMode pFormat, fg::FGType pDataType) : mWidth(pWidth), mHeight(pHeight), mFormat(pFormat), mDataType(FGTypeToGLenum(pDataType)) { CheckGL("Begin Image::Image"); mGLformat = FGModeToGLColor(mFormat); // Initialize OpenGL Items glGenTextures(1, &(mTex)); glBindTexture(GL_TEXTURE_2D, mTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, mGLformat, mWidth, mHeight, 0, mGLformat, mDataType, NULL); CheckGL("Before PBO Initialization"); glGenBuffers(1, &mPBO); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO); size_t typeSize = 0; switch(mDataType) { case GL_INT: typeSize = sizeof(int ); break; case GL_UNSIGNED_INT: typeSize = sizeof(unsigned int); break; case GL_BYTE: typeSize = sizeof(char ); break; case GL_UNSIGNED_BYTE: typeSize = sizeof(unsigned char); break; default: typeSize = sizeof(float); break; } mPBOsize = mWidth * mHeight * mFormat * typeSize; glBufferData(GL_PIXEL_UNPACK_BUFFER, mPBOsize, NULL, GL_STREAM_COPY); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); CheckGL("After PBO Initialization"); mProgram = initShaders(vertex_shader_code, fragment_shader_code); CheckGL("End Image::Image"); }
static void display () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); setProjection(); setViewPoint(); drawWorld(); /* Check everything OK and update screen */ CheckGL(); glutSwapBuffers(); }
void histogram_impl::bindResources(const int pWindowId) { if (mVAOMap.find(pWindowId) == mVAOMap.end()) { CheckGL("Begin histogram_impl::bindResources"); GLuint vao = 0; /* create a vertex array object * with appropriate bindings */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); // attach histogram bar vertices glEnableVertexAttribArray(mPointIndex); glBindBuffer(GL_ARRAY_BUFFER, screenQuadVBO(pWindowId)); glVertexAttribPointer(mPointIndex, 2, GL_FLOAT, GL_FALSE, 0, 0); // attach histogram frequencies glEnableVertexAttribArray(mFreqIndex); glBindBuffer(GL_ARRAY_BUFFER, mVBO); glVertexAttribPointer(mFreqIndex, 1, mGLType, GL_FALSE, 0, 0); glVertexAttribDivisor(mFreqIndex, 1); // attach histogram bar colors glEnableVertexAttribArray(mColorIndex); glBindBuffer(GL_ARRAY_BUFFER, mCBO); glVertexAttribPointer(mColorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribDivisor(mColorIndex, 1); // attach histogram bar alphas glEnableVertexAttribArray(mAlphaIndex); glBindBuffer(GL_ARRAY_BUFFER, mABO); glVertexAttribPointer(mAlphaIndex, 1, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribDivisor(mAlphaIndex, 1); glBindVertexArray(0); /* store the vertex array object corresponding to * the window instance in the map */ mVAOMap[pWindowId] = vao; CheckGL("End histogram_impl::bindResources"); } glBindVertexArray(mVAOMap[pWindowId]); }
static void initApp () { printf("initApp \n"); initGraphics(); initShaders(); /* Make sure we did everything right */ CheckGL(); chooseShader(0); Menu = glutCreateMenu(menuChoice); glutSetMenu(Menu); glutAddMenuEntry("Fragment shader", cmdToggleFragment); glutAddMenuEntry("Sphere", cmdSphere); glutAddMenuEntry("Teapot", cmdTeapot); glutAddMenuEntry("----", 0); glutAddMenuEntry("Exit", cmdExit); glutAttachMenu(GLUT_RIGHT_BUTTON); }
static void display () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glLoadIdentity(); gluLookAt(0, 2, 8, 0, 0, 0, 0, 1, 0); float red = 0.002; float green = 0.002; float blue = 0.2; glColor3f(red, green, blue); if (Teapot) glutWireTeapot(3); else gluSphere(QState, 3, 32, 8); glPopMatrix(); CheckGL(); glutSwapBuffers(); }
void Chart3D::renderChart(int pWindowId, int pX, int pY, int pVPW, int pVPH) { CheckGL("Being Chart3D::renderChart"); float w = float(pVPW - (mLeftMargin + mRightMargin + mTickSize)); float h = float(pVPH - (mTopMargin + mBottomMargin + mTickSize)); Chart3D::bindResources(pWindowId); /* bind the plotting shader program */ glUseProgram(mBorderProgram); /* set uniform attributes of shader * for drawing the plot borders */ glm::mat4 model = glm::rotate(glm::mat4(1.0f), -glm::radians(90.f), glm::vec3(0,1,0)) * glm::rotate(glm::mat4(1.0f), -glm::radians(90.f), glm::vec3(1,0,0)) * glm::scale(glm::mat4(1.f), glm::vec3(1.0f, 1.0f, 1.0f)); glm::mat4 view = glm::lookAt(glm::vec3(-1,0.5f,1.0f), glm::vec3(1,-1,-1),glm::vec3(0,1,0)); glm::mat4 projection = glm::ortho(-2.f, 2.f, -2.f, 2.f, -1.1f, 10.f); glm::mat4 mvp = projection * view * model; glm::mat4 trans = mvp; glUniformMatrix4fv(mBorderUniformMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); glUniform4fv(mBorderUniformColorIndex, 1, WHITE); /* Draw borders */ glDrawArrays(GL_LINES, 0, 6); /* reset shader program binding */ glUseProgram(0); /* bind the sprite shader program to * draw ticks on x and y axes */ glEnable(GL_PROGRAM_POINT_SIZE); glPointSize((GLfloat)mTickSize); glUseProgram(mSpriteProgram); glUniform4fv(mSpriteUniformTickcolorIndex, 1, WHITE); glUniformMatrix4fv(mSpriteUniformMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); /* Draw tick marks on z axis */ glUniform1i(mSpriteUniformTickaxisIndex, 1); glDrawArrays(GL_POINTS, 6, mTickCount); /* Draw tick marks on y axis */ glUniform1i(mSpriteUniformTickaxisIndex, 0); glDrawArrays(GL_POINTS, 6 + mTickCount, mTickCount); /* Draw tick marks on x axis */ glUniform1i(mSpriteUniformTickaxisIndex, 0); glDrawArrays(GL_POINTS, 6 + (2*mTickCount), mTickCount); glUseProgram(0); glPointSize(1); glDisable(GL_PROGRAM_POINT_SIZE); Chart3D::unbindResources(); renderTickLabels(pWindowId, w, h, mZText, trans, 0); renderTickLabels(pWindowId, w, h, mYText, trans, mTickCount); renderTickLabels(pWindowId, w, h, mXText, trans, 2*mTickCount); auto &fonter = getChartFont(); fonter->setOthro2D(int(w), int(h)); float pos[2]; /* render chart axes titles */ if (!mZTitle.empty()) { glm::vec4 res = trans * glm::vec4(-1.0f, -1.0f, 0.0f, 1.0f); pos[0] = w*(res.x/res.w+1.0f)/2.0f; pos[1] = h*(res.y/res.w+1.0f)/2.0f; pos[0] -= 6*(mTickSize * (w/pVPW)); pos[1] += mZTitle.length()/2 * CHART2D_FONT_SIZE; fonter->render(pWindowId, pos, WHITE, mZTitle.c_str(), CHART2D_FONT_SIZE, true); } if (!mYTitle.empty()) { glm::vec4 res = trans * glm::vec4(1.0f, 0.0f, -1.0f, 1.0f); pos[0] = w*(res.x/res.w+1.0f)/2.0f; pos[1] = h*(res.y/res.w+1.0f)/2.0f; pos[0] += 0.5 * ((mTickSize * (w/pVPW)) + mYTitle.length()/2 * CHART2D_FONT_SIZE); pos[1] -= 4*(mTickSize * (h/pVPH)); fonter->render(pWindowId, pos, WHITE, mYTitle.c_str(), CHART2D_FONT_SIZE); } if (!mXTitle.empty()) { glm::vec4 res = trans * glm::vec4(0.0f, -1.0f, -1.0f, 1.0f); pos[0] = w*(res.x/res.w+1.0f)/2.0f; pos[1] = h*(res.y/res.w+1.0f)/2.0f; pos[0] -= (mTickSize * (w/pVPW)) + mXTitle.length()/2 * CHART2D_FONT_SIZE; pos[1] -= 4*(mTickSize * (h/pVPH)); fonter->render(pWindowId, pos, WHITE, mXTitle.c_str(), CHART2D_FONT_SIZE); } CheckGL("End Chart3D::renderChart"); }
void font_impl::render(int pWindowId, const float pPos[], const float pColor[], const char* pText, int pFontSize, bool pIsVertical) { if(!mIsFontLoaded) { std::cerr<<"No font was loaded!, hence skipping text rendering."<<std::endl; return; } glDisable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(mProgram); GLuint pmat_loc = glGetUniformLocation(mProgram, "projectionMatrix"); GLuint mvmat_loc = glGetUniformLocation(mProgram, "modelViewMatrix"); GLuint tex_loc = glGetUniformLocation(mProgram, "tex"); GLuint col_loc = glGetUniformLocation(mProgram, "textColor"); glm::mat4 projMat = glm::ortho(0.0f, float(mWidth), 0.0f, float(mHeight)); glUniformMatrix4fv(pmat_loc, 1, GL_FALSE, (GLfloat*)&projMat); glUniform4fv(col_loc, 1, pColor); int loc_x = int(pPos[0]); int loc_y = int(pPos[1]); if(pFontSize == -1) pFontSize = mLoadedPixelSize; float scale_factor = float(pFontSize) / float(mLoadedPixelSize); bindResources(pWindowId); CheckGL("After Font::render bind resources"); glActiveTexture(GL_TEXTURE0); glUniform1i(tex_loc, 0); glBindSampler(0, mSampler); std::string str(pText); for (std::string::iterator it = str.begin(); it != str.end(); ++it) { char currChar = *it; if(currChar == '\n') { // if it is new line, move location to next line loc_x = int(pPos[0]); loc_y -= mNewLine * pFontSize / mLoadedPixelSize; } else if (currChar <= '~' && currChar >= ' ') { // regular characters are rendered as textured quad int idx = int(currChar) - START_CHAR; loc_x += mBearingX[idx] * pFontSize / mLoadedPixelSize; glBindTexture(GL_TEXTURE_2D, mCharTextures[idx]); /* rotate by 90 degress if we need * to render the characters vertically */ glm::mat4 modelView = glm::translate(glm::mat4(1.0f), glm::vec3(float(loc_x), float(loc_y), 0.0f)); modelView = glm::scale(modelView, glm::vec3(scale_factor)); glUniformMatrix4fv(mvmat_loc, 1, GL_FALSE, (GLfloat*)&modelView); // Draw letter glDrawArrays(GL_TRIANGLE_STRIP, idx*4, 4); loc_x += (mAdvX[idx] - mBearingX[idx]) * pFontSize / mLoadedPixelSize; } /* if the text needs to be rendered vertically, * move the pen cursor to next line after each * character render mandatorily */ if (pIsVertical) { loc_x = int(pPos[0]); loc_y -= mNewLine * pFontSize / mLoadedPixelSize; } } unbindResources(); glUseProgram(0); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); CheckGL("After Font::render "); }
void PrimitiveShader_PC::Flush() { if(buffer_.empty()) return; auto renderer = getRenderer(); Use(); CheckGL(); // Send our transformation to the currently bound shader, // in the "MVP" uniform auto const &pv = renderer->getCamera().getPV(); glEnable(GL_BLEND); if(hasTransform()){ //m[0][2],m[1][2] is always 0 auto const &m = getTransform(); auto pv2 = pv * Mat4(Vec4(m[0][0],m[0][1],0,m[0][2]), Vec4(m[1][0],m[1][1],0,m[1][2]), Vec4(0,0,1,0), Vec4(m[2][0],m[2][1],0,m[2][2])); glUniformMatrix4fv(pv_, 1, GL_FALSE, &pv2[0][0]); }else{ glUniformMatrix4fv(pv_, 1, GL_FALSE, &pv[0][0]); } CheckGL(); glBindBuffer(GL_ARRAY_BUFFER, vbo_); glBufferData(GL_ARRAY_BUFFER, sizeof(Point)*buffer_.size(), (const void*)&buffer_[0], GL_DYNAMIC_DRAW); CheckGL(); // 1rst attribute buffer : vertices glEnableVertexAttribArray(model_xy_); glVertexAttribPointer( model_xy_, // attribute. No particular reason for 0, but must match the layout in the shader. 2, // size GL_FLOAT, // type GL_FALSE, // normalized? sizeof(Point), // stride (void*)0 // array buffer offset ); CheckGL(); // 2nd attribute buffer : color glEnableVertexAttribArray(color_); glVertexAttribPointer( color_, 4, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)(2*sizeof(GLfloat)) ); CheckGL(); glEnable(GL_PROGRAM_POINT_SIZE); glDrawArrays((GLenum)drawMode_, 0, buffer_.size()); glDisable(GL_PROGRAM_POINT_SIZE); CheckGL(); glDisableVertexAttribArray(model_xy_); glDisableVertexAttribArray(color_); glDisable(GL_BLEND); Unuse(); buffer_.clear(); renderer->addRenderCall(); }
void Chart2D::renderChart(int pWindowId, int pX, int pY, int pVPW, int pVPH) { CheckGL("Begin Chart2D::renderChart"); float w = float(pVPW - (mLeftMargin + mRightMargin + mTickSize)); float h = float(pVPH - (mTopMargin + mBottomMargin + mTickSize)); float offset_x = (2.0f * (mLeftMargin+mTickSize) + (w - pVPW)) / pVPW; float offset_y = (2.0f * (mBottomMargin+mTickSize) + (h - pVPH)) / pVPH; float scale_x = w / pVPW; float scale_y = h / pVPH; Chart2D::bindResources(pWindowId); /* bind the plotting shader program */ glUseProgram(mBorderProgram); /* set uniform attributes of shader * for drawing the plot borders */ glm::mat4 trans = glm::translate(glm::scale(glm::mat4(1), glm::vec3(scale_x, scale_y, 1)), glm::vec3(offset_x, offset_y, 0)); glUniformMatrix4fv(mBorderUniformMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); glUniform4fv(mBorderUniformColorIndex, 1, WHITE); /* Draw borders */ glDrawArrays(GL_LINE_LOOP, 0, 4); /* reset shader program binding */ glUseProgram(0); /* bind the sprite shader program to * draw ticks on x and y axes */ glPointSize((GLfloat)mTickSize); glUseProgram(mSpriteProgram); glUniform4fv(mSpriteUniformTickcolorIndex, 1, WHITE); glUniformMatrix4fv(mSpriteUniformMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); /* Draw tick marks on y axis */ glUniform1i(mSpriteUniformTickaxisIndex, 1); glDrawArrays(GL_POINTS, 4, mTickCount); /* Draw tick marks on x axis */ glUniform1i(mSpriteUniformTickaxisIndex, 0); glDrawArrays(GL_POINTS, 4+mTickCount, mTickCount); glUseProgram(0); glPointSize(1); Chart2D::unbindResources(); renderTickLabels(pWindowId, int(w), int(h), mYText, trans, 0, false); renderTickLabels(pWindowId, int(w), int(h), mXText, trans, mTickCount, false); auto &fonter = getChartFont(); fonter->setOthro2D(int(w), int(h)); float pos[2]; /* render chart axes titles */ if (!mYTitle.empty()) { glm::vec4 res = trans * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[0] += (mTickSize * (w/pVPW)); fonter->render(pWindowId, pos, WHITE, mYTitle.c_str(), CHART2D_FONT_SIZE, true); } if (!mXTitle.empty()) { glm::vec4 res = trans * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[1] += (mTickSize * (h/pVPH)); fonter->render(pWindowId, pos, WHITE, mXTitle.c_str(), CHART2D_FONT_SIZE); } CheckGL("End Chart2D::renderChart"); }
void Chart3D::generateChartData() { CheckGL("Begin Chart3D::generateChartData"); static const float border[] = { -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1 }; static const int nValues = sizeof(border)/sizeof(float); std::vector<float> decorData; std::copy(border, border+nValues, std::back_inserter(decorData)); float step = 2.0f/(mTickCount); /* push tick points for z axis: * push (0,0) first followed by * [-1, 0) ticks and then * (0, 1] ticks */ pushPoint(decorData, -1.0f, -1.0f, 0.0f); pushTicktextCoords(-1.0f, -1.0f, 0.0f); mZText.push_back(toString(0)); int ticksLeft = mTickCount/2; for(int i=1; i<=ticksLeft; ++i) { /* (0, -1] to [-1, -1] */ float neg = i*-step; pushPoint(decorData, -1.0f, -1.0f, neg); /* push tick marks */ pushTicktextCoords(-1.0f, -1.0f, neg); /* push tick text label */ mZText.push_back(toString(neg)); /* (0, -1] to [1, -1] */ float pos = i*step; pushPoint(decorData, -1.0f, -1.0f, pos); /* push tick marks */ pushTicktextCoords(-1.0f, -1.0f, pos); /* push tick text label */ mZText.push_back(toString(pos)); } /* push tick points for y axis: * push (0,0) first followed by * [-1, 0) ticks and then * (0, 1] ticks */ pushPoint(decorData, 1.0f, 0.0f, -1.0f); pushTicktextCoords(1.0f, 0.0f, -1.0f); mYText.push_back(toString(0)); for(int i=1; i<=ticksLeft; ++i) { /* [-1, 0) to [-1, -1] */ float neg = i*-step; pushPoint(decorData, 1.0f, neg, -1.0f); pushTicktextCoords(1.0f, neg, -1.0f); mYText.push_back(toString(neg)); /* [-1, 0) to [-1, 1] */ float pos = i*step; pushPoint(decorData, 1.0f, pos, -1.0f); pushTicktextCoords(1.0f, pos, -1.0f); mYText.push_back(toString(pos)); } /* push tick points for x axis: * push (0,0) first followed by * [-1, 0) ticks and then * (0, 1] ticks */ pushPoint(decorData, 0.0f, -1.0f, -1.0f); pushTicktextCoords( 0.0f, -1.0f, -1.0f); mXText.push_back(toString(0)); for(int i=1; i<=ticksLeft; ++i) { /* (0, -1] to [-1, -1] */ float neg = i*-step; pushPoint(decorData, neg, -1.0f, -1.0f); pushTicktextCoords( neg, -1.0f, -1.0f); mXText.push_back(toString(neg)); /* [-1, 0) to [-1, 1] */ float pos = i*step; pushPoint(decorData, pos, -1.0f, -1.0f); pushTicktextCoords( pos, -1.0f, -1.0f); mXText.push_back(toString(pos)); } /* check if decoration VBO has been already used(case where * tick marks are being changed from default(21) */ if (mDecorVBO != 0) glDeleteBuffers(1, &mDecorVBO); /* create vbo that has the border and axis data */ mDecorVBO = createBuffer<float>(GL_ARRAY_BUFFER, decorData.size(), &(decorData.front()), GL_STATIC_DRAW); CheckGL("End Chart3D::generateChartData"); }
void AbstractChart2D::renderChart(const void* pWnd, int pX, int pY, int pVPW, int pVPH) { float w = float(pVPW - (mLeftMargin + mRightMargin + mTickSize)); float h = float(pVPH - (mTopMargin + mBottomMargin + mTickSize)); float offset_x = (1.9f * (mLeftMargin+mTickSize) + (w - pVPW)) / pVPW; float offset_y = (1.9f * (mBottomMargin+mTickSize) + (h - pVPH)) / pVPH; float scale_x = w / pVPW; float scale_y = h / pVPH; CheckGL("Begin Chart::render"); bindResources(pWnd); /* bind the plotting shader program */ glUseProgram(mBorderProgram); /* set uniform attributes of shader * for drawing the plot borders */ glm::mat4 trans = glm::scale(glm::translate(glm::mat4(1), glm::vec3(offset_x, offset_y, 0)), glm::vec3(scale_x, scale_y, 1)); glUniformMatrix4fv(mBorderMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); glUniform4fv(mBorderColorIndex, 1, WHITE); /* Draw borders */ glDrawArrays(GL_LINE_LOOP, 0, 4); /* reset shader program binding */ glUseProgram(0); /* bind the sprite shader program to * draw ticks on x and y axes */ glPointSize((GLfloat)mTickSize); glUseProgram(mSpriteProgram); glUniform4fv(mSpriteTickcolorIndex, 1, WHITE); glUniformMatrix4fv(mSpriteMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); /* Draw tick marks on y axis */ glUniform1i(mSpriteTickaxisIndex, 1); glDrawArrays(GL_POINTS, 4, mTickCount); /* Draw tick marks on x axis */ glUniform1i(mSpriteTickaxisIndex, 0); glDrawArrays(GL_POINTS, 4+mTickCount, mTickCount); glUseProgram(0); glPointSize(1); unbindResources(); auto &fonter = getChartFont(); fonter->setOthro2D(int(w), int(h)); float pos[2]; /* render tick marker texts for y axis */ for (StringIter it = mYText.begin(); it!=mYText.end(); ++it) { int idx = int(it - mYText.begin()); glm::vec4 res = trans * glm::vec4(mTickTextX[idx], mTickTextY[idx], 0, 1); /* convert text position from [-1,1] range to * [0, 1) range and then offset horizontally * to compensate for margins and ticksize */ pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[0] -= (pVPW-w)*0.60f; fonter->render(pWnd, pos, WHITE, it->c_str(), CHART2D_FONT_SIZE); } /* render tick marker texts for x axis */ for (StringIter it = mXText.begin(); it!=mXText.end(); ++it) { int idx = int(it - mXText.begin()); /* mTickCount offset is needed while reading point coordinates for * x axis tick marks */ glm::vec4 res = trans * glm::vec4(mTickTextX[idx+mTickCount], mTickTextY[idx+mTickCount], 0, 1); /* convert text position from [-1,1] range to * [0, 1) range and then offset vertically * to compensate for margins and ticksize */ pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[1] -= (pVPH-h)*0.34f; /* offset horizontally based on text size to align * text center with tick mark position */ pos[0] -= (CHART2D_FONT_SIZE*(it->length()-2)/2.0f); fonter->render(pWnd, pos, WHITE, it->c_str(), CHART2D_FONT_SIZE); } /* render chart axes titles */ if (!mYTitle.empty()) { glm::vec4 res = trans * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[0] -= (pVPW-w)*0.76; fonter->render(pWnd, pos, WHITE, mYTitle.c_str(), CHART2D_FONT_SIZE, true); } if (!mXTitle.empty()) { glm::vec4 res = trans * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[1] -= (pVPH-h)*0.66; fonter->render(pWnd, pos, WHITE, mXTitle.c_str(), CHART2D_FONT_SIZE); } CheckGL("End Chart::render"); }
void AbstractChart2D::renderChart(int pX, int pY, int pVPW, int pVPH) const { float w = float(pVPW - (mLeftMargin + mRightMargin + mTickSize)); float h = float(pVPH - (mTopMargin + mBottomMargin + mTickSize)); float offset_x = (2.0f * (mLeftMargin+mTickSize) + (w - pVPW)) / pVPW; float offset_y = (2.0f * (mBottomMargin+mTickSize) + (h - pVPH)) / pVPH; float scale_x = w / pVPW; float scale_y = h / pVPH; CheckGL("Begin Chart::render"); glEnableVertexAttribArray(mBorderPointIndex); glBindBuffer(GL_ARRAY_BUFFER, mDecorVBO); glVertexAttribPointer(mBorderPointIndex, 2, GL_FLOAT, GL_FALSE, 0, 0); /* bind the plotting shader program */ glUseProgram(mBorderProgram); /* set uniform attributes of shader * for drawing the plot borders */ glm::mat4 trans = glm::scale(glm::translate(glm::mat4(1), glm::vec3(offset_x, offset_y, 0)), glm::vec3(scale_x, scale_y, 1)); glUniformMatrix4fv(mBorderMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); glUniform4fv(mBorderColorIndex, 1, WHITE); /* Draw borders */ glDrawArrays(GL_LINE_LOOP, 0, 4); /* reset shader program binding */ glUseProgram(0); /* bind the sprite shader program to * draw ticks on x and y axes */ glPointSize((GLfloat)mTickSize); /* Following line is required for opengl compatibility profile */ glEnable(GL_POINT_SPRITE); glUseProgram(mSpriteProgram); glUniform4fv(mSpriteTickcolorIndex, 1, WHITE); glUniformMatrix4fv(mSpriteMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); /* Draw tick marks on y axis */ glUniform1i(mSpriteTickaxisIndex, 1); glDrawArrays(GL_POINTS, 4, mTickCount); /* Draw tick marks on x axis */ glUniform1i(mSpriteTickaxisIndex, 0); glDrawArrays(GL_POINTS, 4+mTickCount, mTickCount); glUseProgram(0); glPointSize(1); glDisableVertexAttribArray(mBorderPointIndex); glBindBuffer(GL_ARRAY_BUFFER, 0); /* Following line is required for opengl compatibility profile */ glDisable(GL_POINT_SPRITE); auto &fonter = getChartFont(); fonter.setOthro2D(int(w), int(h)); float pos[2]; /* render tick marker texts for y axis */ for (StringIter it = mYText.begin(); it!=mYText.end(); ++it) { int idx = int(it - mYText.begin()); glm::vec4 res = trans * glm::vec4(mTickTextX[idx], mTickTextY[idx], 0, 1); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[0] -= (pVPW-w)*0.50f; fonter.render(pos, WHITE, it->c_str(), 15); } /* render tick marker texts for x axis */ for (StringIter it = mXText.begin(); it!=mXText.end(); ++it) { int idx = int(it - mXText.begin()); /* mTickCount offset is needed while reading point coordinates for * x axis tick marks */ glm::vec4 res = trans * glm::vec4(mTickTextX[idx+mTickCount], mTickTextY[idx+mTickCount], 0, 1); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[1] -= (pVPH-h)*0.32f; fonter.render(pos, WHITE, it->c_str(), 15); } /* render chart axes titles */ if (!mYTitle.empty()) { glm::vec4 res = trans * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[0] -= (pVPW-w)*0.70f; fonter.render(pos, WHITE, mYTitle.c_str(), 15, true); } if (!mXTitle.empty()) { glm::vec4 res = trans * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f); pos[0] = w*(res.x+1.0f)/2.0f; pos[1] = h*(res.y+1.0f)/2.0f; pos[1] -= (pVPH-h)*0.70f; fonter.render(pos, WHITE, mXTitle.c_str(), 15); } CheckGL("End Chart::render"); }