?? raytrace.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 + -