Commit e9d20f87 authored by Andreas Kempe's avatar Andreas Kempe

Moved the renderer into a class to prepare for client/server operations.

parent b3c41f35
......@@ -10,7 +10,7 @@ find_package(Qt5Gui)
find_package(Qt5Network)
# Source files
set(SERVER_SRC server/main.cpp server/mandelbrot.cpp)
set(SERVER_SRC server/main.cpp server/mandelbrot.cpp server/mandel_render_srv.cpp)
set(CLIENT_SRC client/main.cpp client/main_window.cpp)
set(MANDELNET_SRC network/data_packet.cpp network/mandel_socket.cpp
network/mandel_tcp_server.cpp)
......
......@@ -8,7 +8,7 @@
main_window::main_window(unsigned int port, QWidget* parent) :
port(port), QWidget(parent)
{
mandel_image = new QImage("output.png");//(1064, 800, QImage::Format_RGB30);
mandel_image = new QImage(1064, 800, QImage::Format_RGB30);
scene = new QGraphicsScene(this);
scene->setSceneRect(0, 0, 1064, 800);
......
......@@ -10,7 +10,8 @@ enum op_codes : quint32
* The image should be in the payload
* encoded as base64 using ImageMagicks
* Blob-class. */
IMG_DATA = 0x1
IMG_DATA = 0x1,
RENDER_IMG = 0x2
};
#endif
#include "mandelbrot.h"
#include "mandel_socket.h"
#include "network_defines.h"
#include "data_packet.h"
#include "mandel_render_srv.h"
#include <mpi.h>
#include <iostream>
#include <Magick++.h>
#include <complex>
#include <cmath>
#include <sstream>
#include <iomanip>
#include <QCoreApplication>
#define IMG_WIDTH 1064lu
#define IMG_HEIGHT 800lu
......@@ -20,72 +12,24 @@
#define IM_MIN -1.3
using namespace std;
using namespace Magick;
void root_process_handling(unsigned long *receive_buffer)
{
Image my_image(Geometry(IMG_WIDTH, IMG_HEIGHT), "white");
my_image.modifyImage();
Pixels pixel_cache(my_image);
PixelPacket *pixels = pixel_cache.get(0, 0, IMG_WIDTH, IMG_HEIGHT);
cout << "Assembling image!" << endl;
for (unsigned long y = 0; y < IMG_HEIGHT; ++y)
{
cout << "Progress: " << setprecision(3) <<
static_cast<float>(y * 100) / IMG_HEIGHT << " % \r" << flush;
for (unsigned long x = 0; x < IMG_WIDTH; ++x)
{
const unsigned long& iter_res = receive_buffer[y * IMG_WIDTH + x];
if (iter_res == ITERATIONS)
pixels[y * IMG_WIDTH + x] = Color(MaxRGB * 0.55, MaxRGB * 0.35, MaxRGB * 0.6);
else
pixels[y * IMG_WIDTH + x] = Color(MaxRGB * cosf(exp(iter_res)), 0, MaxRGB * sinf(exp(iter_res)));
}
}
pixel_cache.sync();
cout << "Progress: 100 % " << endl;
cout << "Sending image!" << endl;
mandel_socket socket("192.168.1.2", PORT, nullptr);
socket.waitForConnected(10000);
Blob image_data;
my_image.magick("PNG");
my_image.write(&image_data);
std::string enc_img = image_data.base64();
char* data = new char[enc_img.size() + 1];
memcpy(data, enc_img.c_str(), enc_img.size() + 1);
data_packet packet(op_codes::IMG_DATA, enc_img.size() + 1, data);
socket.send_data_packet(packet);
// Since we don't have an event loop (yet?)
// we'll wait for the socket to finish sending its data.
while (!socket.is_transmission_done())
socket.waitForBytesWritten();
}
int main(int argc, char** argv)
{
int id;
int procs;
unsigned long *receive_buffer = nullptr;
// Init MPI.
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &procs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
// For the Qt event loop.
QCoreApplication app(argc, argv);
unsigned long effective_height = IMG_HEIGHT / procs;
mandel_settings settings = { .re_max = RE_MAX,
.re_min = RE_MIN,
.im_max = get_max_im(IM_MAX, IM_MIN, id, procs),
......@@ -94,22 +38,12 @@ int main(int argc, char** argv)
.img_height = effective_height,
.iterations = ITERATIONS };
mandelbrot mandel(settings);
mandel.calculate_set();
mandel_render_srv srv(settings, "192.168.1.2", PORT, id, procs, nullptr);
srv.start_drawing();
if (id == 0)
receive_buffer = new unsigned long[IMG_WIDTH * IMG_HEIGHT];
cout << "Process: " << id << ", gathering!" << endl;
MPI_Gather(mandel.get_point_array(), IMG_WIDTH * effective_height, MPI_UNSIGNED_LONG, receive_buffer,
IMG_WIDTH * effective_height, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
cout << "Process: " << id << ", done gathering!" << endl;
if (id == 0)
root_process_handling(receive_buffer);
delete[] receive_buffer;
int exit_code = app.exec();
MPI_Finalize();
return exit_code;
}
#include "mandel_render_srv.h"
#include <iostream>
#include <mpi.h>
#include <Magick++.h>
#include <iomanip>
#include <cmath>
#include <complex>
using namespace std;
using namespace Magick;
mandel_render_srv::mandel_render_srv(mandel_settings settings, std::string host, unsigned int port,
int id, int procs, QObject* parent) :
QObject(parent), settings(settings), id(id), procs(procs)
{
// We only let the root process connect to the client.
if (id == 0)
socket = new mandel_socket(host.c_str(), port, this);
else
socket = nullptr;
}
void mandel_render_srv::start_drawing()
{
unsigned long *receive_buffer = nullptr;
mandelbrot mandel(settings);
mandel.calculate_set();
if (id == 0)
receive_buffer = new unsigned long[settings.img_width * settings.img_height * procs];
cout << "Process: " << id << ", gathering!" << endl;
MPI_Gather(mandel.get_point_array(), settings.img_width * settings.img_height,
MPI_UNSIGNED_LONG, receive_buffer, settings.img_width * settings.img_height,
MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
cout << "Process: " << id << ", done gathering!" << endl;
if (id == 0)
root_process_handling(receive_buffer);
delete[] receive_buffer;
}
void mandel_render_srv::root_process_handling(unsigned long *receive_buffer)
{
Image my_image(Geometry(settings.img_width, settings.img_width * procs), "white");
my_image.modifyImage();
Pixels pixel_cache(my_image);
PixelPacket *pixels = pixel_cache.get(0, 0, settings.img_width, settings.img_width * procs);
cout << "Assembling image!" << endl;
for (unsigned long y = 0; y < settings.img_width * procs; ++y)
{
cout << "Progress: " << setprecision(3) <<
static_cast<float>(y * 100) / settings.img_width * procs << " % \r" << flush;
for (unsigned long x = 0; x < settings.img_width; ++x)
{
const unsigned long& iter_res = receive_buffer[y * settings.img_width + x];
if (iter_res == settings.iterations)
pixels[y * settings.img_width + x] = Color(MaxRGB * 0.55, MaxRGB * 0.35, MaxRGB * 0.6);
else
pixels[y * settings.img_width + x] = Color(MaxRGB * cosf(exp(iter_res)), 0,
MaxRGB * sinf(exp(iter_res)));
}
}
pixel_cache.sync();
cout << "Progress: 100 % " << endl;
cout << "Sending image!" << endl;
Blob image_data;
my_image.magick("PNG");
my_image.write(&image_data);
std::string enc_img = image_data.base64();
char* data = new char[enc_img.size() + 1];
memcpy(data, enc_img.c_str(), enc_img.size() + 1);
data_packet packet(op_codes::IMG_DATA, enc_img.size() + 1, data);
socket->send_data_packet(packet);
}
#ifndef MANDEL_RENDER_SRV_H
#define MANDEL_RENDER_SRV_H
#include <QObject>
#include "mandel_socket.h"
#include "mandelbrot.h"
class mandel_render_srv : public QObject
{
public:
mandel_render_srv(mandel_settings settings, std::string host, unsigned int port,
int id, int procs, QObject* parent);
void start_drawing();
private:
void root_process_handling(unsigned long *receive_buffer);
mandel_settings settings;
const int id;
const int procs;
mandel_socket* socket;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment