|
|
@ -1,5 +1,10 @@ |
|
|
|
#include <iostream> |
|
|
|
#include <iostream> |
|
|
|
#include <QResource> |
|
|
|
#include <QResource> |
|
|
|
|
|
|
|
#include <thread> |
|
|
|
|
|
|
|
#include <future> |
|
|
|
|
|
|
|
#include <QOpenGLFramebufferObject> |
|
|
|
|
|
|
|
#include <QFileDialog> |
|
|
|
|
|
|
|
#include <utility> |
|
|
|
#include "../headers/OutputWidget.h" |
|
|
|
#include "../headers/OutputWidget.h" |
|
|
|
|
|
|
|
|
|
|
|
using std::cout, std::endl; |
|
|
|
using std::cout, std::endl; |
|
|
@ -7,19 +12,28 @@ using std::cout, std::endl; |
|
|
|
void OutputWidget::initializeGL() { |
|
|
|
void OutputWidget::initializeGL() { |
|
|
|
cout << "Initialize OpenGL" << endl; |
|
|
|
cout << "Initialize OpenGL" << endl; |
|
|
|
initializeOpenGLFunctions(); |
|
|
|
initializeOpenGLFunctions(); |
|
|
|
getMandelbrot().init(); |
|
|
|
getMandelbrot().init(createVAO()); |
|
|
|
initShader(); |
|
|
|
if (!getMandelbrot().initShader()) close(); |
|
|
|
|
|
|
|
|
|
|
|
auto format = this->format(); |
|
|
|
auto format = this->format(); |
|
|
|
cout << "OpenGL version: " << format.majorVersion() << "." << format.minorVersion() << endl; |
|
|
|
cout << "OpenGL version: " << format.majorVersion() << "." << format.minorVersion() << endl; |
|
|
|
|
|
|
|
|
|
|
|
vao = createVAO(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); |
|
|
|
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void OutputWidget::paintGL() { |
|
|
|
void OutputWidget::paintGL() { |
|
|
|
getMandelbrot().draw(vao, shader); |
|
|
|
getMandelbrot().draw(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<QVector2D> genVertices() { |
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
{-1, -1}, |
|
|
|
|
|
|
|
{1, -1}, |
|
|
|
|
|
|
|
{1, 1}, |
|
|
|
|
|
|
|
{1, 1}, |
|
|
|
|
|
|
|
{-1, 1}, |
|
|
|
|
|
|
|
{-1, -1} |
|
|
|
|
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GLuint OutputWidget::createVAO() { |
|
|
|
GLuint OutputWidget::createVAO() { |
|
|
@ -44,23 +58,6 @@ GLuint OutputWidget::createVAO() { |
|
|
|
return vaoId; |
|
|
|
return vaoId; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<QVector2D> OutputWidget::genVertices() { |
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
{-1, -1}, |
|
|
|
|
|
|
|
{1, -1}, |
|
|
|
|
|
|
|
{1, 1}, |
|
|
|
|
|
|
|
{-1, 1} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OutputWidget::initShader() { |
|
|
|
|
|
|
|
if (!shader.addShaderFromSourceFile(QOpenGLShader::Vertex, "Vertex.glsl")) close(); |
|
|
|
|
|
|
|
if (!shader.addShaderFromSourceFile(QOpenGLShader::Fragment, "Fragment.glsl")) close(); |
|
|
|
|
|
|
|
if (!shader.link()) close(); |
|
|
|
|
|
|
|
if (!shader.bind()) close(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QVector2D divide(QPoint p, QSize s){ |
|
|
|
QVector2D divide(QPoint p, QSize s){ |
|
|
|
return { |
|
|
|
return { |
|
|
|
float(p.x()) / float(s.width()), |
|
|
|
float(p.x()) / float(s.width()), |
|
|
@ -113,3 +110,38 @@ void OutputWidget::mouseReleaseEvent(QMouseEvent *e) { |
|
|
|
void OutputWidget::keyPressEvent(QKeyEvent *e) { |
|
|
|
void OutputWidget::keyPressEvent(QKeyEvent *e) { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OutputWidget::saveToImage(const std::function<void(void)>& receiveCb, const std::function<void(bool)>& saveCb) { |
|
|
|
|
|
|
|
double maxSize = pow(2, 14); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double div = double(width()) / height(); |
|
|
|
|
|
|
|
int w, h; |
|
|
|
|
|
|
|
if (div > 1){ |
|
|
|
|
|
|
|
w = int(maxSize); |
|
|
|
|
|
|
|
h = int(maxSize / div); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
h = int(maxSize); |
|
|
|
|
|
|
|
w = int(maxSize * div); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QOpenGLFramebufferObject fbo(w, h); |
|
|
|
|
|
|
|
fbo.bind(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glViewport(0, 0, w, h); |
|
|
|
|
|
|
|
getMandelbrot().draw(); |
|
|
|
|
|
|
|
QOpenGLFramebufferObject::bindDefault(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QImage img = fbo.toImage(); |
|
|
|
|
|
|
|
receiveCb(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString fileName = QFileDialog::getSaveFileName(this, "", "", tr("Images (*.png *.xpm *.jpg)")); |
|
|
|
|
|
|
|
if (fileName.isNull()){ |
|
|
|
|
|
|
|
saveCb(false); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::thread job([saveCb](const QImage& img, const QString& fileName) { |
|
|
|
|
|
|
|
saveCb(img.save(fileName)); |
|
|
|
|
|
|
|
}, img, fileName); |
|
|
|
|
|
|
|
job.detach(); |
|
|
|
|
|
|
|
} |
|
|
|