zoukankan      html  css  js  c++  java
  • 针对单个球体的World类

    好了,终于到了可以看到图片的环节了。之前的类,你一定要实现好了。所有关于World类的报错,现在我们一个一个解决来了。

    先看看World类的声明:

    #pragma once
    #ifndef __WORLD_HEADER__
    #define __WORLD_HEADER__
    
    #include "geometry.h"
    #include "viewplane.h"
    #include "../objects/primitive/sphere.h"
    #include "../tracers/tracer.h"
    
    class World {
    public:
    	World();
    	World(const World& wr);
    	~World();
    	void build();//初始化数据
    	void render();//渲染
    	void add_object(Geometrics* obj);//添加几何对象
    	void remove_object(Geometrics* obj);//删除几何对象
    	integer get_object_size() const;//几何对象个数,这个在SingleSphere类中用到了哈
    	ShadeRec hit_bare_bones_objects(const Ray& ray);
    private:
    	void open_window(const integer hres, const integer vres);//初始化视窗,有条件的可以用DirectX或者OpenGL显示,我这里用ppm文件显示
    	void display_pixel(const integer row, const integer column, const RGBColor& color);//写入像素
    	std::stringstream ss;//缓存
    	std::vector<Geometrics*> objects;
    	ViewPlane vp;//视窗类
    	RGBColor backgrd_color;//背景色
    	Tracer* tracer_ptr;//光线和几何对象的碰撞
    };
    #endif
    

      

    类实现:

    #include "pch.h"
    #include "world.h"
    #include "../tracers/singlesphere.h"
    
    World::World():tracer_ptr(nullptr) {}
    
    World::~World() {//写入到ppm文件
    	std::ofstream fout;
    	fout.open("test.ppm", std::ios::out);
    	fout.write(ss.str().c_str(), ss.str().size());
    	fout.close();
    }
    
    World::World(const World& wr)
    	: vp(wr.vp), backgrd_color(wr.backgrd_color), tracer_ptr(wr.tracer_ptr) {
    	objects.clear();
    }
    
    void World::build() {
    	vp.set_hres(200);
    	vp.set_vres(100);//200*100像素图片
    	tracer_ptr = new SingleSphere(this);
    	Geometrics* obj = new Sphere(0, 0.5);
    	obj->set_color(RGBColor(1, 0, 0));//球体颜色是红色
    	add_object(obj);
    }
    
    void World::render() {
    	Ray ray;
    	ldouble x, y;
    	open_window(vp.hres, vp.vres);
    	Point3 sp;
    	ray.o = Point3(0, 0, 1);//光线源位置
    	for (integer r = vp.vres - 1; r >= 0; r--)//render from left-corner to right-corner, 书上是错误的,必须这样渲染,不然图像是颠倒的
    		for (integer c = 0; c < vp.hres; c++) {
    			RGBColor color;
    			x = vp.s * (c - 0.5 * vp.hres);
    			y = vp.s * (r - 0.5 * vp.vres);
    			ray.d = Point3(x, y, -1);//只需要改变光线的方向
    			color = tracer_ptr->trace_ray(ray);
    			display_pixel(r, c, color);
    		}
    }
    
    void World::add_object(Geometrics* obj) {
    	objects.push_back(obj);
    }
    
    void World::remove_object(Geometrics* obj) {
    	for (auto it = objects.begin(); it != objects.end(); it++)
    		if ((*it) == obj)
    			objects.erase(it);
    }
    
    integer World::get_object_size() const {
    	return objects.size();
    }
    
    ShadeRec World::hit_bare_bones_objects(const Ray& ray) {//这个就是经常出现在SingleSphere和MultiSphere类中的函数了
    	ShadeRec sr(*this);
    	ldouble t, tmin= std::numeric_limits<ldouble>::max();
    	for (auto obj : objects)
    		if (obj->hit(ray, t, sr) && t < tmin) {
    			sr.hit_an_object = true;
    			tmin = t;
    			sr.color = obj->get_color();//保存碰撞后的颜色
    		}
    	return sr;
    }
    
    void World::open_window(const integer hres, const integer vres) {
    	ss.clear();
    	ss << "P3
    " << hres << " " << vres << "
    255
    ";//ppm文件头
    }
    
    void World::display_pixel(const integer row, const integer column, const RGBColor& color) {
    	RGBColor c = color;
    	if (vp.g != 1.0)
    		c = color.powc(vp.g);
    	integer ir = (integer)(255.99 * c.r),
    		ig = (integer)(255.99 * c.g),
    		ib = (integer)(255.99 * c.b);
    	ss << ir << " " << ig << " " << ib << "
    ";//写入颜色值
    }
    

    好了,现在我们看下main函数的调用吧(以后main函数的调用都是一样的,所以不再重复了)

    #include "../Common/RayTracingGroundUp/utilities/world.h"
    
    int main() {
    	World w;
    	w.build();
    	w.render();
    	return 0;
    }

    得到的图像如下(因为我是mac电脑下开的win7虚拟机,所以mac自带读取ppm文件,如果你的win7不能打开,请用photoshop等作图软件打开就行了),终于成功了:

  • 相关阅读:
    JQuery Ajax调用asp.net后台方法
    使用NuGet发布自己的类库包(Library Package)
    Database Schema Reader
    DELL服务器引导光盘图片及下载链接
    android 点击屏幕关闭 软键盘
    xUtils
    fastjson是阿里巴巴的开源JSON解析库
    安卓学习资料
    DELL服务器引导光盘下载
    sqlserver下载
  • 原文地址:https://www.cnblogs.com/dalgleish/p/12602738.html
Copyright © 2011-2022 走看看