Click here to Skip to main content
15,885,767 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am trying to use OpenGL to display the result of my rendering engine but I get a blank screen with no display. Below is my main c++ file with OpenGL calls and the file with the rendering engine. Please what am I doing wrongly. The original raytracing by Jacco Bikker displays the result alright using Windows API (WinMain), the problem I have with that is that while trying to parallelize the code using cilk++ it will not work with WinMain() method. It only works with main() method in c++ that is why am using OpenGL to display.
Please anyone there who can help me out...I deeply appreciate it. Below is the main c++ file where the OpenGL calls are made:

C++
#define _CRT_SECURE_NO_WARNINGS
 
#include <windows.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "common.h"
#include "raytracer.h"
#include "scene.h"
#include "surface.h"
#include "cilk.h"
#include "cilkview.h"
#include <cstdio>
#include <cassert>
#include <vector>

//#define SCRWIDTH 640
//#define SCRHEIGHT 480
#define SCRWIDTH 800
#define SCRHEIGHT 600
 
GLuint texture = 0;
Raytracer::Surface* surface = 0;
Pixel* buffer = 0;
Raytracer::Engine* tracer = 0;
 

void start(){
	// prepare output canvas
	surface = new Raytracer::Surface( SCRWIDTH, SCRHEIGHT );
	buffer = surface->GetBuffer();
	surface->Clear( 0 );
	surface->InitCharset();
	surface->Print( "timings:", 2, 2, 0xffffffff );
	// prepare renderer
	tracer = new Raytracer::Engine();
	tracer->GetScene()->InitScene();
	tracer->SetTarget( surface->GetBuffer(), SCRWIDTH, SCRHEIGHT );
int tpos = 60;
 
	
		 FILE *outFile;
 
		   outFile = fopen("RayTracing.out","a");
		   if (!outFile){
			   printf("Cannot open output file");
			   exit(1);
		   }
 
	//Displaying the Trace Depth to output file
	fprintf (outFile, "Tracing Depth : %d\n", TRACEDEPTH);
 
	// go
	while (1)
	{
		int fstart = GetTickCount();
		tracer->InitRender();
		while (!tracer->Render()) glutSwapBuffers();
		int ftime = GetTickCount() - fstart;
		char t[] = "00:00.000";
		t[6] = (ftime / 100) % 10 + '0';
		t[7] = (ftime / 10) % 10 + '0';
		t[8] = (ftime % 10) + '0';
		int secs = (ftime / 1000) % 60;
		int mins = (ftime / 60000) % 100;
		t[3] = ((secs / 10) % 10) + '0';
		t[4] = (secs % 10) + '0';
		t[1] = (mins % 10) + '0';
		t[0] = ((mins / 10) % 10) + '0';
 
		float par_time = ftime / 1000.f;	//Time accumulated is converted to seconds and stored in a variable
			
		fprintf (outFile, "%.3f\n", par_time);
		fflush (stdout);
		surface->Print( t, tpos, 2, 0xffffffff );
		tpos += 100;
	}
}
void render(void) {
	start();
	glClear(GL_COLOR_BUFFER_BIT);
	glRasterPos2i(0, 0);
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, texture);
	glDrawPixels(SCRWIDTH, SCRHEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, 0);
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
 
	glutSwapBuffers();
	glutPostRedisplay();
 
	
}
 
void reshape(int x, int y) {
	glViewport(0, 0, x, y);
 
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0); 
}
 

 
void appInit(int w, int h) {
	glGenBuffersARB(1, &texture);
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, texture);
	glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, w * h * sizeof(GLubyte) * 4, 0, GL_STREAM_DRAW_ARB);
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
 
		
}
 

void idle() { glutPostRedisplay(); }
 

void cleanup(){
	glDeleteBuffersARB(1, &texture);
}
 
int main(int argc, char **argv) {
	
	atexit(cleanup);
	glutInit(&argc, argv);
 
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(SCRWIDTH, SCRHEIGHT);
	glutCreateWindow("Cilk Plus raytracer");
 
	glewInit();
	appInit(SCRWIDTH, SCRHEIGHT);
	glutDisplayFunc(render);
	glutIdleFunc(idle);
	glutReshapeFunc(reshape);
 
	glutMainLoop();
 
	return 0;
}


The raytracing engine is in the following file:

raytracer.cpp

C++
// -----------------------------------------------------------
// raytracer.cpp
// 2004 - Jacco Bikker - jacco@bik5.com - www.bik5.com -   <><
// -----------------------------------------------------------

#include "raytracer.h"
#include "scene.h"
#include "common.h"
#include "windows.h"
#include "winbase.h"
#include "cilk.h"

 
namespace Raytracer {
 
Ray::Ray( vector3& a_Origin, vector3& a_Dir ) : 
	m_Origin( a_Origin ), 
	m_Direction( a_Dir )
{
}
 
Engine::Engine()
{
	m_Scene = new Scene();
}
 
Engine::~Engine()
{
	delete m_Scene;
}
 
// -----------------------------------------------------------
// Engine::SetTarget
// Sets the render target canvas
// -----------------------------------------------------------
void Engine::SetTarget( Pixel* a_Dest, int a_Width, int a_Height )
{
	// set pixel buffer address & size
	m_Dest = a_Dest;
	m_Width = a_Width;
	m_Height = a_Height;
}
 
// -----------------------------------------------------------
// Engine::Raytrace
// Naive ray tracing: Intersects the ray with every primitive
// in the scene to determine the closest intersection
// -----------------------------------------------------------
Primitive* Engine::Raytrace( Ray& a_Ray, Color& a_Acc, int a_Depth, float a_RIndex, float& a_Dist )
{
	if (a_Depth > TRACEDEPTH) return 0;
	// trace primary ray
	a_Dist = 1000000.0f;
	vector3 pi;
	Primitive* prim = 0;
	int result;
	// find the nearest intersection
	for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
	{
		Primitive* pr = m_Scene->GetPrimitive( s );
		int res;
		if (res = pr->Intersect( a_Ray, a_Dist )) 
		{
			prim = pr;
			result = res; // 0 = miss, 1 = hit, -1 = hit from inside primitive
		}
	}
	// no hit, terminate ray
	if (!prim) return 0;
		// ---- Handle intersection ----
	if (prim) {
		// Update statistics
		//m_statisticsDataStructCpp->rayIntersectionsCount[0]++;
		if (prim->IsLight())
		{
			// we hit a light, stop tracing
			a_Acc =Color( 1.0f, 1.0f, 1.0f );
		}
		else
		{
			// determine color at point of intersection
			pi = a_Ray.GetOrigin() + a_Ray.GetDirection() * a_Dist;
			// trace lights
			for ( int l = 0; l < m_Scene->GetNrPrimitives(); l++ )
			{
				Primitive* p = m_Scene->GetPrimitive( l );
 
				if (p->IsLight()) 
				{
					Primitive* light = p;
						// handle point light source
						float shade = 1.0f;
						if (light->GetType() == Primitive::SPHERE)
						{
							vector3 L = ((Sphere*)light)->GetCentre() - pi;
							float tdist = LENGTH( L );
							NORMALIZE(L);
							vector3 TempVector3(pi + L * EPSILON);
							Ray r = Ray( TempVector3, L );
							for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
							{
								Primitive* pr = m_Scene->GetPrimitive( s );						
								if ((pr != light) && (pr->Intersect( r, tdist )))
								{
									shade = 0;
									break;
								}
							}
						}
						if (shade > 0)
						{
							vector3 L = ((Sphere*)light)->GetCentre() - pi;
							NORMALIZE( L );
							vector3 N = prim->GetNormal( pi );
							// determine diffuse component
							if (prim->GetMaterial()->GetDiffuse() > 0)
							{
								float dot = DOT( L, N );
								if (dot > 0)
								{
									float diff = dot * prim->GetMaterial()->GetDiffuse() * shade;
									// add diffuse component to ray color
									Color ncol = diff * prim->GetMaterial()->GetColor();
									// Scale back the color, if necessary
									if (ncol.r > 1.0f || ncol.g > 1.0f || ncol.b > 1.0f)
									{
										float max = 1.0f;
										if (ncol.r > max) max = ncol.r;
										if (ncol.g > max) max = ncol.g;
										if (ncol.b > max) max = ncol.b;
										ncol *= 1.0f/max;
									}
									a_Acc += ncol;
								}
							}
							// determine specular component
							if (prim->GetMaterial()->GetSpecular() > 0)
							{
								// point light source: sample once for specular highlight
								vector3 V = a_Ray.GetDirection();
								vector3 R = L - 2.0f * DOT( L, N ) * N;
								float dot = DOT( V, R );
								if (dot > 0)
								{
									float spec = powf( dot, 20 ) * prim->GetMaterial()->GetSpecular() * shade;
									// add specular component to ray color
									Color ncol = spec * light->GetMaterial()->GetColor();
									// Adjust specular component to be within 0 <-> 1.0
									if (ncol.r > 1.0f) ncol.r = 1.0f; else if (ncol.r < 0.0f) ncol.r = 0.0f;
									if (ncol.g > 1.0f) ncol.g = 1.0f; else if (ncol.g < 0.0f) ncol.g = 0.0f;
									if (ncol.b > 1.0f) ncol.b = 1.0f; else if (ncol.b < 0.0f) ncol.b = 0.0f;
									a_Acc += ncol;								
								}
							}
						}
					}
				}
			// Scale back the local color contribution, if necessary
			if (a_Acc.r > 1.0f || a_Acc.g > 1.0f || a_Acc.b > 1.0f)
			{
				float max = 1.0f;
				if (a_Acc.r > max) max = a_Acc.r;
				if (a_Acc.g > max) max = a_Acc.g;
				if (a_Acc.b > max) max = a_Acc.b;
				a_Acc *= 1.0f/max;
			}
			// -- Calculate reflection --
			float refl = prim->GetMaterial()->GetReflection();
			if ((refl > 0.0f) && (a_Depth < TRACEDEPTH))
			{
				vector3 N = prim->GetNormal( pi );
				vector3 R = a_Ray.GetDirection() - 2.0f * DOT( a_Ray.GetDirection(), N ) * N;
				Color rcol( 0.0f, 0.0f, 0.0f );
				float dist;
				vector3 TempVector3(pi + R * EPSILON);
				Ray TempRay(TempVector3, R);
				Raytrace( TempRay, rcol, a_Depth + 1, a_RIndex, dist );
				a_Acc += refl * rcol;
			}
		}
	}
	else {
		// -- No intersection occured; stop tracing --
		// Update statistics
		//m_statisticsDataStructCpp->rayMissesCount[0]++;
		// Do nothing
	}
	
	// return pointer to primitive hit by primary ray
	return prim;
}
 
// -----------------------------------------------------------
// Engine::InitRender
// Initializes the renderer, by resetting the line / tile
// counters and precalculating some values
// -----------------------------------------------------------
void Engine::InitRender()
{
	// set firts line to draw to
	m_CurrLine = 20;
	// set pixel buffer address of first pixel
	m_PPos = 20 * m_Width;
	// screen plane in world space coordinates
	m_WX1 = -4, m_WX2 = 4, m_WY1 = m_SY = 3, m_WY2 = -3;
	// calculate deltas for interpolation
	m_DX = (m_WX2 - m_WX1) / m_Width;
	m_DY = (m_WY2 - m_WY1) / m_Height;
	m_SY += 20 * m_DY;
	// allocate space to store pointers to primitives for previous line
	m_LastRow = new Primitive*[m_Width];
	memset( m_LastRow, 0, m_Width * 4 );
	// statistics
	m_RayMissesCount = 0;
	m_RayIntersectionsCount = 0;
}
 
void Engine::PreRender() {
	// Prepare linearized data
	m_spheres.clear();
	m_planes.clear();
	Sphere* tempSphere;
	PlanePrim* tempPlane;
	int sphereCount;	
	int planesCount;
	Primitive* prim;
	for (int i = 0; i < m_Scene->GetNrPrimitives(); i++) {
		prim = m_Scene->GetPrimitive(i);
 
		tempSphere = dynamic_cast<Sphere*> (prim);
		if (dynamic_cast<Sphere*> (prim) != 0){
			m_spheres.push_back(tempSphere);
//			continue;
		}
		tempPlane = dynamic_cast<PlanePrim*> (prim);
		if (dynamic_cast<PlanePrim*> (prim) != 0)
			m_planes.push_back(tempPlane);
	}
	
	
	// Spheres
	m_sphereDataStructCpp = new SphereDataStructCpp(m_spheres.size());
	
	for (int i = 0; i < m_spheres.size(); i++)	{
		tempSphere = m_spheres[i];
		// Geometric Data
		m_sphereDataStructCpp->centerX[i] = tempSphere->GetCentre().x;
		m_sphereDataStructCpp->centerY[i] = tempSphere->GetCentre().y;
		m_sphereDataStructCpp->centerZ[i] = tempSphere->GetCentre().z;
		m_sphereDataStructCpp->recRadius[i] = tempSphere->GetRecRadius();
		m_sphereDataStructCpp->sqRadius[i] = tempSphere->GetSqRadius();
		// Material Data
		m_sphereDataStructCpp->diffuse[i] = tempSphere->GetMaterial()->GetDiffuse();
		m_sphereDataStructCpp->specular[i] = tempSphere->GetMaterial()->GetSpecular();
		m_sphereDataStructCpp->reflection[i] = tempSphere->GetMaterial()->GetReflection();
		m_sphereDataStructCpp->refraction[i] = tempSphere->GetMaterial()->GetRefraction();
		m_sphereDataStructCpp->refrIndex[i] = tempSphere->GetMaterial()->GetRefrIndex();
		// Color Data
		m_sphereDataStructCpp->red[i] = tempSphere->GetMaterial()->GetColor().r;
		m_sphereDataStructCpp->green[i] = tempSphere->GetMaterial()->GetColor().g;
		m_sphereDataStructCpp->blue[i] = tempSphere->GetMaterial()->GetColor().b;
		// Light?
		m_sphereDataStructCpp->isLight[i] = tempSphere->IsLight();
	}
	
	// Planes

	m_planeDataStructCpp = new PlaneDataStructCpp(m_planes.size());
	
	for (int i = 0; i < m_planes.size(); i++)	{
		tempPlane = m_planes[i];
		// Geometric data
		m_planeDataStructCpp->normalX[i] = tempPlane->GetNormal().x;
		m_planeDataStructCpp->normalY[i] = tempPlane->GetNormal().y;
		m_planeDataStructCpp->normalZ[i] = tempPlane->GetNormal().z;
		m_planeDataStructCpp->d[i] = tempPlane->GetD();
		// Material data
		m_planeDataStructCpp->diffuse[i] = tempPlane->GetMaterial()->GetDiffuse();
		m_planeDataStructCpp->specular[i] = tempPlane->GetMaterial()->GetSpecular();
		m_planeDataStructCpp->reflection[i] = tempPlane->GetMaterial()->GetReflection();
		m_planeDataStructCpp->refraction[i] = tempPlane->GetMaterial()->GetRefraction();
		m_planeDataStructCpp->refrIndex[i] = tempPlane->GetMaterial()->GetRefrIndex();
		// Color data
		m_planeDataStructCpp->red[i] = tempPlane->GetMaterial()->GetColor().r;
		m_planeDataStructCpp->green[i] = tempPlane->GetMaterial()->GetColor().g;
		m_planeDataStructCpp->blue[i] = tempPlane->GetMaterial()->GetColor().b;
		// Light data
		m_planeDataStructCpp->isLight[i] = tempPlane->IsLight();
	}
	
	// Statistics
	m_RayMissesCount = 0;
	m_RayIntersectionsCount = 0;
	
	m_statisticsDataStructCpp = new StatisticsDataStructCpp((size_t)m_CohortPSize);
	
		
}
 
// -----------------------------------------------------------
// Engine::Render
// Fires rays in the scene one scanline at a time, from left
// to right
// -----------------------------------------------------------
bool Engine::Render()
{
	// render scene
	vector3 o( 0, 0, -5 );
	// initialize timer
	int msecs = GetTickCount();
	// reset last found primitive pointer
	Primitive* lastprim = 0;
	// render remaining lines
	for ( int y = m_CurrLine; y < (m_Height - 20); y++ )
	{
		m_SX = m_WX1;
		// render pixels for current line
		for ( int x = 0; x < m_Width; x++ )
		{
			// fire primary ray
			Color acc( 0, 0, 0 );
			vector3 dir = vector3( m_SX, m_SY, 0 ) - o;
			NORMALIZE( dir );
			Ray r( o, dir );
			float dist;
			Primitive* prim = Raytrace( r, acc, 1, 1.0f, dist );
			int red = (int)(acc.r * 256);
			int green = (int)(acc.g * 256);
			int blue = (int)(acc.b * 256);
			if (red > 255) red = 255;
			if (green > 255) green = 255;
			if (blue > 255) blue = 255;
			m_Dest[m_PPos++] = (red << 16) + (green << 8) + blue;
			m_SX += m_DX;
		}
		
		m_SY += m_DY;
		// see if we've been working to long already
		if ((GetTickCount() - msecs) > 100) 
		{
			// return control to windows so the screen gets updated
			m_CurrLine = y + 1;
			return false;
		}
		
	}
	// all done
	return true;
}
 
}; // namespace Raytracer
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900