www.pudn.com > GPUVision_5-13-05-2.zip > GPUVision.cpp
// gpuvision.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "gpuvision.h" #includeusing namespace std; using namespace corona; #define ONLY_RED 0 GPUVision::GPUVision(const char *strFileName, bool mipmapped) { _ChooseProfiles(); _LoadCgPrograms(); _mipmapped = mipmapped; _bound = false; Image* image = OpenImage(strFileName,PF_R8G8B8A8,FF_AUTODETECT); if(!image) { throw "Error, could not load image"; return; } int numImgPixels = image->getWidth()*image->getHeight(); _dataFloats = new float[numImgPixels*4]; ConvertByte2Float((byte*)image->getPixels(),numImgPixels,4,4,_dataFloats,1); _width = image->getWidth(); _height = image->getHeight(); _textureID = UploadToTexture(_dataFloats); _Init(); // _packedInto = 4; } GPUVision::GPUVision(float* data, int width, int height, bool mipmapped) { _mipmapped = mipmapped; _width = width; _height = height; _ChooseProfiles(); _LoadCgPrograms(); _bound = false; _textureID = UploadToTexture(data); _Init(); // don't use the passed in data directly. Just create a new one _dataFloats = new float[_width*_height*4]; } GPUVision::GPUVision(unsigned int textureID, int width, int height) { _textureID = textureID; _width = width; _height = height; // Just create a new data array for download purposes _dataFloats = new float[_width*_height*4]; _mipmapped = false; //IJ _Init(); _ChooseProfiles(); _LoadCgPrograms(); _bound = false; } GPUVision::~GPUVision() { // should we destroy the context and the texture? cgDestroyContext(_CGcontext); glDeleteTextures(1,&_textureID); delete _rt; delete _dataFloats; } void GPUVision::DisplayCurrent() { _ExecutePassThrough(IsReset()?GetTextureID():GetRenderedTextureID(), true); } void GPUVision::PassThrough(unsigned int aTextureID, bool shouldFlip) { _ExecutePassThrough(aTextureID, shouldFlip); } void GPUVision::PassThrough(unsigned int aTextureID) { _ExecutePassThrough(aTextureID, true); } void GPUVision::PassThrough() { bool isReset = IsReset(); int id = IsReset()?GetTextureID():GetRenderedTextureID(); int texid = GetTextureID(); int rtexid = GetRenderedTextureID(); _ExecutePassThrough(IsReset()?GetTextureID():GetRenderedTextureID(), false); } // load up the texture stored in _textureID into the frontRT void GPUVision::LoadBase() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _ExecutePassThrough(_textureID, false); } float* GPUVision::DownloadTexture() {//IJ _dataFloats = (GLfloat*)malloc(_width*_height*4*sizeof(GLfloat)); Begin(); glReadPixels(0,0,_width,_height,GL_RGBA,GL_FLOAT,_dataFloats); End(); return _dataFloats; } // if we are drawing to the screen then we need to flip the y values // so that it is upright =) void GPUVision::_ExecutePassThrough(unsigned int aTextureID, bool flip) { cgGLBindProgram(_passThroughTextureProgram); cgGLSetTextureParameter(_passThroughTextureParam, aTextureID); cgGLEnableTextureParameter(_passThroughTextureParam); cgGLEnableProfile(_fragmentProfile); if(flip) _DrawFullFlip(); else _DrawFull(); cgGLDisableTextureParameter(_passThroughTextureParam); cgGLDisableProfile(_fragmentProfile); } void GPUVision::Flip() { _frontBufferIndex = !_frontBufferIndex; glDrawBuffer(glsurf[_frontBufferIndex]); glReadBuffer(glsurf[!_frontBufferIndex]); _rt->BindBuffer(wglsurf[!_frontBufferIndex]); _isReset = false; } void GPUVision::Begin() { _bound = true; _rt->BeginCapture(); // make sure that everything is set to what we left it // if this isn't done then you can't do multiple begin/ends glDrawBuffer(glsurf[_frontBufferIndex]); glReadBuffer(glsurf[!_frontBufferIndex]); _rt->BindBuffer(wglsurf[!_frontBufferIndex]); } // a bit more efficient because if chaining then // do not need to call End void GPUVision::Begin(GPUVision *currentlyBound) { currentlyBound->_bound = false; _bound = true; _rt->BeginCapture(currentlyBound->_rt); // make sure that everything is set to what we left it // if this isn't done then you can't do multiple begin/ends glDrawBuffer(glsurf[_frontBufferIndex]); glReadBuffer(glsurf[!_frontBufferIndex]); _rt->BindBuffer(wglsurf[!_frontBufferIndex]); } void GPUVision::End() { _bound = false; _rt->EndCapture(); } void GPUVision::Clear() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Flip(); } void GPUVision::ConvertByte2Float(byte* data, int data_pixels, int data_offset, int output_offset, float* output, float fill) { int i,j; byte* td; float* to; // fill in the difference with the fill value td = data; to = output; if(data_offset < output_offset) { for(i = 0; i < data_pixels; i++,to+=output_offset) { for(j = data_offset; j < output_offset; j++) { to[j] = fill; } } } td = data; to = output; for(i = 0; i < data_pixels; i++, td+=data_offset, to += output_offset) { for(j = 0; j < data_offset; j++) { to[j] = ((float)td[j])/255.; } } bool ok = true; } RenderTexture* GPUVision::CreateRenderTexture(const char *strMode) { RenderTexture *output = new RenderTexture(); output->Reset(strMode); if (!output->Initialize((int)_width, (int)_height)) { fprintf(stderr, "RenderTexture Initialization failed!\n"); } output->BeginCapture(); { if (output->IsDoubleBuffered()) output->BindBuffer(WGL_BACK_LEFT_ARB); output->Bind(); glEnable(GL_DEPTH_TEST); glViewport(0, 0, _width, _height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,_width,0,_height,0,-1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0, 0, 0, 0); } output->EndCapture(); output->Bind(); glTexParameteri(output->GetTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(output->GetTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_LINEAR); output->BindDepth(); glTexParameteri(output->GetTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(output->GetTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_LINEAR); return output; } void GPUVision::SetData(float* data) { SetData(data,_width,_height,GL_RGBA,_textureID); } void GPUVision::SetData(float* data, int width, int height, unsigned int inputDataFormat, unsigned int textureID) { int no_components; //IJ, let's suppose 4 channel or 1 channel no_components=(inputDataFormat==GL_RGBA)?GL_FLOAT_RGBA32_NV:GL_FLOAT_R32_NV; glDisable(GL_TEXTURE_2D); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_RECTANGLE_NV, textureID); // glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if(_mipmapped) { gluBuild2DMipmaps(GL_TEXTURE_RECTANGLE_NV, no_components, width, height, inputDataFormat, GL_FLOAT, data); } else { glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0, no_components, width, height, 0, inputDataFormat, GL_FLOAT, data); } } unsigned int GPUVision::UploadToTexture(float *data) { return UploadToTexture(data,_width,_height, GL_RGBA); } unsigned int GPUVision::UploadToTexture(float *data, int width, int height, unsigned int inputDataFormat) { unsigned int textureID; glGenTextures(1,&textureID); SetData(data, width, height, inputDataFormat, textureID); return textureID; } void GPUVision::_Init() { #if ONLY_RED _rt = CreateRenderTexture("r=32f doublebuffer texRECT rtt"); #else _rt = CreateRenderTexture("rgba=32f doublebuffer texRECT rtt"); #endif _frontBufferIndex = 0; } void GPUVision::_DrawFull() { glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(0, 0); glTexCoord2f(_width, 0); glVertex2f(_width, 0); glTexCoord2f(_width, _height); glVertex2f(_width, _height); glTexCoord2f(0, _height); glVertex2f(0, _height); glEnd(); } void GPUVision::_DrawIntoCoords(int width, int height) { glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(0, 0); glTexCoord2f(_width, 0); glVertex2f(width, 0); glTexCoord2f(_width, _height); glVertex2f(width, height); glTexCoord2f(0, _height); glVertex2f(0, height); glEnd(); } // for display purposes we need to flip the image around for // some reason void GPUVision::_DrawFullFlip() { glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(0, _height); glTexCoord2f(_width, 0); glVertex2f(_width, _height); glTexCoord2f(_width, _height); glVertex2f(_width, 0); glTexCoord2f(0, _height); glVertex2f(0, 0); glEnd(); } void GPUVision::_ChooseProfiles() { _CGcontext = cgCreateContext(); // try ARBFP1 if (cgGLIsProfileSupported(CG_PROFILE_FP30)) _fragmentProfile = CG_PROFILE_FP30; else if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1)) _fragmentProfile = CG_PROFILE_ARBFP1; else { fprintf(stderr, "Neither arbfp1 or fp30 fragment profiles supported on this system.\n"); exit(1); } } void GPUVision::_LoadCgPrograms() { assert(cgIsContext(_CGcontext)); cgGLEnableProfile(_fragmentProfile); char* strPassThrough = "void main(float2 iCoords : TEX0,\n" " uniform samplerRECT texture,\n" " out float3 oColor : COLOR) { \n" " oColor = f3texRECT(texture, iCoords);\n" "}\n"; _passThroughTextureProgram = cgCreateProgram(_CGcontext, CG_SOURCE, strPassThrough, _fragmentProfile, NULL, NULL); if (!cgIsProgramCompiled(_passThroughTextureProgram)) cgCompileProgram(_passThroughTextureProgram); cgGLLoadProgram(_passThroughTextureProgram); _passThroughTextureParam = cgGetNamedParameter(_passThroughTextureProgram, "texture"); cgGLDisableProfile(_fragmentProfile); } // copy the rendered void GPUVision::CopyRenderedToSource() { bool unBind = !_bound; if(unBind) Begin(); CopyRenderedToTexture(_textureID); if(unBind) End(); } void GPUVision::CopyRenderedToTexture(unsigned int textureID){ glEnable(GL_TEXTURE_RECTANGLE_NV); glBindTexture(GL_TEXTURE_RECTANGLE_NV, textureID); glCopyTexImage2D(GL_TEXTURE_RECTANGLE_NV,0, GL_FLOAT_RGBA32_NV, 0,0,_width, _height, 0); glDisable(GL_TEXTURE_RECTANGLE_EXT); glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0); // unbind it } // When making a copy it will simply GPUVision* GPUVision::Copy(){ // return this; /* unsigned int textureID; glGenTextures(1,&textureID); GPUVision *output = new GPUVision(textureID, _width,_height); this->UploadToTexture(this->_dataFloats,_width,_height, GL_RGBA); this->Reset(); this->Begin(); this->PassThrough(); //this->Flip(); CopyRenderedToTexture(output->_textureID); this->End(); this->Reset(); return output; */ GPUVision *output = new GPUVision(_dataFloats, _width,_height); return output; } int GPUVision::BackUpToTexture(){ // IJ unsigned int textureID; glGenTextures(1,&textureID); bool unBind = !_bound; if(unBind) Begin(); CopyRenderedToTexture(textureID); if(unBind) End(); return textureID; } unsigned int GPUVision::generateTextureID(){ //IJ unsigned int textureID; glGenTextures(1,&textureID); return textureID; } void GPUVision::deleteTextureID(const unsigned int textureID){ //IJ glDeleteTextures(1,&textureID); }