Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <math.h>
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #define WIDTH 119
- #define HEIGHT 29
- #define PIXELASPECT 2.0f
- struct vec3 {
- float x;
- float y;
- float z;
- vec3 operator+(const vec3& other) const {
- return { x + other.x, y + other.y, z + other.z };
- }
- vec3 operator-(const vec3& other) const {
- return { x - other.x, y - other.y, z - other.z };
- }
- vec3 operator-() const {
- return { -x, -y, -z };
- }
- vec3 operator*(const float& scalar) const {
- return { x * scalar, y * scalar, z * scalar };
- }
- vec3 operator/(const float& scalar) const {
- return { x / scalar, y / scalar, z / scalar };
- }
- float dot(const vec3& other) const {
- return x * other.x + y * other.y + z * other.z;
- }
- float len() const {
- return sqrtf(this->dot(*this));
- }
- void normalize() {
- float len = this->len();
- x /= len;
- y /= len;
- z /= len;
- }
- };
- // Sphere data
- vec3 center{ 0.0f, 0.0f, 0.0f };
- float radius = 22.0f;
- // Light data
- vec3 lightpos{ 0.0f, 0.0f, -500.0f };
- const char colors[] = { '.', '-', ':', '=', '+', '#', '@' };
- // Each frame, we move the light around in a circle
- void update(unsigned int frame) {
- lightpos.x = sinf((float)frame / 10.0f) * 500.0f;
- lightpos.y = cosf((float)frame / 10.0f) * 500.0f;
- }
- float intersectSphere(vec3 origin, vec3 dir, vec3 center, float radius) {
- vec3 oc = origin - center;
- float a = 1.0f;
- float b = 2.0f * oc.dot(dir);
- float c = oc.dot(oc) - radius * radius;
- float discriminant = b * b - 4 * a * c;
- if (discriminant < 0.0f) {
- return -1.0f;
- }
- return (-b - sqrtf(discriminant)) / (2.0f * a);
- }
- void draw() {
- // Ray direction - all parallel, down Z axis.
- const vec3 dir{ 0.0f, 0.0f, 1.0f };
- // For each pixel...
- for (int y = 0; y < HEIGHT; y++) {
- for (int x = 0; x < WIDTH; x++) {
- float xWorld = x - (WIDTH / 2) + 0.5f;
- float yWorld = (y - (HEIGHT / 2) + 0.5f) * PIXELASPECT;
- vec3 origin = vec3{ xWorld, yWorld, -30.0f };
- float t = intersectSphere(origin, dir, center, radius);
- if (t > 0.0f) { // Ray hit.
- vec3 intersection = origin + (dir * t);
- vec3 normal = intersection - center;
- normal.normalize();
- vec3 lightDir = lightpos - intersection;
- lightDir.normalize();
- float lum = normal.dot(lightDir);
- if (lum < 0) {
- // Give some brightness even if pointing
- // completely away from the light.
- std::cout << colors[0];
- }
- else {
- // Pick character based on light calculation.
- std::cout << colors[(int)(sizeof(colors) * lum)];
- }
- }
- else { // Ray miss
- std::cout << " ";
- }
- }
- std::cout << "\n";
- }
- }
- int main() {
- HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
- // Hide cursor
- CONSOLE_CURSOR_INFO info;
- info.dwSize = 100;
- info.bVisible = FALSE;
- SetConsoleCursorInfo(console, &info);
- unsigned int frame = 0;
- while (true) {
- SetConsoleCursorPosition(console, { 0, 0 });
- update(frame++);
- draw();
- Sleep(16);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement