Sign in to follow this  
cignox1

Image class for raytracing advices

Recommended Posts

In the process of rewriting my raytracer from scratch, I'm try to find a good way to encapsulate images. What I'm thinking is a general interface that can be then implemented by bitmapped 24bit images, HDR images, animations and so on. Until now I thought to something like this:
	class QLImage
	{
	protected:
		unsigned int width, height;
		unsigned int frames;

	public:
		QLImage() : width(0), height(0), frames(0) {}

		//Accessors
		virtual unsigned int GetWidth() const { return width; }
		virtual unsigned int GetHeight() const { return height; }
		virtual unsigned int GetFramesCount() const { return frames; }

		//The following method interfaces must return false if the parameters are out of bounds
		virtual bool GetPixel(const Spectrum &value, unsigned int x, unsigned int y, unsigned int frame = 0) const = 0;
		virtual bool SetPixel(const Spectrum &value, unsigned int x, unsigned int y, unsigned int frame = 0) = 0;
		virtual bool GetRawPixel(const void* value, unsigned int x, unsigned int y, unsigned int frame = 0) const = 0;
		virtual bool SetRawPixel(const void* value, unsigned int x, unsigned int y, unsigned int frame = 0) = 0;
	};


My main concern is that the virtual methods and the fact that with this interface I have not the buffer available for fast lookup of multiple values (a specific GetPixel() call has to be made for each read) could be really heavy as far as performances goes. I'm open to suggestion about smarter ways to do this. NOTE: The spectrum class represents a color, but even while currently it is implemented as RGB, in the future I mighht change it to other color spaces or something completely different... EDIT: only now I notice that I left my topic without title. Fixed. [Edited by - cignox1 on February 29, 2008 5:29:46 PM]

Share this post


Link to post
Share on other sites
The way I have done it and seen it done many times is in addition to width and height, the base image class has a pixel depth or pitch with tells the user of the class how many bits or bytes each pixel takes. Also a format, which tells the user what format the buffer is in. Typically you have multiple formats even within the same image space. For example, you may have a 24bit image that is represented as R8G8B8 or R6G6B6A6.

I would recommend staying away from a get pixel call, as it will be the bottleneck in your system. It is better to have a GetData() method that returns a void* or char* to the raw data and then let the user of the class choose how they want to iterate over the data. This way performance and ease of use can be balanced on a case by case basis. By providing a pointer to the raw data, a pixel depth, and a format you are giving the user of the class all of the information they need to optimize it for their particular situation.

Drak

Share this post


Link to post
Share on other sites
Thank you, I'm not really concerned about the pixel layout (RGB, RGBA, BRG and so on) because I can always require vthat valid images always have a predefined layout. It's not also a problem the pixel depth. What I don't know is what kind of data is inside the picture (I don't even know if there is a buffer or if the image is calculated on demand, or if the data has to be loaded from other sources like files and so on. I can also think the image like a filter that simply returns the filtered value of the referenced image...
I suppose that I have to limit the flexibility of my class in order to keep reasonable performances...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this