// © Copyright 2008 Vladimir Frolov, Moscow State University Graphics & Media Lab
#pragma once

#include "IGraphicsEngine.h"
//#include "Common_Graphics_Engine.h"
#include "Ray_Tracer.h"


using namespace MGML_ERROR;

class DLL_API GPU_Ray_Tracer: public Ray_Tracer // ,public Singleton
{
	typedef Ray_Tracer Base;

public:

  GPU_Ray_Tracer(int w, int h);
	~GPU_Ray_Tracer();

	void BeginDrawScene(unsigned int trace_depth, bool shadows);			// account multithreading
	void EndDrawScene();			// account multithreading

  void BeginDrawScene(const Ray3f* a_rays, int a_maxSize, int a_traceDepth, bool a_shadows);	
  void GetColorsToBuffer(vec4f* a_colors, int a_maxSize);			                  

	void BuildAccelerationStructures(uint in_maxNodes = MAX_KD_TREE_NODES);

	void SetActiveScene(unsigned int scnIndex);
	void SetCamMatrix(const Matrix4x4f& mat);

  void PrintPerfInfo(std::ostream& out);

	Ray_Tracer::RT_Core* GetRTCore();

	class DLL_API RT_Core : public Base::RT_Core
	{
	public:

		void TraverseRays(Ray* in_out_rays, RAYTR::Hit* out_hits, size_t in_N);
		void TraverseRays(Ray* in_out_rays, RAYTR::Hit* out_hits, size_t in_width, size_t in_height);
	};

protected:
	virtual GPU_Ray_Tracer& operator=(const GPU_Ray_Tracer& x)
	{ 
		throw Error("GPU_Ray_Tracer:: Atempt to call protected operator=() "); 
		return (GPU_Ray_Tracer&)x;
	}

	virtual void CopyDynamicDataToGPU();
  void InitPBO(GLuint* a_pBuffer);

  RT_Core m_core;

  GLuint m_pixelBufferObject;
  GLuint m_screenTexture;
};