Tornado-Visualization/datenvisualisierung_sose2024/horizontalslicerenderer.cpp
2024-07-07 01:39:09 +02:00

234 lines
7.4 KiB
C++

#include "horizontalslicerenderer.h"
#include <iostream>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#include <QOpenGLTexture>
#include <QImage>
HorizontalSliceRenderer::HorizontalSliceRenderer()
: vertexBuffer(QOpenGLBuffer::VertexBuffer)
{
initOpenGLShaders();
initBoundingBoxGeometry();
initFrame();
}
HorizontalSliceRenderer::HorizontalSliceRenderer(int zy, int zsy)
: vertexBuffer(QOpenGLBuffer::VertexBuffer)
{
z=zy;
zs=zsy;
initOpenGLShaders();
initBoundingBoxGeometry();
initFrame();
}
HorizontalSliceRenderer::~HorizontalSliceRenderer()
{
vertexBuffer.destroy();
frameBuffer.destroy();
std::cout << "RENDERER DESTRUCTOR CALLED\n";
}
void HorizontalSliceRenderer::setMapper(HorizontalSliceToImageMapper* mappery) {
mapper = mappery;
}
void HorizontalSliceRenderer::initOpenGLShaders()
{
if (!shaderProgramTexture.addShaderFromSourceFile(QOpenGLShader::Vertex,
"lines_vshader_texture.glsl"))
{
std::cout << "Vertex shader error:\n"
<< shaderProgramTexture.log().toStdString() << "\n" << std::flush;
return;
}
if (!shaderProgramTexture.addShaderFromSourceFile(QOpenGLShader::Fragment,
"lines_fshader_texture.glsl"))
{
std::cout << "Fragment shader error:\n"
<< shaderProgramTexture.log().toStdString() << "\n" << std::flush;
return;
}
if (!shaderProgramTexture.link())
{
std::cout << "Shader link error:\n"
<< shaderProgramTexture.log().toStdString() << "\n" << std::flush;
return;
}
// For the cube and the frame
if (!shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
"lines_vshader.glsl"))
{
std::cout << "Vertex shader error:\n"
<< shaderProgram.log().toStdString() << "\n" << std::flush;
return;
}
if (!shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
"lines_fshader.glsl"))
{
std::cout << "Fragment shader error:\n"
<< shaderProgram.log().toStdString() << "\n" << std::flush;
return;
}
if (!shaderProgram.link())
{
std::cout << "Shader link error:\n"
<< shaderProgram.log().toStdString() << "\n" << std::flush;
return;
}
}
void HorizontalSliceRenderer::initBoundingBoxGeometry()
{
// Vertices of a unit cube that represents the bounding box.
const unsigned int numVertices = 16;
float unitCubeVertices[numVertices][3] = {
{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0},
{0, 0, 0}, {0, 0, 1}, {1, 0, 1}, {1, 0, 0},
{1, 0, 1}, {1, 1, 1}, {1, 1, 0}, {1, 1, 1},
{0, 1, 1}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}};
// Create vertex buffer and upload vertex data to buffer.
vertexBuffer.create(); // make sure to destroy in destructor!
vertexBuffer.bind();
vertexBuffer.allocate(unitCubeVertices, numVertices * 3 * sizeof(float));
vertexBuffer.release();
// Store the information OpenGL needs for rendering the vertex buffer
// in a "vertex array object". This can easily be bound to the OpenGL
// pipeline during rendering.
QOpenGLVertexArrayObject::Binder vaoBinder(&vertexArrayObject);
if (vertexArrayObject.isCreated())
{
vertexBuffer.bind();
shaderProgram.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3, 3*sizeof(float));
shaderProgram.enableAttributeArray("vertexPosition");
vertexBuffer.release();
}
}
void HorizontalSliceRenderer::moveSlice(int steps) {
z += steps;
float zeddy = float(z)/float(zs-1);
const unsigned int numVertices = 5;
float unitFrameVertices[numVertices][3] = {
{0, 0, zeddy}, {1, 0, zeddy}, {1, 1, zeddy}, {0, 1, zeddy}, {0, 0, zeddy}};
// Vertex Buffer upload
frameBuffer.bind();
frameBuffer.allocate(unitFrameVertices, numVertices * 3 * sizeof(float));
frameBuffer.release();
}
void HorizontalSliceRenderer::initFrame() {
// Works analogously to the init of the Bounding Box
const unsigned int numVertices = 5;
float zeddy = float(z)/float(zs-1);
std::cout << zeddy << std::endl;
float unitFrameVertices[numVertices][3] = {
{0, 0, zeddy}, {1, 0, zeddy}, {1, 1, zeddy}, {0, 1, zeddy}, {0, 0, zeddy}};
// Vertex Buffer upload
frameBuffer.create(); // make sure to destroy in destructor!
frameBuffer.bind();
frameBuffer.allocate(unitFrameVertices, numVertices * 3 * sizeof(float));
frameBuffer.release();
// I don't know exactly what happens here
QOpenGLVertexArrayObject::Binder vaoBinder(&frameArrayObject);
if (frameArrayObject.isCreated())
{
frameBuffer.bind();
shaderProgram.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3, 3*sizeof(float));
shaderProgram.enableAttributeArray("vertexPosition");
shaderProgramTexture.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3, 3*sizeof(float));
shaderProgramTexture.enableAttributeArray("vertexPosition");
frameBuffer.release();
}
}
void HorizontalSliceRenderer::drawImage(QMatrix4x4 mvpMatrix) {
img = mapper->mapSliceToImage();
//QImage img = (*mapper).mapSliceToImage("uhhlogo.png");
if (img.isNull()) {
std::cout << "IMAGE LOADING IN RENDERER ERROR";
}
QOpenGLTexture texture(QOpenGLTexture::Target2D);
texture.create();
texture.setWrapMode(QOpenGLTexture::ClampToEdge);
texture.setData(img);
const int textureUnit = 0;
texture.bind(textureUnit);
shaderProgramTexture.setUniformValue("colorMappingTexture", textureUnit);
// Issue OpenGL draw commands.
shaderProgramTexture.bind();
frameArrayObject.bind();
shaderProgramTexture.setUniformValue("mvpMatrix", mvpMatrix);
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
frameArrayObject.release();
texture.release();
shaderProgramTexture.release();
texture.destroy();
}
void HorizontalSliceRenderer::drawBoundingBox(QMatrix4x4 mvpMatrix)
{
// Tell OpenGL to use the shader program of this class.
shaderProgram.bind();
// Bind the vertex array object that links to the bounding box vertices.
vertexArrayObject.bind();
// Set the model-view-projection matrix as a uniform value.
shaderProgram.setUniformValue("mvpMatrix", mvpMatrix);
// Issue OpenGL draw commands.
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glLineWidth(2);
f->glDrawArrays(GL_LINE_STRIP, 0, 16);
// Release objects until next render cycle.
vertexArrayObject.release();
shaderProgram.release();
}
void HorizontalSliceRenderer::drawFrame(QMatrix4x4 mvpMatrix)
{
// Tell OpenGL to use the shader program of this class.
shaderProgram.bind();
// Bind the vertex array object that links to the bounding box vertices.
frameArrayObject.bind();
// Set the model-view-projection matrix as a uniform value.
shaderProgram.setUniformValue("mvpMatrix", mvpMatrix);
// Issue OpenGL draw commands.
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glLineWidth(2);
f->glDrawArrays(GL_LINE_STRIP, 0, 5);
// Release objects until next render cycle.
frameArrayObject.release();
shaderProgram.release();
}