User Tools

Site Tools


keckcaves:threaded_rendering

Threaded Rendering

// threaded rendering with vrui
// sean whalen, 03-2009 (updated 09-2009) 
 
#include <stdlib.h>
#include <vector>
 
#include <Geometry/Random.h>
#include <GL/GLContextData.h>
#include <GL/GLGeometryWrappers.h>
#include <Threads/Mutex.h>
#include <Threads/Thread.h>
#include <Vrui/Vrui.h>
#include <Vrui/Application.h>
#include <Vrui/Geometry.h>
 
#define RADIUS 10
#define NUM_POINTS 12
 
using namespace std;
 
class ThreadExample : public Vrui::Application, public GLObject
{
private:
	struct DataItem : public GLObject::DataItem
	{
		GLuint displayList;
		int displayListVersion;
 
		DataItem()
		{
			displayList = glGenLists(1);
			displayListVersion = 0;
		}
 
		~DataItem()
		{
			glDeleteLists(displayList, 1);
		}
	};
 
	int displayListVersion;
	vector<Vrui::Point> pointsWrite;
	vector<Vrui::Point> pointsRead;
	Vrui::Point min;
	Vrui::Point max;
 
	Threads::Thread layoutThread;
	Threads::Mutex mutex;
	bool stopped;
 
public:
	ThreadExample(int, char**, char**);
	~ThreadExample();
 
	void display(GLContextData&) const;
	void frame();
	void initContext(GLContextData&) const;
	void* threadMethod();
};
 
ThreadExample::ThreadExample(int argc, char** argv, char** appDefaults)
: Vrui::Application(argc, argv, appDefaults)
{
	displayListVersion = 0;
	min = Vrui::Point(-RADIUS, -RADIUS, -RADIUS);
	max = Vrui::Point(RADIUS, RADIUS, RADIUS);
 
	for(int i = 0; i < NUM_POINTS; i++)
	{
		Vrui::Point p = Geometry::randPointUniformCO(min, max);
		pointsWrite.push_back(p);
	}
 
	Vrui::setNavigationTransformation(Vrui::Point(0, 0, 0), 25.0);
 
	stopped = false;
	layoutThread.start(this, &ThreadExample::threadMethod);
}
 
ThreadExample::~ThreadExample()
{
	stopped = true;
}
 
void ThreadExample::initContext(GLContextData& contextData) const
{
	DataItem* dataItem = new DataItem;
	contextData.addDataItem(this, dataItem);
}
 
void ThreadExample::display(GLContextData& contextData) const
{
	DataItem* dataItem = contextData.retrieveDataItem<DataItem>(this);
	glPointSize(3);
 
	if(dataItem->displayListVersion != displayListVersion)
	{
		glNewList(dataItem->displayList, GL_COMPILE);
			glBegin(GL_POINTS);
			glColor3f(0, 255, 0);
 
			for(int i = 0; i < NUM_POINTS; i++)
			{
				glVertex(pointsRead[i]);
			}
 
			glEnd();
		glEndList();
 
		dataItem->displayListVersion = displayListVersion;
	}
 
	glCallList(dataItem->displayList);
}
 
void ThreadExample::frame()
{
	mutex.lock();
 
	pointsRead = pointsWrite;
	displayListVersion++;
 
	mutex.unlock();
	Vrui::requestUpdate();
}
 
void* ThreadExample::threadMethod()
{
	while(!stopped)
	{
		mutex.lock();
 
		for(int i = 0; i < NUM_POINTS; i++)
		{
			pointsWrite[i] = Geometry::randPointUniformCO(min, max);
		}
 
		mutex.unlock();
	}
 
	return 0;
}
 
int main(int argc, char** argv)
{
	char** appDefaults = 0;
	ThreadExample app(argc, argv, appDefaults);
	app.run();
 
	return 0;	
}
keckcaves/threaded_rendering.txt · Last modified: 2009/10/16 14:30 by 76.20.60.65