#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include "object.h"
#include "intersect.h"
#include "perspective.h"
#include "point.h"
#include "ray.h"
#include "sphere.h"
#include "color.h"
#include "plane.h"
#include "material.h"
#include "checkmaterial.h"
#include "phong.h"
#include "Union.h"
#include "directlight.h"
#include "pointlight.h"
#define WIN_WIDTH 600
#define WIN_HEIGHT 600
static void key_callback(GLFWwindow *window,int key,int scancode,int action,int mods)
{
if(key==GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window,GL_TRUE);
}
void init(int w,int h)
{
glShadeModel(GL_SMOOTH);
glClearColor(0,0,0,0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
}
color recursive(object *scene,ray &r,long maxref)
{
intersect result = scene->isintersect(r);
if(result.ishit){
float reff;
color clr;
if(scene->getord()==1){
reff = scene->mat.getref();
clr = scene->mat.sample(r,result.pos,result.norm);
}
if(scene->getord()==2){
reff = scene->pmat.getref();
clr = scene->pmat.sample(r,result.pos,result.norm);
}
if(scene->getord()==3){
reff = scene->cmat.getref();
clr = scene->cmat.sample(r,result.pos,result.norm);
}
clr = clr.multi(1-reff);
if((reff>0)&&(maxref>0)){
point p = result.norm*(-2*result.norm.dotmul(r.getdir())) + r.getdir();
ray r = ray(result.pos,p);
color refclr = recursive(scene,r,maxref-1);
clr = clr.add(refclr.multi(reff));
}
return clr;
}
else
return color::black();
}
void renderlight(GLFWwindow *window)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-0.5f,-0.5f,-1.0f);
glPointSize(1.0);
perspective camera(point(0,10,10),point(0,0,-1),point(0,1,0),90);
plane *pl1=new plane(point(0,1,0),0.0);
plane *pl2=new plane(point(0,0,1),-50);
plane *pl3=new plane(point(1,0,0),-20);
sphere *s1=new sphere(point(0,10,-10),10.0);
Union scene;
scene.push(pl1);
scene.push(pl2);
scene.push(pl3);
scene.push(s1);
pointlight light2(color::white().multi(200),point(10,20,10),true);
directlight light1(color::white().multi(10),point(-1.75,-2,-1.5),true);
long maxdepth = 20;
float dx = 1.0f/WIN_WIDTH;
float dy = 1.0f/WIN_HEIGHT;
float dD = 255.0f/maxdepth;
glBegin(GL_POINTS);
for(long y = 0 ; y < WIN_HEIGHT ; y++){
float sy = 1 - dy * y;
for(long x = 0 ; x < WIN_WIDTH ; x++){
float sx = dx * x;
ray r(camera.getray(sx,sy));
intersect result = scene.isintersect(r);
if(result.ishit){
color clr = light1.inter(scene,result);
//color clr = light2.inter(scene,result);
//clr.saturate();
glColor3ub(clr.r*255,clr.g*255,clr.b*255);
glVertex2f(sx,sy);
}
}
}
glEnd();
glfwSwapBuffers(window);
}
void renderdepth(GLFWwindow *window)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-0.5f,-0.5f,-1.0f);
glPointSize(1.0);
perspective camera(point(0,10,10),point(0,-0.5,-1),point(0,1,0),90);
long maxdepth = 20;
long maxref = 5;
plane *pl=new plane(point(0,1,0),1.0);
sphere *s1=new sphere(point(-2,5,-2),4.0);
sphere *s2=new sphere(point(5,5,-7),3.0);
checkmaterial cm(0.1f,0.5f);
phong p1(phong(color::red(),color::white(),16,0.25));
phong p2(phong(color::blue(),color::white(),16,0.25));
pl->setcheck(cm);
s1->setphong(p1);
s2->setphong(p2);
Union scene;
scene.push(pl);
scene.push(s1);
scene.push(s2);
float dx = 1.0f/WIN_WIDTH;
float dy = 1.0f/WIN_HEIGHT;
float dD = 255.0f/maxdepth;
glBegin(GL_POINTS);
for(long y = 0 ; y < WIN_HEIGHT ; y++){
float sy = 1 - dy * y;
for(long x = 0 ; x < WIN_WIDTH ; x++){
float sx = dx * x;
ray r(camera.getray(sx,sy));
//intersect result = s1->isintersect(r);
intersect result = scene.isintersect(r);
if(result.ishit){
//color clr = s1->pmat.sample(r,result.pos,result.norm);
//color clr = scene.showmat(r,result);
color clr = scene.recursive(r,maxref,result);
//color clr = recursive(&scene,r,maxref);
clr.saturate();
glColor3ub(clr.r*255,clr.g*255,clr.b*255);
glVertex2f(sx,sy);
}
}
}
glEnd();
glfwSwapBuffers(window);
}
int main(void)
{
if(!glfwInit())
exit(EXIT_FAILURE);
GLFWwindow *window = glfwCreateWindow(WIN_WIDTH,WIN_HEIGHT,"learn",nullptr,nullptr);
if(window == nullptr)
{
glfwTerminate();
exit( EXIT_FAILURE );
}
//init(WIN_WIDTH,WIN_HEIGHT);
glfwMakeContextCurrent(window);
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.1f,0.1f,0.1f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSetKeyCallback(window,key_callback);
renderlight(window);
//renderdepth(window);
//glfwSwapBuffers(window);
}
glfwTerminate();
exit(EXIT_SUCCESS);
system("pause");
return 0;
}