send image data to client
This commit is contained in:
parent
8b62cd574d
commit
e41d268581
57
src/colour.h
57
src/colour.h
|
@ -2,22 +2,65 @@
|
||||||
|
|
||||||
#include "rtweekend.h"
|
#include "rtweekend.h"
|
||||||
|
|
||||||
|
// for writing to stdout
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void write_colour(std::ostream &out, colour pixel_colour, int samples_per_pixel)
|
// for writing to socket
|
||||||
{
|
#include <unistd.h>
|
||||||
auto r = pixel_colour.x();
|
|
||||||
auto g = pixel_colour.y();
|
|
||||||
auto b = pixel_colour.z();
|
|
||||||
|
|
||||||
// divide the colour total by the number of samples and gamme-correct for gamma=2.0
|
void correct_gamma(colour& pixel_colour, int samples)
|
||||||
auto scale = 1.0 / samples_per_pixel;
|
{
|
||||||
|
double r = pixel_colour.x();
|
||||||
|
double g = pixel_colour.y();
|
||||||
|
double b = pixel_colour.z();
|
||||||
|
|
||||||
|
// divide the colour total by the number of samples and gamma-correct for gamma=2.0
|
||||||
|
auto scale = 1.0 / samples;
|
||||||
r = sqrt(scale * r);
|
r = sqrt(scale * r);
|
||||||
g = sqrt(scale * g);
|
g = sqrt(scale * g);
|
||||||
b = sqrt(scale * b);
|
b = sqrt(scale * b);
|
||||||
|
|
||||||
|
pixel_colour = colour(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_colour_to_stream(std::ostream &out, colour pixel_colour, int samples_per_pixel)
|
||||||
|
{
|
||||||
|
correct_gamma(pixel_colour, samples_per_pixel);
|
||||||
|
|
||||||
|
auto r = pixel_colour.x();
|
||||||
|
auto g = pixel_colour.y();
|
||||||
|
auto b = pixel_colour.z();
|
||||||
|
|
||||||
// write the translated [0,255] value of each colour component.
|
// write the translated [0,255] value of each colour component.
|
||||||
out << static_cast<int>(256 * clamp(r, 0.0, 0.999)) << ' '
|
out << static_cast<int>(256 * clamp(r, 0.0, 0.999)) << ' '
|
||||||
<< static_cast<int>(256 * clamp(g, 0.0, 0.999)) << ' '
|
<< static_cast<int>(256 * clamp(g, 0.0, 0.999)) << ' '
|
||||||
<< static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
|
<< static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int format_component(double component)
|
||||||
|
{
|
||||||
|
return int(256 * clamp(component, 0.0, 0.999));
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_colour_to_socket(int sockfd, colour pixel_colour, int samples_per_pixel)
|
||||||
|
{
|
||||||
|
correct_gamma(pixel_colour, samples_per_pixel);
|
||||||
|
|
||||||
|
|
||||||
|
int r = format_component(pixel_colour.x());
|
||||||
|
int g = format_component(pixel_colour.y());
|
||||||
|
int b = format_component(pixel_colour.z());
|
||||||
|
|
||||||
|
// pack values
|
||||||
|
int len = 3;
|
||||||
|
char s[len];
|
||||||
|
sprintf(s, "%c%c%c", r, g, b);
|
||||||
|
|
||||||
|
printf("SEND %x %x %x\n", r, g, b);
|
||||||
|
|
||||||
|
int written = write(sockfd, s, len);
|
||||||
|
if (written < 0)
|
||||||
|
{
|
||||||
|
error("ERROR writing colour to socket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
60
src/main.cpp
60
src/main.cpp
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
#include "hittable_list.h"
|
#include "hittable_list.h"
|
||||||
#include "sphere.h"
|
#include "sphere.h"
|
||||||
|
|
||||||
|
void error(const char* message)
|
||||||
|
{
|
||||||
|
perror(message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
#include "colour.h"
|
#include "colour.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
|
@ -15,8 +22,8 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
const double ASPECT_RATIO = 16.0 / 9.0;
|
const double ASPECT_RATIO = 1.0;
|
||||||
const int WIDTH = 1920;
|
const int WIDTH = 64;
|
||||||
const int HEIGHT = static_cast<int>(WIDTH / ASPECT_RATIO);
|
const int HEIGHT = static_cast<int>(WIDTH / ASPECT_RATIO);
|
||||||
const int SAMPLES_PER_PIXEL = 8;
|
const int SAMPLES_PER_PIXEL = 8;
|
||||||
const int MAX_DEPTH = 5;
|
const int MAX_DEPTH = 5;
|
||||||
|
@ -119,12 +126,6 @@ hittable_list random_scene()
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
void error(const char* message)
|
|
||||||
{
|
|
||||||
perror(message);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// file descriptor of the socket we're listening for connections on
|
// file descriptor of the socket we're listening for connections on
|
||||||
//
|
//
|
||||||
// returns fd for the client connection
|
// returns fd for the client connection
|
||||||
|
@ -162,6 +163,18 @@ int wait_for_client(int& sockfd)
|
||||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
serv_addr.sin_port = htons(64999); // convert number from host to network byte order
|
serv_addr.sin_port = htons(64999); // convert number from host to network byte order
|
||||||
|
|
||||||
|
// this is a bit of developer QoL so we can iterate more quickly
|
||||||
|
// TODO: make it possible to disable this debug/release build configuration
|
||||||
|
const int enable = 1;
|
||||||
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
|
||||||
|
{
|
||||||
|
error("ERROR setsockopt(SO_REUSEADDR) failed");
|
||||||
|
}
|
||||||
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0)
|
||||||
|
{
|
||||||
|
error("ERROR setsockopt(SO_REUSEPORT) failed");
|
||||||
|
}
|
||||||
|
|
||||||
// bind the socket
|
// bind the socket
|
||||||
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
|
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
|
||||||
{
|
{
|
||||||
|
@ -193,17 +206,15 @@ int main()
|
||||||
printf("got a connection!\n");
|
printf("got a connection!\n");
|
||||||
|
|
||||||
// write a message to the client
|
// write a message to the client
|
||||||
send_message(newsockfd, "hi there!");
|
//send_message(newsockfd, "hi there!");
|
||||||
|
|
||||||
// close client socket
|
// write image header
|
||||||
close(newsockfd);
|
char buf[100];
|
||||||
|
sprintf(buf, "P3\n%d %d\n255\n", WIDTH, HEIGHT);
|
||||||
|
send_message(newsockfd, buf);
|
||||||
|
|
||||||
printf("closed client connection\n");
|
//write_colour_to_socket(newsockfd, colour(.4, .5, .6), 1);
|
||||||
|
|
||||||
// close listening socket
|
|
||||||
close(sockfd);
|
|
||||||
// exit after all our connections are closed
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
std::cout << "P3\n" << WIDTH << ' ' << HEIGHT << "\n255\n";
|
std::cout << "P3\n" << WIDTH << ' ' << HEIGHT << "\n255\n";
|
||||||
|
|
||||||
|
@ -234,10 +245,23 @@ int main()
|
||||||
pixel_colour += ray_colour(r, world, MAX_DEPTH);
|
pixel_colour += ray_colour(r, world, MAX_DEPTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_colour(std::cout, pixel_colour, SAMPLES_PER_PIXEL);
|
//write_colour_to_stream(std::cout, pixel_colour, SAMPLES_PER_PIXEL);
|
||||||
|
write_colour_to_socket(newsockfd, pixel_colour, SAMPLES_PER_PIXEL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "\nDone." << std::endl;
|
// close client socket
|
||||||
|
close(newsockfd);
|
||||||
|
|
||||||
|
printf("closed client connection\n");
|
||||||
|
|
||||||
|
// close listening socket
|
||||||
|
close(sockfd);
|
||||||
|
|
||||||
|
printf("closed listening socket\n");
|
||||||
|
|
||||||
|
printf("done!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rti1w as a base
|
||||||
* [x] client establishes connection
|
* [x] client establishes connection
|
||||||
* [x] send a message to the client
|
* [x] send a message to the client
|
||||||
* [ ] move rendering out of main.cpp
|
* [ ] move rendering out of main.cpp
|
||||||
* [ ] send rendered image data to client
|
* [x] send rendered image data to client
|
||||||
* [ ] form image file on client
|
* [ ] form image file on client
|
||||||
* [ ] client sends receiving port to server
|
* [ ] client sends receiving port to server
|
||||||
* [ ] client application sends command to send image
|
* [ ] client application sends command to send image
|
||||||
|
|
Loading…
Reference in New Issue