⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raytrace.cpp

📁 file code.zip are used to implement ray tracing technology.
💻 CPP
字号:
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string>
using namespace std;
#include <gl/glut.h>
#include "scene.h"
#include "camera.h" 
#include <io.h>
Camera cam; // global camera object 
Scene scn;

// Window size and raster starting position
int windowWidth = 0;
int windowHeight = 0;
int rasterX = 0;
int rasterY = 0;
float amount = 1.0;
int blockSize =1;
string BMPfilename = "";
unsigned char* imgBuffer = NULL;

void myKeyboard(unsigned char key, int x, int y);
void reshapeScene(int width, int height);
void myDisplay();

// Has the scene been fully raytraced yet?
bool traced = false;

// Is the image buffer inverted (it is initially)?
bool inverted = true; 
bool roll = true;
//<<<<<<<<<<<<<<<<<<<<<< getFileName >>>>>>>>>>>>>>>>.
void getFileName(string& fname)
{ // display list of all .sdl files in current directory - needs #include <io.h>
	struct _finddata_t sdl_file;
	long hFile;
	if( (hFile = _findfirst("*.sdl", &sdl_file)) == -1L)
		 cout << " No *.sdl files in current directory!\n";
	else
	{
			cout << "Available *.sdl files\n";
			cout << "FILE NAME\t\tSIZE\n";
			cout << sdl_file.name << "\t\t"<< sdl_file.size << endl;
			while( _findnext( hFile, &sdl_file) == 0)
					cout << sdl_file.name <<"\t\t";
	}
	_findclose(hFile);
	cout << "type file name: (omit the '.sdl') \n";
	cin >> fname; // user types his/her choice
	fname += ".sdl"; //append suffix
}
//<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
int  main(int argc, char **argv) 
{ 
	// Variables for the command line parameters
	string fname;
	bool BMP_OUTPUT = false;
	bool OPENGL_OUT = false;
	bool DYNAMIC_OPENGL_OUT = false;
	size_t xRes = 640, yRes = 480;

	// Check that at least one type of output was specified.  If not, default to dynamic.
	if(!BMP_OUTPUT && !OPENGL_OUT && !DYNAMIC_OPENGL_OUT)
		DYNAMIC_OPENGL_OUT = true;

	// Read the SDL file
	scn.xRes = xRes;
	scn.yRes = yRes;
	scn.aspect = xRes/(double)yRes;
	getFileName(fname);
	scn.read(fname);

	// Build the camera
	
	cam.set(scn.eye, scn.lookAt, scn.up);
	cam.setShape(scn.angle, scn.aspect, scn.nearPlane, scn.farPlane);
	cam.setResolution(scn.yRes, scn.xRes);

	// Raytrace now if the output is not dynamic.
	if(!DYNAMIC_OPENGL_OUT)
	{
		imgBuffer = cam.raytrace(scn, blockSize, false);
		traced = true;
	}

	if(OPENGL_OUT || DYNAMIC_OPENGL_OUT)
	{
		// Draw the buffer to an OpenGL window
		windowWidth = scn.xRes;
		windowHeight = scn.yRes;

		glutInit(&argc, argv);
		glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
		glutInitWindowSize(windowWidth, windowHeight);
		glutInitWindowPosition(50, 50);
		glutCreateWindow("RayTracer");

		glutKeyboardFunc(myKeyboard);
		glutDisplayFunc(myDisplay);
		glutReshapeFunc(reshapeScene);

		// Display the buffer
		glutMainLoop();
	}

	// Clean up
	if(imgBuffer != NULL)
		delete [] imgBuffer;

	return 0;
}

void invertBuffer(unsigned char* &buffer)
{
	unsigned char* flippedBuffer = new unsigned char[scn.xRes*scn.yRes*3];

	// Turn the buffer upside down because BMP format stores it that way
    for(size_t i=0; i<scn.yRes; i++)
    {
        for(size_t j=0; j<scn.xRes; j++)
        {
            flippedBuffer[i*scn.xRes*3+3*j]   = buffer[(scn.yRes-1-i)*scn.xRes*3+3*j];
            flippedBuffer[i*scn.xRes*3+3*j+1] = buffer[(scn.yRes-1-i)*scn.xRes*3+3*j+1];
            flippedBuffer[i*scn.xRes*3+3*j+2] = buffer[(scn.yRes-1-i)*scn.xRes*3+3*j+2];
        }
    }

	// Replace original with the flipped version
	delete [] buffer;
	buffer = flippedBuffer;
}

// The GLUT keyboard callback function.  Processes key presses.
void myKeyboard(unsigned char key, int x, int y)
{
	switch(key){
		case 'r':
			inverted = true;
			break; 
		case 'a':
			cam.slide(0,0,-amount);
			
			break;
		case 'b':
			cam.slide(0,0,amount);
			
			break;
		default:
			cout<<"\n not a valid command\n";
	}
	glutPostRedisplay();
}

// This is the GLUT reshape callback function.  It is called whenever the window is reshaped
// and also when it is initially created.
void reshapeScene(int width, int height)
{
    windowWidth = width;
    windowHeight = height;

    rasterX = (int)floor(windowWidth/2.0 - scn.xRes/2.0);
    rasterY = (int)floor(windowHeight/2.0 - scn.yRes/2.0);

    if(rasterY < 0) rasterY = 0;
    if(rasterX < 0) rasterX = 0;

	glMatrixMode(GL_PROJECTION); glLoadIdentity();
	glMatrixMode(GL_MODELVIEW); glLoadIdentity();

	gluOrtho2D(0, width, 0, height);
    glViewport(0, 0, width, height);

	glutPostRedisplay();
}

// The GLUT display callback function.  Called everytime the window is to be redrawn.
void myDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if(!traced)
	{
		
			imgBuffer = cam.raytrace(scn, blockSize, true);
			if(imgBuffer == NULL) cerr << "Error: Image buffer is empty (possibly out of memory).\n";
			traced = true;
		
		
	}

	else if(imgBuffer != NULL)
	{
		// The BMP buffer is upside-down so invert it before displaying it
		if(inverted)
		{
			invertBuffer(imgBuffer);
			inverted = false;
		}
		glRasterPos2i(rasterX, rasterY);
		glDrawPixels(scn.xRes, scn.yRes, GL_RGB, GL_UNSIGNED_BYTE, imgBuffer);
		
	}
	

	glFlush();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -