forked from speed-dreams/speed-dreams-code
OSG : Parameters load and save for split screen and cameras. Split pane working.
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@5230 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: eef0d8d985576db1c4a00c53ae5710d3149df67c Former-commit-id: b36fd9213c404d270c390c808fe1828e2f9abd74
This commit is contained in:
parent
d2fb2380a3
commit
fa944b832d
7 changed files with 199 additions and 100 deletions
|
@ -40,12 +40,12 @@ static float bezelComp;
|
|||
static float screenDist;
|
||||
static float arcRatio;
|
||||
static float spanaspect;
|
||||
//void *grHandle;
|
||||
static tdble spanA;
|
||||
|
||||
static double lastTime;
|
||||
|
||||
|
||||
|
||||
SDCamera::SDCamera(SDView * c, int myid, int mydrawCurrent, int mydrawdrv, int mydrawBackground, int mymirrorAllowed){
|
||||
screen = c;
|
||||
id = myid;
|
||||
|
@ -74,60 +74,6 @@ void SDCamera::setViewOffset(float v){
|
|||
|
||||
void SDCamera::update(tCarElt * car, tSituation * s)
|
||||
{
|
||||
/*osg::Vec3 P, p;
|
||||
float offset = 0;
|
||||
// int Speed = 0;
|
||||
|
||||
p[0] = car->_drvPos_x;
|
||||
p[1] = car->_drvPos_y;
|
||||
p[2] = car->_drvPos_z;
|
||||
|
||||
float t0 = p[0];
|
||||
float t1 = p[1];
|
||||
float t2 = p[2];
|
||||
|
||||
p[0] = t0*car->_posMat[0][0] + t1*car->_posMat[1][0] + t2*car->_posMat[2][0] + car->_posMat[3][0];
|
||||
p[1] = t0*car->_posMat[0][1] + t1*car->_posMat[1][1] + t2*car->_posMat[2][1] + car->_posMat[3][1];
|
||||
p[2] = t0*car->_posMat[0][2] + t1*car->_posMat[1][2] + t2*car->_posMat[2][2] + car->_posMat[3][2];
|
||||
|
||||
//GfOut("Car X = %f - P0 = %f\n", car->_pos_X, P[0]);
|
||||
|
||||
eye[0] = p[0];
|
||||
eye[1] = p[1];
|
||||
eye[2] = p[2];
|
||||
|
||||
|
||||
// Compute offset angle and bezel compensation)
|
||||
/*if (spansplit && viewOffset) {
|
||||
offset += (viewOffset - 10 + (int((viewOffset - 10) * 2) * (bezelcomp - 100)/200)) *
|
||||
atan(screen->getViewRatio() / spanaspect * tan(spanfovy * M_PI / 360.0)) * 2;
|
||||
fovy = spanfovy;
|
||||
}*/
|
||||
|
||||
/*P[0] = (car->_pos_X + 30.0 * cos(car->_glance + offset + car->_yaw));
|
||||
P[1] = (car->_pos_Y + 30.0 * sin(car->_glance + offset + car->_yaw));
|
||||
P[2] = car->_pos_Z + car->_yaw;
|
||||
//osgXformPnt3(P, car->_posMat);
|
||||
|
||||
center[0] = P[0];
|
||||
center[1] = P[1];
|
||||
center[2] = P[2];
|
||||
|
||||
up[0] = car->_posMat[2][0];
|
||||
up[1] = car->_posMat[2][1];
|
||||
up[2] = car->_posMat[2][2];
|
||||
|
||||
speed[0] = car->pub.DynGCg.vel.x;
|
||||
speed[1] = car->pub.DynGCg.vel.y;
|
||||
speed[2] = car->pub.DynGCg.vel.z;
|
||||
|
||||
//Speed = car->_speed_x * 3.6;
|
||||
|
||||
// osg::Camera * osgCam = screen->getOsgCam();
|
||||
|
||||
// osgCam->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
|
||||
//osgCam->setViewMatrixAsLookAt( eye, center, up);*/
|
||||
}
|
||||
|
||||
// SdPerspCamera ================================================================
|
||||
|
@ -156,7 +102,8 @@ void SDPerspCamera::setProjection(void)
|
|||
|
||||
|
||||
|
||||
screen->getOsgCam()->setProjectionMatrixAsPerspective(fovy,screen->getViewRatio(),fnear,ffar);
|
||||
//screen->getOsgCam()->setProjectionMatrixAsPerspective(fovy,screen->getViewRatio(),fnear,ffar);
|
||||
|
||||
|
||||
// PLib takes the field of view as angles in degrees. However, the
|
||||
// aspect ratio really aplies to lengths in the projection
|
||||
|
@ -166,15 +113,22 @@ void SDPerspCamera::setProjection(void)
|
|||
// tan and atan functions operate on angles in radians. Also,
|
||||
// we're only interested in half the viewing angle.
|
||||
|
||||
/* float fovx = atan(getAspectRatio() / spanaspect * tan(fovy * M_PI / 360.0)) * 360.0 / M_PI;
|
||||
grContext.setFOV(fovx, fovy);
|
||||
grContext.setNearFar(fnear, ffar);
|
||||
// float fovx = atan(getAspectRatio() / spanaspect * tan(fovy * M_PI / 360.0)) * 360.0 / M_PI;
|
||||
screen->getOsgCam()->setProjectionMatrixAsPerspective(fovy,screen->getViewRatio() / spanaspect,fnear,ffar);
|
||||
|
||||
// grContext.setFOV(fovx, fovy);
|
||||
//grContext.setNearFar(fnear, ffar);
|
||||
|
||||
// correct view for split screen spanning
|
||||
if (viewOffset != 0 && spanOffset != 0) {
|
||||
float dist, left, right;
|
||||
double frnear,frfar,frtop,frbottom,frleft,frright;
|
||||
|
||||
//sgFrustum * frus = grContext.getFrustum();
|
||||
screen->getOsgCam()->getProjectionMatrixAsFrustum(frleft,frright,
|
||||
frbottom,frtop,
|
||||
frnear,frfar);
|
||||
|
||||
sgFrustum * frus = grContext.getFrustum();
|
||||
|
||||
//=($A$2/$B$2)-((($A$2/$B$2)-$A$2)*cos(B10))
|
||||
if (spanAngle)
|
||||
|
@ -183,20 +137,18 @@ void SDPerspCamera::setProjection(void)
|
|||
dist = screenDist;
|
||||
|
||||
if (dist !=0) {
|
||||
left = frus->getLeft() + (spanOffset * frus->getNear()/dist);
|
||||
right = frus->getRight() + (spanOffset * frus->getNear()/dist);
|
||||
#if 0
|
||||
GfLogInfo("Adjusting ViewOffset %f : Frustum %f : dist %f : left %f -> %1.12f, Right %f -> %1.12f, near %f\n",
|
||||
left = frleft + (spanOffset * frnear/dist);
|
||||
right = frright + (spanOffset * frnear/dist);
|
||||
|
||||
/*GfLogInfo("Adjusting ViewOffset %f : Frustum %f : dist %f : left %f -> %1.12f, Right %f -> %1.12f, near %f\n",
|
||||
viewOffset, spanOffset, dist,
|
||||
frus->getLeft(), left, //frus->getLeft() + spanOffset,
|
||||
frus->getRight(), right, //frus->getRight() + spanOffset,
|
||||
frus->getNear());
|
||||
#endif
|
||||
frus->setFrustum(left, right,
|
||||
frus->getBot(), frus->getTop(),
|
||||
frus->getNear(), frus->getFar());
|
||||
frus->getNear());*/
|
||||
|
||||
screen->getOsgCam()->setProjectionMatrixAsFrustum(left,right,frbottom,frtop,frnear,frfar);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void SDPerspCamera::setModelView(void)
|
||||
|
@ -227,7 +179,7 @@ float SDPerspCamera::getLODFactor(float x, float y, float z) {
|
|||
dd = sqrt(dx*dx+dy*dy+dz*dz);
|
||||
|
||||
ang = DEG2RAD(fovy / 2.0);
|
||||
// GfScrGetSize(&dummy, &scrh, &dummy, &dummy);
|
||||
//GfScrGetSize(&dummy, &scrh, &dummy, &dummy);
|
||||
|
||||
res = (float)scrh / 2.0 / dd / tan(ang);
|
||||
if (res < 0) {
|
||||
|
@ -517,13 +469,13 @@ class SDCarCamInsideDynDriverEye : public SDCarCamInsideDriverEye
|
|||
const tdble CosA = cos(A);
|
||||
const tdble SinA = sin(A);
|
||||
|
||||
//tdble brake = 0.0f;
|
||||
//if (car->_accel_x < 0.0)
|
||||
// brake = MIN(2.0, fabs(car->_accel_x) / 20.0);
|
||||
tdble brake = 0.0f;
|
||||
if (car->_accel_x < 0.0)
|
||||
brake = MIN(2.0, fabs(car->_accel_x) / 20.0);
|
||||
|
||||
center[0] = P[0] - (10 - 1) * CosA;
|
||||
center[1] = P[1] - (10 - 1) * SinA;
|
||||
center[2] = P[2]; // - brake; // this does not work yet
|
||||
center[2] = P[2] - brake;
|
||||
|
||||
#else
|
||||
center[0] = P[0];
|
||||
|
@ -745,19 +697,8 @@ class SDCarCamBehindReverse : public SDPerspCamera
|
|||
|
||||
void setModelView(void)
|
||||
{
|
||||
//screen->getOsgCam()->setViewMatrixAsLookAt(eye,center,up);
|
||||
|
||||
//osg::Matrix m= screen->getOsgCam()->getViewMatrix();
|
||||
osg::Matrix m;
|
||||
m.makeLookAt(eye,center,up);
|
||||
//float mirror[4][4];
|
||||
|
||||
/*#define M(row,col) mirror[row][col]
|
||||
M(0,0) = 1.0; M(0,1) = 0.0; M(0,2) = 0.0; M(0,3) = 0.0;
|
||||
M(1,0) = 0.0; M(1,1) =-1.0; M(1,2) = 0.0; M(1,3) = 0.0;
|
||||
M(2,0) = 0.0; M(2,1) = 0.0; M(2,2) = 1.0; M(2,3) = 0.0;
|
||||
M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0;
|
||||
#undef M*/
|
||||
osg::Matrix mir(1,0,0,0,
|
||||
0,1,0,0,
|
||||
0,0,-1,0,
|
||||
|
@ -1842,6 +1783,7 @@ SDCamera::~SDCamera( void ){
|
|||
SDCameras::SDCameras(SDView *c, int ncars){
|
||||
cameraHasChanged = false;
|
||||
|
||||
loadSpanValues();
|
||||
|
||||
|
||||
// Get the factor of visibiity from the graphics settings and from the track.
|
||||
|
@ -2406,9 +2348,30 @@ void SDCameras::nextCamera(int list){
|
|||
cameras[selectedList][selectedCamera]->setViewOffset(screen->getViewOffset());
|
||||
cameras[selectedList][selectedCamera]->setProjection();
|
||||
this->screen->de_activateMirror();
|
||||
screen->saveCamera();
|
||||
|
||||
}
|
||||
|
||||
void SDCameras::selectCamera(int list,int cam){
|
||||
if(list>=0 && list<CAMERA_LISTS && cam >=0 && cam<cameras[list].size()){
|
||||
selectedCamera = cam;
|
||||
selectedList = list;
|
||||
}else{
|
||||
selectedCamera =0;
|
||||
selectedList = 0;
|
||||
}
|
||||
|
||||
cameraHasChanged = true;
|
||||
|
||||
|
||||
cameras[selectedList][selectedCamera]->setViewOffset(screen->getViewOffset());
|
||||
cameras[selectedList][selectedCamera]->setProjection();
|
||||
this->screen->de_activateMirror();
|
||||
screen->saveCamera();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SDCameras::update(tCarElt * car, tSituation * s){
|
||||
if(cameraHasChanged){
|
||||
cameras[selectedList][selectedCamera]->onSelect(car,s);
|
||||
|
@ -2428,3 +2391,20 @@ SDCameras::~SDCameras(){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void SDCameras::loadSpanValues(){
|
||||
/* Check Bezel compensation - used when spaning view across multiple splits */
|
||||
bezelComp = (float)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_BEZELCOMP, "%", 110);
|
||||
screenDist= (float)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_SCREENDIST, NULL, 1);
|
||||
arcRatio = (float)GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_ARCRATIO, NULL, 1.0);
|
||||
|
||||
const char *pszMonitorType =
|
||||
GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_MONITOR, GR_VAL_MONITOR_16BY9);
|
||||
|
||||
if (strcmp(pszMonitorType, GR_VAL_MONITOR_16BY9) == 0)
|
||||
spanaspect = 1.7777;
|
||||
if (strcmp(pszMonitorType, GR_VAL_MONITOR_4BY3) == 0)
|
||||
spanaspect = 1.3333 ;
|
||||
if (strcmp(pszMonitorType, GR_VAL_MONITOR_NONE) == 0)
|
||||
spanaspect = 1;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,14 @@ public:
|
|||
void nextCamera(int list);
|
||||
void update(tCarElt * car, tSituation * s);
|
||||
inline int getIntSelectedCamera(){return selectedCamera;}
|
||||
void selectCamera(int list,int cam);
|
||||
inline void getIntSelectedListAndCamera(int *list,int *cam){
|
||||
*list = selectedList;
|
||||
*cam = selectedCamera;
|
||||
}
|
||||
|
||||
static void loadSpanValues();
|
||||
|
||||
~SDCameras();
|
||||
};
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ SDNextCar(void * /* dummy */)
|
|||
|
||||
void SDSelectCamera(void * vp){
|
||||
long t = (long)vp;
|
||||
screens->getActiveView()->getCameras()->nextCamera(t);
|
||||
screens->changeCamera(t);
|
||||
}
|
||||
|
||||
void SDSetZoom(void * vp){
|
||||
|
|
|
@ -102,10 +102,44 @@ void SDScreens::Init(int x,int y, int width, int height, osg::ref_ptr<osg::Group
|
|||
void SDScreens::InitCars(tSituation *s)
|
||||
{
|
||||
|
||||
char buf[256];
|
||||
char idx[16];
|
||||
int index;
|
||||
int i;
|
||||
tCarElt *elt;
|
||||
void *hdle;
|
||||
const char *pszSpanSplit;
|
||||
int grNbSuggestedScreens = 0;
|
||||
|
||||
|
||||
|
||||
/* Check whether view should be spanned across vertical splits */
|
||||
pszSpanSplit = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_SPANSPLIT, GR_VAL_NO);
|
||||
grSpanSplit = strcmp(pszSpanSplit, GR_VAL_YES) ? 0 : 1;
|
||||
|
||||
if (grSpanSplit == 0 && grNbSuggestedScreens > 1) {
|
||||
// Mulitplayer, so ignore the stored number of screens
|
||||
grNbActiveScreens = grNbSuggestedScreens;
|
||||
grNbArrangeScreens = 0;
|
||||
} else {
|
||||
// Load the real number of active screens and the arrangment.
|
||||
grNbActiveScreens = (int)GfParmGetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_NB_SCREENS, NULL, 1.0);
|
||||
grNbArrangeScreens = (int)GfParmGetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_ARR_SCREENS, NULL, 0.0);
|
||||
}
|
||||
|
||||
|
||||
// Initialize the cameras for all the screens.
|
||||
for (int i=0; i<grScreens.size();i++){
|
||||
grScreens[i]->Init(s);
|
||||
}
|
||||
|
||||
|
||||
// Setup the screens (= OpenGL viewports) inside the physical game window.
|
||||
this->grAdaptScreenSize();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SDScreens::update(tSituation * s,SDFrameInfo* fi)
|
||||
|
@ -400,6 +434,24 @@ void SDScreens::changeScreen(long p){
|
|||
GfLogInfo("Changing current screen to #%d (out of %d)\n", nCurrentScreenIndex, grNbActiveScreens);
|
||||
|
||||
}
|
||||
|
||||
void SDScreens::changeCamera(long p){
|
||||
|
||||
this->getActiveView()->getCameras()->nextCamera(p);
|
||||
|
||||
// For SpanSplit ensure screens change together
|
||||
if (grSpanSplit && getActiveView()->getViewOffset() ) {
|
||||
int i, camList,camNum;
|
||||
|
||||
getActiveView()->getCameras()->getIntSelectedListAndCamera(&camList,&camNum);
|
||||
|
||||
|
||||
for (i=0; i < grNbActiveScreens; i++)
|
||||
if (grScreens[i]->getViewOffset() )
|
||||
grScreens[i]->getCameras()->selectCamera(camList,camNum);
|
||||
}
|
||||
}
|
||||
|
||||
SDScreens::~SDScreens()
|
||||
{
|
||||
for (int i=0;i< grScreens.size();i++){
|
||||
|
|
|
@ -69,6 +69,7 @@ class SDScreens
|
|||
void update(tSituation *s,SDFrameInfo* fi);
|
||||
void splitScreen(long p);
|
||||
void changeScreen(long p);
|
||||
void changeCamera(long p);
|
||||
|
||||
inline SDView * getActiveView(){return grScreens[nCurrentScreenIndex];}
|
||||
|
||||
|
|
|
@ -29,10 +29,12 @@
|
|||
#include "OsgView.h"
|
||||
//#include "OsgCar.h"
|
||||
|
||||
//static char buf[1024];
|
||||
static char buf[1024];
|
||||
static char path[1024];
|
||||
static char path2[1024];
|
||||
|
||||
static int cpt=0;
|
||||
|
||||
SDView::SDView(osg::Camera * c, int x, int y, int width, int height,
|
||||
osg::Camera * mc)
|
||||
{
|
||||
|
@ -68,7 +70,8 @@ SDView::SDView(osg::Camera * c, int x, int y, int width, int height,
|
|||
|
||||
|
||||
|
||||
id = 0;
|
||||
id = cpt;
|
||||
cpt++;
|
||||
curCar = NULL;
|
||||
/*selectNextFlag = false;
|
||||
selectPrevFlag = false;
|
||||
|
@ -213,9 +216,11 @@ Camera* SDView::getCamera(){
|
|||
void SDView::loadParams(tSituation *s)
|
||||
{
|
||||
int camNum;
|
||||
int camList;
|
||||
int i;
|
||||
//class cGrCamera *cam;
|
||||
class cGrCamera *cam;
|
||||
const char *carName;
|
||||
const char *pszSpanSplit;
|
||||
|
||||
// Initialize the screen "current car" if not already done.
|
||||
sprintf(path, "%s/%d", GR_SCT_DISPMODE, id);
|
||||
|
@ -248,12 +253,63 @@ void SDView::loadParams(tSituation *s)
|
|||
}
|
||||
|
||||
// Load "current camera" settings (attached to the "current car").
|
||||
sprintf(path2, "%s/%s", GR_SCT_DISPMODE, curCar->_name);
|
||||
GfOut("Driver Name Camera = %s\n", curCar->_name);
|
||||
//curCamHead = (int)GfParmGetNum(grHandle, path, GR_ATT_CAM_HEAD, NULL, 9);
|
||||
camList = (int)GfParmGetNum(grHandle, path, GR_ATT_CAM_HEAD, NULL, 9);
|
||||
camNum = (int)GfParmGetNum(grHandle, path, GR_ATT_CAM, NULL, 0);
|
||||
mirrorFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_MIRROR, NULL, (tdble)mirrorFlag);
|
||||
//curCamHead = (int)GfParmGetNum(grHandle, path2, GR_ATT_CAM_HEAD, NULL, (tdble)curCamHead);
|
||||
camNum = (int)GfParmGetNum(grHandle, path2, GR_ATT_CAM, NULL, (tdble)camNum);
|
||||
|
||||
// Only apply driver preferences when not spanning split screens
|
||||
pszSpanSplit = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_SPANSPLIT, GR_VAL_NO);
|
||||
if (strcmp(pszSpanSplit, GR_VAL_YES)) {
|
||||
sprintf(path2, "%s/%s", GR_SCT_DISPMODE, curCar->_name);
|
||||
camList = (int)GfParmGetNum(grHandle, path2, GR_ATT_CAM_HEAD, NULL, (tdble)camNum);
|
||||
camNum = (int)GfParmGetNum(grHandle, path2, GR_ATT_CAM, NULL, (tdble)camList);
|
||||
mirrorFlag = (int)GfParmGetNum(grHandle, path2, GR_ATT_MIRROR, NULL, (tdble)mirrorFlag);
|
||||
}
|
||||
|
||||
// Get board width (needed for scissor)
|
||||
/* boardWidth = (int)GfParmGetNum(grHandle, path, GR_ATT_BOARDWIDTH, NULL, 100);
|
||||
if (boardWidth < 0 || boardWidth > 100)
|
||||
boardWidth = 100;*/
|
||||
|
||||
// Retrieve the "current camera".
|
||||
cameras->selectCamera(camList,camNum);
|
||||
|
||||
// Back to the default camera if not found (and save it as the new current one).
|
||||
|
||||
|
||||
cameras->getIntSelectedListAndCamera(&camList,&camNum);
|
||||
GfParmSetNum(grHandle, path, GR_ATT_CAM, NULL, (tdble)camNum);
|
||||
GfParmSetNum(grHandle, path, GR_ATT_CAM_HEAD, NULL, (tdble)camList);
|
||||
|
||||
|
||||
sprintf(buf, "%s-%d-%d", GR_ATT_FOVY, camList, camNum);
|
||||
cameras->getSelectedCamera()->loadDefaults(buf);
|
||||
//drawCurrent = curCam->getDrawCurrent();
|
||||
// board->loadDefaults(curCar);
|
||||
}
|
||||
|
||||
void SDView::saveCamera(){
|
||||
int camList,camNum;
|
||||
|
||||
cameras->getIntSelectedListAndCamera(&camList,&camNum);
|
||||
|
||||
sprintf(path, "%s/%d", GR_SCT_DISPMODE, id);
|
||||
GfParmSetStr(grHandle, path, GR_ATT_CUR_DRV, curCar->_name);
|
||||
GfParmSetNum(grHandle, path, GR_ATT_CAM, (char*)NULL, (tdble)camNum);
|
||||
GfParmSetNum(grHandle, path, GR_ATT_CAM_HEAD, (char*)NULL, (tdble)camList);
|
||||
|
||||
/* save also as user's preference if human */
|
||||
if (curCar->_driverType == RM_DRV_HUMAN) {
|
||||
sprintf(path2, "%s/%s", GR_SCT_DISPMODE, curCar->_name);
|
||||
GfParmSetNum(grHandle, path2, GR_ATT_CAM, (char*)NULL, (tdble)camNum);
|
||||
GfParmSetNum(grHandle, path2, GR_ATT_CAM_HEAD, (char*)NULL, (tdble)camList);
|
||||
}
|
||||
|
||||
sprintf(buf, "%s-%d-%d", GR_ATT_FOVY, camList, camNum);
|
||||
//would be save defaults ?
|
||||
//curCam->loadDefaults(buf);
|
||||
//drawCurrent = curCam->getDrawCurrent();
|
||||
//curCam->limitFov ();
|
||||
GfParmWriteFile(NULL, grHandle, "Graph");
|
||||
GfLogDebug("Written screen=%d camList=%d camNum=%d\n",id,camList,camNum);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,8 @@ class SDView
|
|||
|
||||
inline float getViewOffset() {return viewOffset;}
|
||||
|
||||
void saveCamera();
|
||||
|
||||
void activate(int x, int y, int width, int height,float v);
|
||||
void deactivate();
|
||||
|
||||
|
|
Loading…
Reference in a new issue