void MultiplanarSliceRenderer::process() { tgtAssert(inport_.isReady(), "Inport not ready"); tgtAssert(inport_.getData()->getRepresentation<VolumeRAM>(), "No volume"); outport_.activateTarget("OrthogonalSliceRenderer::process()"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // get GL resources and setup shader TextureUnit transferUnit, texUnit; bool setupSuccessful; if (texMode_.isSelected("2d-texture")) { // 2D texture setupSuccessful = setupSliceShader(sliceShader_, inport_.getData(), &transferUnit); } else if (texMode_.isSelected("3d-texture")) { // 3D texture // also binds the volume setupSuccessful = setupVolumeShader(sliceShader_, inport_.getData(), &texUnit, &transferUnit, 0, lightPosition_.get()); } else { LERROR("unknown texture mode: " << texMode_.get()); setupSuccessful = false; } if (!setupSuccessful) { outport_.deactivateTarget(); return; } transferUnit.activate(); transferFunc_.get()->bind(); sliceShader_->setUniform("textureMatrix_", tgt::mat4::identity); // important: save current camera state before using the processor's camera or // successive processors will use those settings! // glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); camProp_.look(outport_.getSize()); // transform bounding box by dataset transformation matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); tgt::multMatrix(inport_.getData()->getPhysicalToWorldMatrix()); if (renderXYSlice_.get()) { renderSlice(SLICE_XY, sliceNumberXY_.get(), texUnit); } if (renderXZSlice_.get()) { renderSlice(SLICE_XZ, sliceNumberXZ_.get(), texUnit); } if (renderYZSlice_.get()) { renderSlice(SLICE_YZ, sliceNumberYZ_.get(), texUnit); } // restore matrix stack glPopMatrix(); deactivateShader(); glActiveTexture(GL_TEXTURE0); outport_.deactivateTarget(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }
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(); }