Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.
Login
Login
OnlineGDB Q&A
Questions
Unanswered
Tags
Ask a Question
Ask a Question
How can I make a map or how can I even place a object like in Minecraft?
+9
votes
asked
Apr 24
by
Fitzwilliam Bragg
(
230
points)
Please
log in
or register to answer this question.
1 Answer
+1
vote
answered
May 1
by
BODE LADI-SOARES
(
190
points)
Hi! Online GDB is text-based
commented
May 2
by
Isaac Starr
(
110
points)
While Online GDB is text-based you can make 3d rendering I made a CPU based raytracer that generates a single frame when you run it. Being text-based isn't the limiting factor. Frame Rate is XD. Here's the code if your curious.
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <limits>
const int width = 60;
const int height = 60;
struct Vec3
{
float x, y, z;
//add
Vec3 operator+(const Vec3& other) const
{
return { x + other.x, y + other.y, z + other.z };
}
//sub
Vec3 operator-(const Vec3& other) const
{
return { x - other.x, y - other.y, z - other.z };
}
//scalar
Vec3 operator*(float scalar) const
{
return { x * scalar, y * scalar, z * scalar };
}
//dot product
float dot(const Vec3& other) const
{
return (x * other.x) + (y * other.y) + (z * other.z);
}
float length()
{
return std::sqrt(x * x + y * y + z * z);
}
Vec3 normalize() const
{
float mag = std::sqrt(x * x + y * y + z * z);
if (mag > 0)
{
return { x / mag, y / mag, z / mag };
}
return { 0, 0, 0 };
}
};
struct Color
{
int r, g, b;
void clamp(int min, int max)
{
if (r < min)
r = min;
if (r > max)
r = max;
if (g < min)
g = min;
if (g > max)
g = max;
if (b < min)
b = min;
if (b > max)
b = max;
}
};
struct Ray
{
Vec3 origin;
Vec3 direction;
};
struct Sphere
{
Vec3 pos;
float radius;
Color color;
};
float hitSphere(const Ray& ray, const Vec3& center, float radius)
{
Vec3 oc = ray.origin - center;
float a, b, c;
a = 1.0f;
b = 2 * ray.direction.dot(oc);
c = oc.dot(oc) - radius * radius;
float discriminant = b * b - 4 * a * c;
if (discriminant < 0)
{
return -1;
}
else
{
float t1 = (-b - sqrt(discriminant)) / (2 * a);
float t2 = (-b + sqrt(discriminant)) / (2 * a);
return (t1 < t2) ? t1 : t2;
}
}
bool inShadow(const Ray& shadowRay, const std::vector<Sphere>& spheres, float distToLight)
{
for (Sphere sphere : spheres)
{
float nextT = hitSphere(shadowRay, sphere.pos, sphere.radius);
if (nextT > 0 && nextT < distToLight)
return true;
}
return false;
};
int main()
{
Vec3 lightPos = { -2, -2, -1 };
std::vector<Sphere> spheres =
{
{ {0, 0, -3}, 1, { 255, 0, 0 }},
{ {1.5, -0.5, -4}, 1, { 0 , 255, 0 } }
};
float aspect = (float)width / height;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
float u = ((j - 0) * (2.0f) / (width - 1)) + -1;
u *= aspect;
float v = ((i - 0) * (2.0f) / (height - 1)) + -1;
Ray ray = { { 0, 0, 0 }, Vec3{ u, v, -1 }.normalize() };
float t = std::numeric_limits<float>::infinity();
Sphere s = { { 0, 0, 0 }, 0 }; //the sphere it hit
bool somethingWasHit = false;
for (Sphere sphere : spheres)
{
float nextT = hitSphere(ray, sphere.pos, sphere.radius);
if (nextT > 0 && nextT < t)
{
t = nextT;
s = sphere;
somethingWasHit = true;
}
}
if (t < 0 || !somethingWasHit)
{
Color c = { 0, 0, 0 };
std::cout << "\033[48;2;" << c.r << ";" << c.g << ";" << c.b << "m \033[0m";
}
else
{
Vec3 hitPoint = ray.origin + ray.direction * t;
Vec3 normal = (hitPoint - s.pos).normalize();
Color sphereColor = s.color;
Vec3 lightDir = (lightPos - hitPoint).normalize();
Ray shadowRay = { hitPoint + normal * 0.001f, lightDir };
float distToLight = (lightPos - hitPoint).length();
float brightness = 0;
if (!inShadow(shadowRay, spheres, distToLight))
brightness = normal.dot(lightDir);
sphereColor.r *= brightness;
sphereColor.g *= brightness;
sphereColor.b *= brightness;
sphereColor.clamp(5, 255);
std::cout << "\033[48;2;" << sphereColor.r << ";" << sphereColor.g << ";" << sphereColor.b << "m \033[0m";
}
}
std::cout << std::endl;
}
return 0;
}
commented
May 4
by
DAVEY - CAELAN YEPWI
(
250
points)
On line 98,there is an invalid decimal literal and it marks out the 0 in this line of code : a = 1.0f;
commented
May 4
by
Zach
(
380
points)
Here's a fixed and optimized version:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <limits>
#include <sstream>
const int width = 60;
const int height = 60;
struct Vec3 {
float x, y, z;
// add
Vec3 operator+(const Vec3& other) const {
return { x + other.x, y + other.y, z + other.z };
}
// sub
Vec3 operator-(const Vec3& other) const {
return { x - other.x, y - other.y, z - other.z };
}
// scalar
Vec3 operator*(float scalar) const {
return { x * scalar, y * scalar, z * scalar };
}
// dot product
float dot(const Vec3& other) const {
return (x * other.x) + (y * other.y) + (z * other.z);
}
float length() {
return sqrt(x * x + y * y + z * z);
}
Vec3 normalize() const {
float mag = sqrt(x * x + y * y + z * z);
if (mag > 0) {
return ((*this) * (1 / mag));
}
return { 0, 0, 0 };
}
};
void clampNum(int* value, int min, int max) {
if (*value > max) (*value) = max;
if (*value < min) (*value) = min;
}
struct Color {
int r, g, b;
void clamp(int min, int max) {
clampNum(&r, min, max);
clampNum(&g, min, max);
clampNum(&b, min, max);
}
void mult(float scalar) {
r = (int)(r * scalar);
g = (int)(g * scalar);
b = (int)(b * scalar);
}
std::string toString() {
std::ostringstream oss; // just so it isn't a pain later
oss << "\033[48;2;" << r << ";" << g << ";" << b << "m";
return oss.str();
}
};
struct Ray {
Vec3 origin;
Vec3 direction;
};
struct Sphere {
Vec3 pos;
float radius;
Color color;
};
float hitSphere(const Ray& ray, const Vec3& center, float radius) {
Vec3 oc = ray.origin - center;
float a = 1.0f, b = 2 * ray.direction.dot(oc), c = oc.dot(oc) - radius * radius;
float discriminant = b * b - 4 * a * c;
return discriminant >= 0 ? std::min((-b - sqrt(discriminant)) / (2 * a), (sqrt(discriminant) - b) / (2 * a)) : -1;
}
bool inShadow(const Ray& shadowRay, const std::vector<Sphere>& spheres, float distToLight) {
for (Sphere sphere : spheres) {
float nextT = hitSphere(shadowRay, sphere.pos, sphere.radius);
if (nextT > 0 && nextT < distToLight) return true;
}
return false;
};
int main() {
Vec3 lightPos = { -2, -2, -1 };
std::vector<Sphere> spheres = {
{ {0, 0, -3}, 1, { 255, 0, 0 }},
{ {1.5, -0.5, -4}, 1, { 0, 255, 0 } }
};
float aspect = (float)width / height;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
float u = (j * 2.0f) / (width - 1) - 1;
u *= aspect;
float v = (i * 2.0f) / (height - 1) - 1;
Ray ray = { { 0, 0, 0 }, Vec3{ u, v, -1 }.normalize() };
float t = std::numeric_limits<float>::infinity();
Sphere s = { { 0, 0, 0 }, 0 }; // the sphere it hit
bool somethingWasHit = false;
for (Sphere sphere : spheres) {
float nextT = hitSphere(ray, sphere.pos, sphere.radius);
if (nextT > 0 && nextT < t) {
t = nextT;
s = sphere;
somethingWasHit = true;
}
}
if (t < 0 || !somethingWasHit) std::cout << " ";
else {
Vec3 hitPoint = ray.origin + ray.direction * t;
Vec3 normal = (hitPoint - s.pos).normalize();
Color sphereColor = s.color;
Vec3 lightDir = (lightPos - hitPoint).normalize();
Ray shadowRay = { hitPoint + normal * 0.001f, lightDir };
float distToLight = (lightPos - hitPoint).length();
sphereColor.mult(!inShadow(shadowRay, spheres, distToLight) ? normal.dot(lightDir) : 0);
sphereColor.clamp(5, 255);
std::cout << sphereColor.toString() << " \033[0m";
}
}
std::cout << std::endl;
}
return 0;
}
Please
log in
or register to add a comment.
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and receive answers from other members of the community.
...