bool StGLUVCylinder::computeMesh() { clearRAM(); if(myNbRings == 0) { return false; } const int aNbVerts = (myNbRings + 1) * 2; myVertices.initArray(aNbVerts); myNormals .initArray(aNbVerts); myTCoords .initArray(aNbVerts); for(int aRingIter = 0; aRingIter <= myNbRings; ++aRingIter) { const GLfloat aPhi = float(aRingIter) * float(M_PI * 2.0) / float(myNbRings); const GLfloat aTexCrd = float(aRingIter) / float(myNbRings); myTCoords.changeValue(aRingIter * 2 + 0) = StGLVec2(aTexCrd, 0.0f); myTCoords.changeValue(aRingIter * 2 + 1) = StGLVec2(aTexCrd, 1.0f); const StGLVec3 aNorm(cosf(aPhi), 0.0f, sinf(aPhi)); myNormals.changeValue(aRingIter * 2 + 0) = aNorm; myNormals.changeValue(aRingIter * 2 + 1) = aNorm; myVertices.changeValue(aRingIter * 2 + 0) = myCenter + aNorm * myRadius - StGLVec3(0.0f, myHeight * 0.5f, 0.0f); myVertices.changeValue(aRingIter * 2 + 1) = myCenter + aNorm * myRadius + StGLVec3(0.0f, myHeight * 0.5f, 0.0f); } return true; }
void StGLRootWidget::getRectGl(const StRectI_t& theRectPx, StArray<StGLVec2>& theVertices, const size_t theFromId) const { StRectD_t aRectGl = getRectGl(theRectPx); theVertices[theFromId + 0] = StGLVec2(GLfloat(aRectGl.right()), GLfloat(aRectGl.top())); theVertices[theFromId + 1] = StGLVec2(GLfloat(aRectGl.right()), GLfloat(aRectGl.bottom())); theVertices[theFromId + 2] = StGLVec2(GLfloat(aRectGl.left()), GLfloat(aRectGl.top())); theVertices[theFromId + 3] = StGLVec2(GLfloat(aRectGl.left()), GLfloat(aRectGl.bottom())); }
void StGLStereoFrameBuffer::setVPDimensions(StGLContext& theCtx, const GLsizei theSizeX, const GLsizei theSizeY) { GLsizei aVPSizeX = stMin(theSizeX, getSizeX()); GLsizei aVPSizeY = stMin(theSizeY, getSizeY()); if(aVPSizeX != myViewPortX || aVPSizeY != myViewPortY) { GLfloat aDX = GLfloat(aVPSizeX) / GLfloat(getSizeX()); GLfloat aDY = GLfloat(aVPSizeY) / GLfloat(getSizeY()); StArray<StGLVec2> aTCoords(4); aTCoords[0] = StGLVec2(aDX, 0.0f); aTCoords[1] = StGLVec2(aDX, aDY); aTCoords[2] = StGLVec2(0.0f, 0.0f); aTCoords[3] = StGLVec2(0.0f, aDY); myTexCoordBuf.init(theCtx, aTCoords); myViewPortX = aVPSizeX; myViewPortY = aVPSizeY; } }
bool StGLStereoFrameBuffer::init(StGLContext& theCtx, const GLsizei theTextureSizeX, const GLsizei theTextureSizeY, const bool theNeedDepthBuffer) { // release current objects release(theCtx); if(theCtx.arbFbo == NULL) { return false; } // create the textures if(!StGLStereoTexture::initTrash(theCtx, theTextureSizeX, theTextureSizeY)) { release(theCtx); return false; } const GLuint aFboBakDraw = theCtx.stglFramebufferDraw(); const GLuint aFboBakRead = theCtx.stglFramebufferRead(); theCtx.stglBindFramebuffer(StGLFrameBuffer::NO_FRAMEBUFFER); const GLint aDepthFormat = theCtx.isGlGreaterEqual(3, 0) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16; if(theNeedDepthBuffer) { theCtx.arbFbo->glGenRenderbuffers(2, myGLDepthRBIds); theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::LEFT_TEXTURE]); theCtx.arbFbo->glRenderbufferStorage(GL_RENDERBUFFER, aDepthFormat, theTextureSizeX, theTextureSizeY); } // build FBOs theCtx.arbFbo->glGenFramebuffers(2, myGLFBufferIds); theCtx.stglBindFramebuffer(myGLFBufferIds[StGLStereoTexture::LEFT_TEXTURE]); // bind left texture to left FBO as color buffer theCtx.arbFbo->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, StGLStereoTexture::myTextures[StGLStereoTexture::LEFT_TEXTURE].getTextureId(), 0); if(theNeedDepthBuffer) { // bind left render buffer to left FBO as depth buffer theCtx.arbFbo->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::LEFT_TEXTURE]); } bool isOk = theCtx.arbFbo->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, StGLFrameBuffer::NO_RENDERBUFFER); if(!isOk) { release(theCtx); theCtx.stglBindFramebufferDraw(aFboBakDraw); theCtx.stglBindFramebufferRead(aFboBakRead); return false; } theCtx.stglBindFramebuffer(StGLFrameBuffer::NO_FRAMEBUFFER); if(theNeedDepthBuffer) { // create right RenderBuffer (will be used as depth buffer) theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::RIGHT_TEXTURE]); theCtx.arbFbo->glRenderbufferStorage(GL_RENDERBUFFER, aDepthFormat, theTextureSizeX, theTextureSizeY); } theCtx.stglBindFramebuffer(myGLFBufferIds[StGLStereoTexture::RIGHT_TEXTURE]); // bind right texture to rights FBO as color buffer theCtx.arbFbo->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, StGLStereoTexture::myTextures[StGLStereoTexture::RIGHT_TEXTURE].getTextureId(), 0); if(theNeedDepthBuffer) { // bind right render buffer to right FBO as depth buffer theCtx.arbFbo->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::RIGHT_TEXTURE]); } isOk = theCtx.arbFbo->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, StGLFrameBuffer::NO_RENDERBUFFER); theCtx.stglBindFramebufferDraw(aFboBakDraw); theCtx.stglBindFramebufferRead(aFboBakRead); if(!isOk) { release(theCtx); return false; } ST_DEBUG_LOG("OpenGL, created StFrameBuffer(WxH= " + getSizeX() + 'x' + getSizeY() + ')'); // create vertices buffers to draw simple textured quad StArray<StGLVec4> aQuad(4); aQuad[0] = StGLVec4( 1.0f, -1.0f, 0.0f, 1.0f); // top-right aQuad[1] = StGLVec4( 1.0f, 1.0f, 0.0f, 1.0f); // bottom-right aQuad[2] = StGLVec4(-1.0f, -1.0f, 0.0f, 1.0f); // top-left aQuad[3] = StGLVec4(-1.0f, 1.0f, 0.0f, 1.0f); // bottom-left myVerticesBuf.init(theCtx, aQuad); StArray<StGLVec2> aQuadTC(4); aQuadTC[0] = StGLVec2(1.0f, 0.0f); aQuadTC[1] = StGLVec2(1.0f, 1.0f); aQuadTC[2] = StGLVec2(0.0f, 0.0f); aQuadTC[3] = StGLVec2(0.0f, 1.0f); myTexCoordBuf.init(theCtx, aQuadTC); myViewPortX = theTextureSizeX; myViewPortY = theTextureSizeY; return true; }
void StGeometryTest::resizeGrid(const StRectI_t& winRectPx) { StGLContext& aCtx = getContext(); // grid size_t linesCountV = 16 + 1; size_t cellSizePx = 10; size_t linesCountH = 16 + 1; if(winRectPx.width() > winRectPx.height()) { cellSizePx = winRectPx.width() / (linesCountV - 1); linesCountH = (winRectPx.height() / cellSizePx) + 1; } else { cellSizePx = winRectPx.height() / (linesCountH - 1); linesCountV = (winRectPx.width() / cellSizePx) + 1; } myCellSize.x() = 2.0f * GLfloat(cellSizePx) / GLfloat(winRectPx.width()); myCellSize.y() = 2.0f * GLfloat(cellSizePx) / GLfloat(winRectPx.height()); size_t vertixesCount = (linesCountH + linesCountV) * 2; StArray<StGLVec4> vertArray(vertixesCount); // insert black gap to make quads StGLVec2 blackGap(GLfloat(winRectPx.width() - cellSizePx * (linesCountV - 1)) / GLfloat(winRectPx.width()), GLfloat(winRectPx.height() - cellSizePx * (linesCountH - 1)) / GLfloat(winRectPx.height())); StGLVec2 bottomLeft = StGLVec2(-1.0f) + blackGap; StGLVec2 fat = StGLVec2( 2.0f) - blackGap * 2.0f; // horizontal lines for(size_t lineId = 0; lineId < linesCountH; ++lineId) { GLfloat anY = bottomLeft.y() + fat.y() * (GLfloat(lineId) / GLfloat(linesCountH - 1)); vertArray[2 * lineId] = StGLVec4(-1.0f, anY, 0.0f, 1.0f); vertArray[2 * lineId + 1] = StGLVec4( 1.0f, anY, 0.0f, 1.0f); } // vertical lines for(size_t lineId = 0; lineId < linesCountV; ++lineId) { GLfloat anX = bottomLeft.x() + fat.x() * (GLfloat(lineId) / GLfloat(linesCountV - 1)); vertArray[2 * linesCountH + 2 * lineId] = StGLVec4(anX, -1.0f, 0.0f, 1.0f); vertArray[2 * linesCountH + 2 * lineId + 1] = StGLVec4(anX, 1.0f, 0.0f, 1.0f); } myGrid.changeVBO(ST_VBO_VERTEX)->init(aCtx, vertArray); // white color StArray<StGLVec4> lColorsArray(vertixesCount, StGLVec4(1.0f)); myGrid.changeVBO(ST_VBO_COLORS)->init(aCtx, lColorsArray); // bottom left circle myCircles[0].create(StGLVec3(bottomLeft + myCellSize), myCellSize.x(), myCellSize.y(), 64); // bottom right circle myCircles[1].create(StGLVec3(bottomLeft + myCellSize * StGLVec2(GLfloat(linesCountV - 2), 1.0f)), myCellSize.x(), myCellSize.y(), 64); // top left circle myCircles[2].create(StGLVec3(bottomLeft + myCellSize * StGLVec2(1.0f, GLfloat(linesCountH - 2))), myCellSize.x(), myCellSize.y(), 64); // top right circle myCircles[3].create(StGLVec3(bottomLeft + myCellSize * StGLVec2(GLfloat(linesCountV - 2), GLfloat(linesCountH - 2))), myCellSize.x(), myCellSize.y(), 64); // center circle GLfloat minSize = 0.5f * (((linesCountV < linesCountH) ? linesCountV : linesCountH) - 1); myCircles[4].create(StGLVec3(0.0f), myCellSize.x() * minSize, myCellSize.y() * minSize, 64); // white color for(size_t aCircleId = 0; aCircleId < 5; ++aCircleId) { myCircles[aCircleId].computeMesh(); myCircles[aCircleId].initColorsArray(StGLVec4(1.0f)); myCircles[aCircleId].initVBOs(aCtx); } }