void SceneNode::RenderShadowVolumes( const Affine3f & parentTransform ) { const Affine3f worldTransform = parentTransform * m_Transform; glLoadMatrixf( worldTransform.data() ); foreach( MeshInstance & instance, m_MeshInstances ) instance.RenderShadowVolumes(); foreach( SceneNode & child, m_ChildNodes ) child.RenderShadowVolumes( worldTransform ); }
void PhongShadowProgram::setTransformMatrices(const Affine3& viewMatrix, const Affine3& modelMatrix, const Matrix4& PV) { const Affine3f VM = (viewMatrix * modelMatrix).cast<float>(); const Matrix3f N = VM.linear(); const Matrix4f PVM = (PV * modelMatrix.matrix()).cast<float>(); if(useUniformBlockToPassTransformationMatrices){ transformBlockBuffer.write(modelViewMatrixIndex, VM); transformBlockBuffer.write(normalMatrixIndex, N); transformBlockBuffer.write(MVPIndex, PVM); transformBlockBuffer.flush(); } else { glUniformMatrix4fv(modelViewMatrixLocation, 1, GL_FALSE, VM.data()); glUniformMatrix3fv(normalMatrixLocation, 1, GL_FALSE, N.data()); glUniformMatrix4fv(MVPLocation, 1, GL_FALSE, PVM.data()); for(int i=0; i < numShadows_; ++i){ ShadowInfo& shadow = shadowInfos[i]; const Matrix4f BPVM = (shadow.BPV * modelMatrix.matrix()).cast<float>(); glUniformMatrix4fv(shadow.shadowMatrixLocation, 1, GL_FALSE, BPVM.data()); } } }
void TextRenderer::draw(Matrix4f perspectiveMatrix, Matrix4f viewingMatrix, float zNear, float zFar, bool mode2D) { std::lock_guard<std::mutex> lock(mMutex); if(!mode2D) throw Exception("TextRender is only implemented for 2D at the moment"); if(mView == nullptr) throw Exception("TextRenderer need access to the view"); for(auto it : mDataToRender) { Text::pointer input = std::static_pointer_cast<Text>(it.second); uint inputNr = it.first; // Check if a texture has already been created for this text if (mTexturesToRender.count(inputNr) > 0 && mTextUsed[inputNr] == input) continue; // If it has already been created, skip it if (mTexturesToRender.count(inputNr) > 0) { // Delete old texture glDeleteTextures(1, &mTexturesToRender[inputNr]); mTexturesToRender.erase(inputNr); glDeleteVertexArrays(1, &mVAO[inputNr]); mVAO.erase(inputNr); } Text::access access = input->getAccess(ACCESS_READ); std::string text = access->getData(); // Font setup QColor color(mColor.getRedValue() * 255, mColor.getGreenValue() * 255, mColor.getBlueValue() * 255, 255); QFont font = QApplication::font(); font.setPointSize(mFontSize); if (mStyle == STYLE_BOLD) { font.setBold(true); } else if (mStyle == STYLE_ITALIC) { font.setItalic(true); } QFontMetrics metrics(font); const int width = metrics.boundingRect(QString(text.c_str())).width() + 10; const int height = mFontSize + 5; // create the QImage and draw txt into it QImage textimg(width, height, QImage::Format_RGBA8888); textimg.fill(QColor(0, 0, 0, 0)); { // Draw the text to the image QPainter painter(&textimg); painter.setBrush(color); painter.setPen(color); painter.setFont(font); painter.drawText(0, mFontSize, text.c_str()); } // Make texture of QImage GLuint textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textimg.width(), textimg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, textimg.bits()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Draw texture on a quad // Delete old VAO if(mVAO.count(inputNr) > 0) glDeleteVertexArrays(1, &mVAO[inputNr]); GLuint VAO_ID; glGenVertexArrays(1, &VAO_ID); mVAO[inputNr] = VAO_ID; glBindVertexArray(VAO_ID); float vertices[] = { // vertex: x, y, z; tex coordinates: x, y 0.0f, (float)height, 0.0f, 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f, 0.0f, (float)width, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; // Delete old VBO if(mVBO.count(inputNr) > 0) glDeleteBuffers(1, &mVBO[inputNr]); // Create VBO uint VBO; glGenBuffers(1, &VBO); mVBO[inputNr] = VBO; glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *) 0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *) (3 * sizeof(float))); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Delete old EBO if(mEBO.count(inputNr) > 0) glDeleteBuffers(1, &mEBO[inputNr]); // Create EBO uint EBO; glGenBuffers(1, &EBO); mEBO[inputNr] = EBO; uint indices[] = { // note that we start from 0! 0, 1, 3, // first triangle 1, 2, 3 // second triangle }; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glBindVertexArray(0); mTexturesToRender[inputNr] = textureID; mTextUsed[inputNr] = input; } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); activateShader(); for(auto it : mDataToRender) { const uint inputNr = it.first; Affine3f transform = Affine3f::Identity(); // Get width and height of texture glBindTexture(GL_TEXTURE_2D, mTexturesToRender[inputNr]); int width, height; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); const float scale = 1.0f / mView->width(); const float scale2 = 1.0f / mView->height(); const int padding = 15; Vector3f position; switch(mPosition) { case POSITION_CENTER: position = Vector3f(-width*scale/2.0f, -height*scale2/2.0f, 0); // Center break; case POSITION_TOP_CENTER: position = Vector3f(-width*scale/2.0f, 1 - (height + padding)*scale2, 0); // Top center break; case POSITION_BOTTOM_CENTER: position = Vector3f(-width*scale/2.0f, -1 + padding*scale2, 0); // Bottom center break; case POSITION_TOP_LEFT: position = Vector3f(-1 + padding*scale, 1 - (height + padding)*scale2, 0); // Top left corner break; case POSITION_TOP_RIGHT: position = Vector3f(1 - (width + padding)*scale, 1 - (height + padding)*scale2, 0); // Top right corner break; case POSITION_BOTTOM_LEFT: position = Vector3f(-1 + padding*scale, -1 + padding*scale2, 0); // Bottom left corner break; case POSITION_BOTTOM_RIGHT: position = Vector3f(1 - (width + padding)*scale, -1 + padding*scale2, 0); // Bottom right corner break; } transform.translate(position); transform.scale(Vector3f(scale, scale2, 0)); uint transformLoc = glGetUniformLocation(getShaderProgram(), "transform"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, transform.data()); transformLoc = glGetUniformLocation(getShaderProgram(), "perspectiveTransform"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, perspectiveMatrix.data()); transformLoc = glGetUniformLocation(getShaderProgram(), "viewTransform"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, viewingMatrix.data()); // Actual drawing glBindVertexArray(mVAO[inputNr]); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindTexture(GL_TEXTURE_2D, 0); glBindVertexArray(0); } glDisable(GL_BLEND); deactivateShader(); }