Changeset 15 in flair-src for trunk/lib/FlairSimulator/src/SimuCameraGL.cpp
- Timestamp:
- 04/08/16 15:40:57 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/FlairSimulator/src/SimuCameraGL.cpp
r10 r15 41 41 using namespace flair::simulator; 42 42 43 namespace flair 44 { 45 namespace sensor 46 { 47 48 SimuCameraGL::SimuCameraGL(const Model* parent,std::string name,int width,int height,int x,int y,int dev_id) :SimuCamera(parent,name,width,height,3,dev_id),SensorGL(parent) 49 { 50 smgr=getGui()->getSceneManager(); 51 camera=smgr->addCameraSceneNode(); 52 camera->addAnimator(this); 53 camera->setAspectRatio(4.0f/3.0f);//on force a cause du view port 54 55 this->width=width; 56 this->height=height; 57 this->x=x; 58 this->y=y; 59 60 index = 0; 61 62 buffer=(char*)malloc(width*height*3); 63 64 //user interface 65 Tab* setup_tab=new Tab(parent->GetTabWidget(),name); 66 position=new Vector3DSpinBox(setup_tab->NewRow(),"position",-2,2,.01); 67 direction=new Vector3DSpinBox(setup_tab->NewRow(),"direction",-2,2,.01); 68 up=new Vector3DSpinBox(setup_tab->NewRow(),"up",-2,2,.01); 69 fov=new DoubleSpinBox(setup_tab->NewRow(),"fov:",0,180,5); 70 71 if(strcmp((char*)glGetString(GL_VENDOR),"Intel Open Source Technology Center")==0) { 72 Thread::Warn("disabling cameras output for Intel card (bug with PBO)\n"); 73 disable_output=true; 74 } else { 75 disable_output=false; 43 namespace flair { 44 namespace sensor { 45 46 SimuCameraGL::SimuCameraGL(const Model *parent, std::string name, int width, 47 int height, int x, int y, int dev_id) 48 : SimuCamera(parent, name, width, height, 3, dev_id), SensorGL(parent) { 49 smgr = getGui()->getSceneManager(); 50 camera = smgr->addCameraSceneNode(); 51 camera->addAnimator(this); 52 camera->setAspectRatio(4.0f / 3.0f); // on force a cause du view port 53 54 this->width = width; 55 this->height = height; 56 this->x = x; 57 this->y = y; 58 59 index = 0; 60 61 buffer = (char *)malloc(width * height * 3); 62 63 // user interface 64 Tab *setup_tab = new Tab(parent->GetTabWidget(), name); 65 position = new Vector3DSpinBox(setup_tab->NewRow(), "position", -2, 2, .01); 66 direction = new Vector3DSpinBox(setup_tab->NewRow(), "direction", -2, 2, .01); 67 up = new Vector3DSpinBox(setup_tab->NewRow(), "up", -2, 2, .01); 68 fov = new DoubleSpinBox(setup_tab->NewRow(), "fov:", 0, 180, 5); 69 70 if (strcmp((char *)glGetString(GL_VENDOR), 71 "Intel Open Source Technology Center") == 0) { 72 Thread::Warn("disabling cameras output for Intel card (bug with PBO)\n"); 73 disable_output = true; 74 } else { 75 disable_output = false; 76 } 77 78 if (isGlExtensionSupported("GL_ARB_pixel_buffer_object")) { 79 use_pbo = true; 80 // create 2 pixel buffer objects, you need to delete them when program 81 // exits. 82 // glBufferDataARB with NULL pointer reserves only memory space. 83 pboIds = (GLuint *)malloc(PBO_COUNT * sizeof(GLuint)); 84 glGenBuffersARB(PBO_COUNT, pboIds); 85 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[0]); 86 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, width * height * 3, 0, 87 GL_STREAM_READ_ARB); 88 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[1]); 89 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, width * height * 3, 0, 90 GL_STREAM_READ_ARB); 91 92 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 93 } else { 94 use_pbo = false; 95 Thread::Warn("GL_ARB_pixel_buffer_object is not suppoorted\n"); 96 } 97 if (isGlExtensionSupported("GL_PACK_INVERT_MESA")) { 98 invert_pixel = false; 99 Thread::Warn("GL_PACK_INVERT_MESA is suppoorted\n"); 100 } else { 101 invert_pixel = true; 102 } 103 } 104 105 SimuCameraGL::~SimuCameraGL() { 106 free(buffer); 107 108 if (use_pbo) { 109 glDeleteBuffersARB(PBO_COUNT, pboIds); 110 free(pboIds); 111 } 112 } 113 114 void SimuCameraGL::setNearValue(float zn) { camera->setNearValue(zn); } 115 116 void SimuCameraGL::setFarValue(float zf) { camera->setFarValue(zf); } 117 118 void SimuCameraGL::UpdateFrom(const io_data *data) { 119 if (noGui() == false && data == NULL) { 120 smgr->setActiveCamera(camera); 121 smgr->getVideoDriver()->setViewPort(rect<s32>(x, y, x + width, y + height)); 122 smgr->drawAll(); 123 // use_pbo=false; 124 getImage(); 125 } 126 } 127 128 void SimuCameraGL::getImage(void) { 129 if (disable_output) 130 return; 131 // convert from irrlicht top left origin to gl bottom left origin 132 int y = smgr->getVideoDriver()->getScreenSize().Height - height - this->y; 133 134 // We want to read the front buffer to get the latest render finished. 135 Time a = GetTime(); 136 glReadBuffer(GL_FRONT); 137 if (use_pbo) // with PBO 138 { 139 // increment current index first then get the next index 140 // "index" is used to read pixels from a framebuffer to a PBO 141 // "nextIndex" is used to process pixels in the other PBO 142 index = (index + 1) % PBO_COUNT; 143 int nextIndex = (index + 1) % PBO_COUNT; 144 145 // copy pixels from framebuffer to PBO 146 // Use offset instead of pointer. 147 // OpenGL should perform asynch DMA transfer, so glReadPixels() will return 148 // immediately. 149 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]); 150 glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, 0); 151 152 // map the PBO that contain framebuffer pixels before processing it 153 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]); 154 GLubyte *src = (GLubyte *)glMapBufferARB( 155 GL_PIXEL_PACK_BUFFER_ARB, GL_READ_WRITE_ARB); // GL_READ_ONLY_ARB); 156 if (src) { 157 putImage((char *)src); 158 glUnmapBufferARB( 159 GL_PIXEL_PACK_BUFFER_ARB); // release pointer to the mapped buffer 76 160 } 77 78 if(isGlExtensionSupported("GL_ARB_pixel_buffer_object")) 79 { 80 use_pbo=true; 81 // create 2 pixel buffer objects, you need to delete them when program exits. 82 // glBufferDataARB with NULL pointer reserves only memory space. 83 pboIds=(GLuint*)malloc(PBO_COUNT*sizeof(GLuint)); 84 glGenBuffersARB(PBO_COUNT, pboIds); 85 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[0]); 86 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, width*height*3, 0, GL_STREAM_READ_ARB); 87 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[1]); 88 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, width*height*3, 0, GL_STREAM_READ_ARB); 89 90 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 161 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 162 } else { 163 glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, buffer); 164 putImage(buffer); 165 } 166 167 glReadBuffer(GL_BACK); 168 Time b = GetTime(); 169 Time c = b - a; 170 // printf("%s %f\n",Thread::ObjectName().c_str(),(float)(c/1000000.)); 171 } 172 173 void SimuCameraGL::putImage(char *buf) { 174 if (invert_pixel == true) { 175 // opengl images are horizontally flipped, so we have to fix that here. 176 const s32 pitch = width * 3; 177 char *pixels = buf; 178 char *p2 = pixels + (height - 1) * pitch; 179 char *tmpBuffer = new char[pitch]; 180 for (int i = 0; i < height; i += 2) { 181 memcpy(tmpBuffer, pixels, pitch); 182 memcpy(pixels, p2, pitch); 183 memcpy(p2, tmpBuffer, pitch); 184 pixels += pitch; 185 p2 -= pitch; 91 186 } 92 else 93 { 94 use_pbo=false; 95 Thread::Warn("GL_ARB_pixel_buffer_object is not suppoorted\n"); 96 } 97 if(isGlExtensionSupported("GL_PACK_INVERT_MESA")) 98 { 99 invert_pixel=false; 100 Thread::Warn("GL_PACK_INVERT_MESA is suppoorted\n"); 101 } 102 else 103 { 104 invert_pixel=true; 105 } 106 } 107 108 SimuCameraGL::~SimuCameraGL() 109 { 110 free(buffer); 111 112 if(use_pbo) 113 { 114 glDeleteBuffersARB(PBO_COUNT, pboIds); 115 free(pboIds); 116 } 117 } 118 119 void SimuCameraGL::setNearValue(float zn) { 120 camera->setNearValue(zn); 121 } 122 123 124 void SimuCameraGL::setFarValue(float zf) { 125 camera->setFarValue(zf); 126 } 127 128 129 void SimuCameraGL::UpdateFrom(const io_data *data) 130 { 131 if(noGui()==false && data==NULL) 132 { 133 smgr->setActiveCamera(camera); 134 smgr->getVideoDriver()->setViewPort(rect<s32>(x,y,x+width,y+height)); 135 smgr->drawAll(); 136 //use_pbo=false; 137 getImage(); 138 } 139 } 140 141 void SimuCameraGL::getImage(void) 142 { 143 if(disable_output) return; 144 //convert from irrlicht top left origin to gl bottom left origin 145 int y=smgr->getVideoDriver()->getScreenSize().Height-height-this->y; 146 147 // We want to read the front buffer to get the latest render finished. 148 Time a=GetTime(); 149 glReadBuffer(GL_FRONT); 150 if(use_pbo) // with PBO 151 { 152 // increment current index first then get the next index 153 // "index" is used to read pixels from a framebuffer to a PBO 154 // "nextIndex" is used to process pixels in the other PBO 155 index = (index + 1) % PBO_COUNT; 156 int nextIndex = (index + 1) % PBO_COUNT; 157 158 // copy pixels from framebuffer to PBO 159 // Use offset instead of pointer. 160 // OpenGL should perform asynch DMA transfer, so glReadPixels() will return immediately. 161 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]); 162 glReadPixels(x,y,width,height, GL_BGR, GL_UNSIGNED_BYTE, 0); 163 164 // map the PBO that contain framebuffer pixels before processing it 165 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]); 166 GLubyte* src = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,GL_READ_WRITE_ARB);//GL_READ_ONLY_ARB); 167 if(src) 168 { 169 putImage((char*)src); 170 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // release pointer to the mapped buffer 171 } 172 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 173 } 174 else 175 { 176 glReadPixels(x,y,width,height, GL_BGR, GL_UNSIGNED_BYTE, buffer); 177 putImage(buffer); 178 } 179 180 glReadBuffer(GL_BACK); 181 Time b=GetTime(); 182 Time c=b-a; 183 //printf("%s %f\n",Thread::ObjectName().c_str(),(float)(c/1000000.)); 184 } 185 186 void SimuCameraGL::putImage(char* buf) 187 { 188 if(invert_pixel==true) 189 { 190 // opengl images are horizontally flipped, so we have to fix that here. 191 const s32 pitch=width*3; 192 char* pixels = buf; 193 char* p2 = pixels + (height - 1) * pitch; 194 char* tmpBuffer = new char[pitch]; 195 for (int i=0; i < height; i += 2) 196 { 197 memcpy(tmpBuffer, pixels, pitch); 198 memcpy(pixels, p2, pitch); 199 memcpy(p2, tmpBuffer, pitch); 200 pixels += pitch; 201 p2 -= pitch; 202 } 203 delete [] tmpBuffer; 204 } 205 206 shmem->Write(buf,width*height*3); 207 } 208 209 void SimuCameraGL::animateNode(ISceneNode* node, u32 timeMs) 210 { 211 ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node); 212 213 matrix4 m; 214 m.setRotationDegrees(Node()->getRotation()); 215 216 // transform forward vector of camera 217 vector3df frv =ToIrrlichtCoordinates(direction->Value()); 218 m.transformVect(frv); 219 220 // transform upvector of camera 221 vector3df upv =ToIrrlichtCoordinates(up->Value()); 222 m.transformVect(upv); 223 224 // transform camera offset (thanks to Zeuss for finding it was missing) 225 vector3df offset = ToIrrlichtCoordinates(position->Value()); 226 m.transformVect(offset); 227 228 // set camera 229 camera->setPosition(Node()->getPosition() + offset); //position camera in front of the ship 230 camera->setUpVector(upv); //set up vector of camera >> Zeuss - tested with +node->getPostion() and it didnt work, but this works fine. 231 camera->setTarget(Node()->getPosition() + offset+frv); //set target of camera (look at point) >> Zeuss - Dont forget to add the node positiob 232 233 camera->setFOV(Euler::ToRadian(fov->Value())); 234 } 235 236 ISceneNodeAnimator* SimuCameraGL::createClone(ISceneNode* node, 237 ISceneManager* newManager) 238 { 239 return NULL; 187 delete[] tmpBuffer; 188 } 189 190 shmem->Write(buf, width * height * 3); 191 } 192 193 void SimuCameraGL::animateNode(ISceneNode *node, u32 timeMs) { 194 ICameraSceneNode *camera = static_cast<ICameraSceneNode *>(node); 195 196 matrix4 m; 197 m.setRotationDegrees(Node()->getRotation()); 198 199 // transform forward vector of camera 200 vector3df frv = ToIrrlichtCoordinates(direction->Value()); 201 m.transformVect(frv); 202 203 // transform upvector of camera 204 vector3df upv = ToIrrlichtCoordinates(up->Value()); 205 m.transformVect(upv); 206 207 // transform camera offset (thanks to Zeuss for finding it was missing) 208 vector3df offset = ToIrrlichtCoordinates(position->Value()); 209 m.transformVect(offset); 210 211 // set camera 212 camera->setPosition(Node()->getPosition() + 213 offset); // position camera in front of the ship 214 camera->setUpVector(upv); // set up vector of camera >> Zeuss - tested with 215 // +node->getPostion() and it didnt work, but this 216 // works fine. 217 camera->setTarget(Node()->getPosition() + offset + frv); // set target of 218 // camera (look at 219 // point) >> Zeuss - 220 // Dont forget to add 221 // the node positiob 222 223 camera->setFOV(Euler::ToRadian(fov->Value())); 224 } 225 226 ISceneNodeAnimator *SimuCameraGL::createClone(ISceneNode *node, 227 ISceneManager *newManager) { 228 return NULL; 240 229 } 241 230
Note:
See TracChangeset
for help on using the changeset viewer.