Added directional lighting

Made screenshot capture more generic and easier to use
Fixed most compiler warnings
master
Colin 2015-10-16 14:18:08 -07:00
parent adba91d30c
commit da9fff03af
12 changed files with 161 additions and 85 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ SDL_VoxelEngine/SDL_VoxelEngine/Release/
SDL_VoxelEngine/SDL_VoxelEngine/Debug/
SDL_VoxelEngine/Release/
SDL_VoxelEngine/Debug/
*.bmp

Binary file not shown.

View File

@ -1,7 +1,7 @@
#include "Camera.h"
Camera::Camera(double _x, double _y, double _z, double _rotY, double _rotZ, double _rotX,
double _fovH, double _fovV) {
Camera::Camera(float _x, float _y, float _z, float _rotY, float _rotZ, float _rotX,
float _fovH, float _fovV) {
x = _x;
y = _y;
z = _z;

View File

@ -1,12 +1,12 @@
class Camera {
public:
double x;
double y;
double z;
double rotX;
double rotY;
double rotZ;
double fovH;
double fovV;
Camera(double, double, double, double, double, double, double, double);
float x;
float y;
float z;
float rotX;
float rotY;
float rotZ;
float fovH;
float fovV;
Camera(float, float, float, float, float, float, float, float);
};

View File

@ -5,7 +5,7 @@ LabeledColor ColorLibrary::getRandomColor() {
}
LabeledColor ColorLibrary::getColor(string name) {
for (int i = 0; i < colors->size(); i++) {
for (unsigned int i = 0; i < colors->size(); i++) {
LabeledColor c = colors->at(i);
if (c.name == name) {
return c;
@ -18,7 +18,7 @@ LabeledColor ColorLibrary::getColor(int index) {
}
LabeledPalette ColorLibrary::getPalette(string name) {
for (int i = 0; i < palettes->size(); i++) {
for (unsigned int i = 0; i < palettes->size(); i++) {
LabeledPalette p = palettes->at(i);
if (p.name == name) {
return p;
@ -31,12 +31,13 @@ LabeledPalette ColorLibrary::getPalette(int index) {
}
int ColorLibrary::indexOfPalette(string name) {
for (int i = 0; i < palettes->size(); i++) {
for (unsigned int i = 0; i < palettes->size(); i++) {
LabeledPalette p = palettes->at(i);
if (p.name == name) {
return i;
}
}
return -1;
}
string ColorLibrary::nextPalette(string name) {

View File

@ -7,12 +7,12 @@ using namespace std;
typedef struct LabeledColor {
string name;
SDL_Color color;
};
} LabeledColor;
typedef struct LabeledPalette {
string name;
vector<string> palette;
};
} LabeledPalette;
class ColorLibrary {
private:

View File

@ -3,13 +3,15 @@
#include <ctime>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include "Renderer.h"
#include "ObjectGenerator.h"
// Frame constants
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 960;
const double pi = 3.14159f;
const float pi = 3.14159f;
int BPP = 4;
// SDL functions
@ -36,9 +38,24 @@ World* world;
Camera* camera;
ObjectGenerator* generator;
ColorLibrary* library;
double speed = 1.0f;
float speed = 1.0f;
Palette* palette;
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
bool init() {
// Initialization flag
bool success = true;
@ -68,21 +85,6 @@ bool init() {
return success;
}
bool loadMedia() {
//Loading success flag
bool success = true;
//Load splash image
gSurface = SDL_LoadBMP("1280x960.bmp");
if (gSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", "hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}
void close() {
// Deallocate surface
SDL_FreeSurface(gSurface);
@ -104,7 +106,7 @@ void captureImage(int width, int height) {
Uint8 *pixels = (Uint8 *)imageSurface->pixels;
renderer->renderFrame(pixels, width, height, 1);
int rn = rand() % 1000000;
std:string filename = "image-" + std::to_string(rn) + ".bmp";
string filename = "image-" + std::to_string(rn) + ".bmp";
SDL_SaveBMP(imageSurface, filename.c_str());
}
}
@ -281,6 +283,53 @@ void NewRandomPalette() {
library->addPalette(paletteName, colorNames);
}
void CaptureImageAction() {
printf("\n== Capture image ==\n");
// initialize variables
int width = 0;
int height = 0;
float fovV = 0;
float fovH = 0;
float oldFovV = camera->fovV;
float oldFovH = camera->fovH;
// get aspect ratio from user
char toggle;
printf("Use smart capture? y/n ");
cin >> toggle;
if (toggle = 'y') {
string resolution;
printf("Enter a resolution.\n Examples: 4096x4096, 2560x1920, 3840x2160, 3840x1080\n");
printf("Resolution = ");
cin >> resolution;
vector<string> vs = split(resolution, 'x');
width = atoi(vs.at(0).c_str());
height = atoi(vs.at(1).c_str());
fovH = pi / 2.5;
fovV = (height * 2 * pi) / (9 * width);
} else {
printf("Width = ");
cin >> width;
printf("Height = ");
cin >> height;
printf("FovH = ");
cin >> fovH;
printf("FovV = ");
cin >> fovV;
}
// capture image
double start = clock();
camera->fovH = fovH;
camera->fovV = fovV;
captureImage(width, height);
double duration = (clock() - start) / (double)CLOCKS_PER_SEC;
printf("DONE! (%#.3fs)\n", duration);
camera->fovH = oldFovH;
camera->fovV = oldFovV;
}
using namespace std;
int main(int argc, char* args[]) {
@ -296,7 +345,7 @@ int main(int argc, char* args[]) {
string ObjectType;
// initialize colors and palettes
srand(time(NULL));
srand((unsigned int) time(NULL));
library = new ColorLibrary();
addColors();
addPalettes();
@ -334,7 +383,8 @@ int main(int argc, char* args[]) {
int cOffset = offset - 2;
printf("\nInitializing world...\n");
world = new World(WorldSize);
camera = new Camera(cOffset, cOffset, cOffset, 0, 0, pi / 2.0f, pi / 2.5f, pi / 6.0f);
// initialize camera, fovH = ~1.2566, fovV = 0.5235
camera = new Camera((float) cOffset, (float) cOffset, (float) cOffset, 0, 0, pi / 2.0f, pi / 2.5f, pi / 6.0f);
renderer = new Renderer(world, camera);
renderer->defaultOptions();
generator = new ObjectGenerator(world);
@ -360,7 +410,7 @@ int main(int argc, char* args[]) {
}
}
else if (ObjectType == "octflake") {
FlakeParams* fParams = new FlakeParams(ObjectSize, offset, offset, offset, scale);
FlakeParams* fParams = new FlakeParams(ObjectSize, offset, offset, offset, (int) scale);
if (ObjectType == "octflake") {
generator->generateOctFlake(fParams);
}
@ -389,11 +439,7 @@ int main(int argc, char* args[]) {
}
else
{
//Load media
if (!loadMedia())
{
printf("Failed to load media!\n");
}
gSurface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0, 0, 0, 0);
}
printf("%d, %d, %d, %d\n", gSurface->pitch, gSurface->format, gSurface->w, gSurface->h);
@ -409,7 +455,7 @@ int main(int argc, char* args[]) {
frames++;
if (frames == 60) {
duration = (clock() - start) / (double) CLOCKS_PER_SEC;;
std:printf("FPS: %f\n", 60 / duration);
printf("FPS: %f\n", 60 / duration);
printCameraCoords();
printLightingInfo();
start = clock();
@ -483,27 +529,7 @@ int main(int argc, char* args[]) {
LoadPalette(PaletteChoice, ObjectType, minIt, maxIt);
}
if (keys[SDL_GetScancodeFromKey(SDLK_c)]) {
printf("== Capture image ==\n");
int width = 0;
int height = 0;
float fovV = 0;
float fovH = 0;
float oldFovV = camera->fovV;
float oldFovH = camera->fovH;
printf("Width = ");
cin >> width;
printf("Height = ");
cin >> height;
printf("FovV = ");
cin >> fovV;
printf("FovH = ");
cin >> fovH;
camera->fovV = fovV;
camera->fovH = fovH;
captureImage(width, height);
printf("DONE!");
camera->fovV = oldFovV;
camera->fovH = oldFovH;
CaptureImageAction();
}
if (keys[SDL_GetScancodeFromKey(SDLK_RIGHTBRACKET)]) {
PaletteChoice = library->nextPalette(PaletteChoice);

View File

@ -63,18 +63,18 @@ Palette::Palette(LabeledPalette libPalette, ColorLibrary* library, Uint8 max) {
float unit = (size - 1) / ((float) (length - 1));
for (int i = 0; i < length; i++) {
float mappedIndex = i * unit;
int lowIndex = floor(mappedIndex);
int lowIndex = (int) floor(mappedIndex);
if (lowIndex == mappedIndex) {
colors[i] = base[lowIndex];
} else {
int highIndex = ceil(mappedIndex);
int highIndex = (int) ceil(mappedIndex);
float highPercent = mappedIndex - lowIndex;
float lowPercent = 1.0 - highPercent;
float lowPercent = 1.0f - highPercent;
SDL_Color iColor;
iColor.a = floor(lowPercent * base[lowIndex].a + highPercent * base[highIndex].a);
iColor.r = floor(lowPercent * base[lowIndex].r + highPercent * base[highIndex].r);
iColor.g = floor(lowPercent * base[lowIndex].g + highPercent * base[highIndex].g);
iColor.b = floor(lowPercent * base[lowIndex].b + highPercent * base[highIndex].b);
iColor.a = (Uint8) floor(lowPercent * base[lowIndex].a + highPercent * base[highIndex].a);
iColor.r = (Uint8) floor(lowPercent * base[lowIndex].r + highPercent * base[highIndex].r);
iColor.g = (Uint8) floor(lowPercent * base[lowIndex].g + highPercent * base[highIndex].g);
iColor.b = (Uint8) floor(lowPercent * base[lowIndex].b + highPercent * base[highIndex].b);
colors[i] = iColor;
}

View File

@ -9,10 +9,18 @@ template <typename T> int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
template <typename T> T max(T a, T b)
{
return a > b ? a : b;
}
void Renderer::defaultOptions() {
falloff = 4.0f;
rate = 0.6f;
rate = 1.0f;
ambientIntensity = 0.2f;
directionalIntensity = 0.3f;
renderDistance = 100;
}
void Renderer::renderThread(Uint8* pixels, int y1, int y2, int width, int height, float* ref, int pixelScale) {
@ -74,8 +82,8 @@ void Renderer::renderFrame(Uint8* pixels, int width, int height, int pixelScale)
}
SDL_Color Renderer::raycastFrom(int px, int py, int width, int height, float* ref) {
float w2 = width / 2.0;
float h2 = height / 2.0;
float w2 = width / 2.0f;
float h2 = height / 2.0f;
float x = camera->x;
float y = camera->y;
@ -127,9 +135,9 @@ SDL_Color Renderer::raycast(float x, float y, float z, float* ray) {
float tDeltaY = 1 / ay;
float tDeltaZ = 1 / az;
float tMaxX = abs((sx == 1) ? (1 - (fmod(x, 1.0))) : (fmod(x, 1.0))) / ax;
float tMaxY = abs((sy == 1) ? (1 - (fmod(y, 1.0))) : (fmod(y, 1.0))) / ay;
float tMaxZ = abs((sz == 1) ? (1 - (fmod(z, 1.0))) : (fmod(z, 1.0))) / az;
float tMaxX = (float) abs((sx == 1) ? (1 - (fmod(x, 1.0f))) : (fmod(x, 1.0f))) / ax;
float tMaxY = (float) abs((sy == 1) ? (1 - (fmod(y, 1.0f))) : (fmod(y, 1.0f))) / ay;
float tMaxZ = (float) abs((sz == 1) ? (1 - (fmod(z, 1.0f))) : (fmod(z, 1.0f))) / az;
n = (int) (abs(dx) + abs(dy) + abs(dz));
@ -160,10 +168,10 @@ SDL_Color Renderer::raycast(float x, float y, float z, float* ray) {
tMaxZ += tDeltaZ;
}
}
Uint8 block = world->getBlock(x, y, z);
Uint8 block = world->getBlock((int) x, (int) y, (int) z);
if (block != 0) {
SDL_Color c = world->getColor(block);
return calculateColor(c, startX, x, startY, y, startZ, z);
return calculateColor(c, face, startX, x, startY, y, startZ, z);
}
}
@ -186,17 +194,22 @@ Renderer::Renderer(World* _world, Camera* _camera) {
skybox.r = 0;
}
SDL_Color Renderer::calculateColor(SDL_Color c, float x1, float x2, float y1,
SDL_Color Renderer::calculateColor(SDL_Color c, int face, float x1, float x2, float y1,
float y2, float z1, float z2) {
float ray[] = { x1 - x2, y1 - y2, z1 - z2 };
float distance = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2));
double lightIntensity = falloff / pow(distance, rate);
float dot = abs(ray[face]);
// compute light intensity from ambient, directional, and diffuse light intensities
float diffuseIntensity = (falloff / pow(distance, rate)) * dot;
float lightIntensity = ambientIntensity + (1 - ambientIntensity - directionalIntensity) * diffuseIntensity;
// calculate color components
int red = (int)(c.r * lightIntensity);
int red = (int) (c.r * lightIntensity);
red = (red > 255) ? 255 : red;
int green = (int)(c.g * lightIntensity);
int green = (int) (c.g * lightIntensity);
green = (green > 255) ? 255 : green;
int blue = (int)(c.b * lightIntensity);
int blue = (int) (c.b * lightIntensity);
blue = (blue > 255) ? 255 : blue;
c.r = red;
c.b = blue;

View File

@ -14,10 +14,12 @@ public:
void Renderer::renderThread(Uint8*, int, int, int, int, float*, int);
SDL_Color raycastFrom(int, int, int, int, float*);
SDL_Color raycast(float, float, float, float*);
SDL_Color calculateColor(SDL_Color, float, float, float, float, float, float);
SDL_Color calculateColor(SDL_Color, int, float, float, float, float, float, float);
bool inBounds(float, float, float);
Renderer(World*, Camera*);
float falloff;
float rate;
float ambientIntensity;
float directionalIntensity;
int renderDistance;
};

View File

@ -0,0 +1,33 @@
(1:1) (1.2566h 0.7v)
1024x1024
2048x2048
4096x4096
8192x8192
10240x10240
(4:3) (1.2566h 0.5235v)
640x480
960x720
1280x960
1920x1440
2560x1920
3840x2880
5120x3840
7680x5760
10240x7680
(16:9) (1.2566h 0.3926v)
1280x720
1920x1080
2560x1440
3840x2160
5120x2880
7680x4320
10240x5760
(32:9) (2.5132h 0.3926v)
2560x720
3840x1080
5120x1440
7680x2160
10240x2880