source: flair-src/trunk/lib/FlairSimulator/src/SimuCameraGL.cpp@ 8

Last change on this file since 8 was 8, checked in by Sanahuja Guillaume, 8 years ago

simulator

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