X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fpanel.cxx;h=a7b860afa43aa4ac8433a640f0e4640f9021a5c8;hb=35396de6f87e2a8b8d0c21eb1d0908db586799f8;hp=f9924fbd48359c71251a36cd3afc4063fd9a39db;hpb=db86d15c5f980a36b0de48f58294409e75289974;p=flightgear.git diff --git a/src/Cockpit/panel.cxx b/src/Cockpit/panel.cxx index f9924fbd4..a7b860afa 100644 --- a/src/Cockpit/panel.cxx +++ b/src/Cockpit/panel.cxx @@ -31,22 +31,24 @@ # include #endif -#ifdef HAVE_WINDOWS_H -# include -#endif - #include // sprintf #include +#include -#include +#include +#include +#include +#include +#include -#include SG_GLU_H +#include -#include #include #include #include +#include +#include #include
#include
@@ -65,7 +67,7 @@ // The number of polygon-offset "units" to place between layers. In // principle, one is supposed to be enough. In practice, I find that // my hardware/driver requires many more. -#define POFF_UNITS 4 +#define POFF_UNITS 8 //////////////////////////////////////////////////////////////////////// // Local functions. @@ -92,47 +94,52 @@ get_aspect_adjust (int xsize, int ysize) bool fgPanelVisible () { - if(globals->get_current_panel() == 0) + const FGPanel* current = globals->get_current_panel(); + if (current == 0) return false; - if(globals->get_current_panel()->getVisibility() == 0) + if (current->getVisibility() == 0) return false; - if(globals->get_viewmgr()->get_current() != 0) + if (globals->get_viewmgr()->get_current() != 0) return false; - if(globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0) + if (current->getAutohide() && globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0) return false; return true; } - //////////////////////////////////////////////////////////////////////// // Implementation of FGTextureManager. //////////////////////////////////////////////////////////////////////// -map FGTextureManager::_textureMap; +map > FGTextureManager::_textureMap; -ssgTexture * -FGTextureManager::createTexture (const string &relativePath) +osg::Texture2D* +FGTextureManager::createTexture (const string &relativePath, bool staticTexture) { - ssgTexture * texture = _textureMap[relativePath]; + osg::Texture2D* texture = _textureMap[relativePath].get(); if (texture == 0) { SG_LOG( SG_COCKPIT, SG_DEBUG, "Texture " << relativePath << " does not yet exist" ); SGPath tpath(globals->get_fg_root()); tpath.append(relativePath); - texture = new ssgTexture((char *)tpath.c_str(), false, false); + + texture = SGLoadTexture2D(staticTexture, tpath); + _textureMap[relativePath] = texture; - if (_textureMap[relativePath] == 0) + if (!_textureMap[relativePath].valid()) SG_LOG( SG_COCKPIT, SG_ALERT, "Texture *still* doesn't exist" ); - SG_LOG( SG_COCKPIT, SG_DEBUG, "Created texture " << relativePath - << " handle=" << texture->getHandle() ); + SG_LOG( SG_COCKPIT, SG_DEBUG, "Created texture " << relativePath ); } return texture; } - +void FGTextureManager::addTexture(const string &relativePath, + osg::Texture2D* texture) +{ + _textureMap[relativePath] = texture; +} //////////////////////////////////////////////////////////////////////// // Implementation of FGCropped Texture. @@ -160,13 +167,16 @@ FGCroppedTexture::~FGCroppedTexture () } -ssgTexture * +osg::StateSet* FGCroppedTexture::getTexture () { if (_texture == 0) { - _texture = FGTextureManager::createTexture(_path); + _texture = new osg::StateSet; + _texture->setTextureAttribute(0, FGTextureManager::createTexture(_path)); + _texture->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + _texture->setTextureAttribute(0, new osg::TexEnv(osg::TexEnv::MODULATE)); } - return _texture; + return _texture.get(); } @@ -254,11 +264,52 @@ FGPanel::unbind () } +void +FGPanel::update (double dt) +{ + std::cout << "OSGFIXME" << std::endl; +} + +void +FGPanel::update (osg::State& state, GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh) +{ + // Calculate accelerations + // and jiggle the panel accordingly + // The factors and bounds are just + // initial guesses; using sqrt smooths + // out the spikes. + double x_offset = _x_offset->getIntValue(); + double y_offset = _y_offset->getIntValue(); + + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + if ( _flipx->getBoolValue() ) { + gluOrtho2D(winx + winw, winx, winy + winh, winy); /* up side down */ + } else { + gluOrtho2D(winx, winx + winw, winy, winy + winh); /* right side up */ + } + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glTranslated(x_offset, y_offset, 0); + + draw(state); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + /** * Update the panel. */ void -FGPanel::update (double dt) +FGPanel::update (osg::State& state) { // Do nothing if the panel isn't visible. if ( !fgPanelVisible() ) { @@ -271,9 +322,9 @@ FGPanel::update (double dt) float aspect_adjust = get_aspect_adjust(_xsize_node->getIntValue(), _ysize_node->getIntValue()); if (aspect_adjust <1.0) - update(WIN_X, int(WIN_W * aspect_adjust), WIN_Y, WIN_H); + update(state, WIN_X, int(WIN_W * aspect_adjust), WIN_Y, WIN_H); else - update(WIN_X, WIN_W, WIN_Y, int(WIN_H / aspect_adjust)); + update(state, WIN_X, WIN_W, WIN_Y, int(WIN_H / aspect_adjust)); } /** @@ -294,90 +345,44 @@ void FGPanel::updateMouseDelay() void -FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh) -{ - // Calculate accelerations - // and jiggle the panel accordingly - // The factors and bounds are just - // initial guesses; using sqrt smooths - // out the spikes. - double x_offset = _x_offset->getIntValue(); - double y_offset = _y_offset->getIntValue(); - -#if 0 - if (_jitter->getFloatValue() != 0.0) { - double a_x_pilot = current_aircraft.fdm_state->get_A_X_pilot(); - double a_y_pilot = current_aircraft.fdm_state->get_A_Y_pilot(); - double a_z_pilot = current_aircraft.fdm_state->get_A_Z_pilot(); - - double a_zx_pilot = a_z_pilot - a_x_pilot; - - int x_adjust = int(sqrt(fabs(a_y_pilot) * _jitter->getFloatValue())) * - (a_y_pilot < 0 ? -1 : 1); - int y_adjust = int(sqrt(fabs(a_zx_pilot) * _jitter->getFloatValue())) * - (a_zx_pilot < 0 ? -1 : 1); - - // adjustments in screen coordinates - x_offset += x_adjust; - y_offset += y_adjust; - } -#endif - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - if ( _flipx->getBoolValue() ) { - gluOrtho2D(winx + winw, winx, winy + winh, winy); /* up side down */ - } else { - gluOrtho2D(winx, winx + winw, winy, winy + winh); /* right side up */ - } - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glTranslated(x_offset, y_offset, 0); - - draw(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - ssgForceBasicState(); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -} - -void -FGPanel::draw() +FGPanel::draw(osg::State& state) { // In 3D mode, it's possible that we are being drawn exactly on top // of an existing polygon. Use an offset to prevent z-fighting. In // 2D mode, this is a no-op. - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1, -POFF_UNITS); - - // save some state - glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT - | GL_TEXTURE_BIT | GL_PIXEL_MODE_BIT | GL_CULL_FACE - | GL_DEPTH_BUFFER_BIT ); - - // Draw the background - glEnable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - if( _enable_depth_test ) - glDepthFunc(GL_ALWAYS); + static osg::ref_ptr panelStateSet; + if (!panelStateSet.valid()) { + panelStateSet = new osg::StateSet; + panelStateSet->setAttributeAndModes(new osg::PolygonOffset(-1, -POFF_UNITS)); + panelStateSet->setTextureAttribute(0, new osg::TexEnv); + + // Draw the background + panelStateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + panelStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + panelStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); + panelStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); + osg::Material* material = new osg::Material; + material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1)); + material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1)); + material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1)); + material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1)); + panelStateSet->setAttribute(material); + panelStateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON); + panelStateSet->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK)); + panelStateSet->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL)); + } + if ( _enable_depth_test ) + panelStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); else - glDisable(GL_DEPTH_TEST); + panelStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + state.pushStateSet(panelStateSet.get()); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); FGLight *l = (FGLight *)(globals->get_subsystem("lighting")); - sgCopyVec4( panel_color, l->scene_diffuse()); + sgCopyVec4( panel_color, l->scene_diffuse().data()); if ( fgGetDouble("/systems/electrical/outputs/instrument-lights") > 1.0 ) { if ( panel_color[0] < 0.7 ) panel_color[0] = 0.7; if ( panel_color[1] < 0.2 ) panel_color[1] = 0.2; @@ -385,68 +390,138 @@ FGPanel::draw() } glColor4fv( panel_color ); if (_bg != 0) { - glBindTexture(GL_TEXTURE_2D, _bg->getHandle()); - // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + state.pushStateSet(_bg.get()); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex2f(WIN_X, WIN_Y); glTexCoord2f(1.0, 0.0); glVertex2f(WIN_X + _width, WIN_Y); glTexCoord2f(1.0, 1.0); glVertex2f(WIN_X + _width, WIN_Y + _height); glTexCoord2f(0.0, 1.0); glVertex2f(WIN_X, WIN_Y + _height); glEnd(); + state.popStateSet(); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + } else { for (int i = 0; i < 4; i ++) { // top row of textures...(1,3,5,7) - glBindTexture(GL_TEXTURE_2D, _mbg[i*2]->getHandle()); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + state.pushStateSet(_mbg[i*2].get()); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y + (_height/2)); glTexCoord2f(1.0, 0.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y + (_height/2)); glTexCoord2f(1.0, 1.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y + _height); glTexCoord2f(0.0, 1.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y + _height); glEnd(); + state.popStateSet(); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + // bottom row of textures...(2,4,6,8) - glBindTexture(GL_TEXTURE_2D, _mbg[(i*2)+1]->getHandle()); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + state.pushStateSet(_mbg[i*2+1].get()); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y); glTexCoord2f(1.0, 0.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y); glTexCoord2f(1.0, 1.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y + (_height/2)); glTexCoord2f(0.0, 1.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y + (_height/2)); glEnd(); + state.popStateSet(); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + } } // Draw the instruments. + // Syd Adams: added instrument clipping instrument_list_type::const_iterator current = _instruments.begin(); instrument_list_type::const_iterator end = _instruments.end(); + GLdouble blx[4]={1.0,0.0,0.0,0.0}; + GLdouble bly[4]={0.0,1.0,0.0,0.0}; + GLdouble urx[4]={-1.0,0.0,0.0,0.0}; + GLdouble ury[4]={0.0,-1.0,0.0,0.0}; + for ( ; current != end; current++) { FGPanelInstrument * instr = *current; glPushMatrix(); glTranslated(instr->getXPos(), instr->getYPos(), 0); - instr->draw(); + + int ix= instr->getWidth(); + int iy= instr->getHeight(); + glPushMatrix(); + glTranslated(-ix/2,-iy/2,0); + glClipPlane(GL_CLIP_PLANE0,blx); + glClipPlane(GL_CLIP_PLANE1,bly); + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + + glTranslated(ix,iy,0); + glClipPlane(GL_CLIP_PLANE2,urx); + glClipPlane(GL_CLIP_PLANE3,ury); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); + glPopMatrix(); + instr->draw(state); + glPopMatrix(); } + glDisable(GL_CLIP_PLANE0); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE2); + glDisable(GL_CLIP_PLANE3); + + state.popStateSet(); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + + // Draw yellow "hotspots" if directed to. This is a panel authoring // feature; not intended to be high performance or to look good. if ( fgGetBool("/sim/panel-hotspots") ) { - glDisable(GL_TEXTURE_2D); + static osg::ref_ptr hotspotStateSet; + if (!hotspotStateSet.valid()) { + hotspotStateSet = new osg::StateSet; + hotspotStateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF); + hotspotStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + } + + state.pushStateSet(hotspotStateSet.get()); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_COLOR_MATERIAL); glColor3f(1, 1, 0); for ( unsigned int i = 0; i < _instruments.size(); i++ ) - _instruments[i]->drawHotspots(); - } + _instruments[i]->drawHotspots(state); + + glPopAttrib(); + state.popStateSet(); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); - // restore some original state - if( _enable_depth_test ) - glDepthFunc(GL_LESS); - glPopAttrib(); - glPolygonOffset(0, 0); - glDisable(GL_POLYGON_OFFSET_FILL); + } } /** @@ -473,19 +548,28 @@ FGPanel::getVisibility () const * Set the panel's background texture. */ void -FGPanel::setBackground (ssgTexture * texture) +FGPanel::setBackground (osg::Texture2D* texture) { - _bg = texture; + osg::StateSet* stateSet = new osg::StateSet; + stateSet->setTextureAttribute(0, texture); + stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + stateSet->setTextureAttribute(0, new osg::TexEnv(osg::TexEnv::MODULATE)); + _bg = stateSet; } /** * Set the panel's multiple background textures. */ void -FGPanel::setMultiBackground (ssgTexture * texture, int idx) +FGPanel::setMultiBackground (osg::Texture2D* texture, int idx) { _bg = 0; - _mbg[idx] = texture; + + osg::StateSet* stateSet = new osg::StateSet; + stateSet->setTextureAttribute(0, texture); + stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + stateSet->setTextureAttribute(0, new osg::TexEnv(osg::TexEnv::MODULATE)); + _mbg[idx] = stateSet; } /** @@ -606,7 +690,7 @@ FGPanelAction::~FGPanelAction () } void -FGPanelAction::addBinding (FGBinding * binding, int updown) +FGPanelAction::addBinding (SGBinding * binding, int updown) { _bindings[updown].push_back(binding); } @@ -673,7 +757,7 @@ FGPanelInstrument::~FGPanelInstrument () } void -FGPanelInstrument::drawHotspots() +FGPanelInstrument::drawHotspots(osg::State& state) { for ( unsigned int i = 0; i < _actions.size(); i++ ) { FGPanelAction* a = _actions[i]; @@ -771,14 +855,14 @@ FGLayeredInstrument::~FGLayeredInstrument () } void -FGLayeredInstrument::draw () +FGLayeredInstrument::draw (osg::State& state) { if (!test()) return; for (int i = 0; i < (int)_layers.size(); i++) { glPushMatrix(); - _layers[i]->draw(); + _layers[i]->draw(state); glPopMatrix(); } } @@ -828,7 +912,7 @@ FGSpecialInstrument::~FGSpecialInstrument () } void -FGSpecialInstrument::draw () +FGSpecialInstrument::draw (osg::State& state) { complex->draw(); } @@ -873,7 +957,7 @@ FGInstrumentLayer::transform () const val = t->max; } - if(t->table==0) { + if (t->table==0) { val = val * t->factor + t->offset; } else { val = t->table->interpolate(val) * t->factor + t->offset; @@ -918,13 +1002,13 @@ FGGroupLayer::~FGGroupLayer () } void -FGGroupLayer::draw () +FGGroupLayer::draw (osg::State& state) { if (test()) { transform(); int nLayers = _layers.size(); for (int i = 0; i < nLayers; i++) - _layers[i]->draw(); + _layers[i]->draw(state); } } @@ -955,14 +1039,18 @@ FGTexturedLayer::~FGTexturedLayer () void -FGTexturedLayer::draw () +FGTexturedLayer::draw (osg::State& state) { if (test()) { int w2 = _w / 2; int h2 = _h / 2; transform(); - glBindTexture(GL_TEXTURE_2D, _texture.getTexture()->getHandle()); + state.pushStateSet(_texture.getTexture()); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + glBegin(GL_POLYGON); if (_emissive) { @@ -978,6 +1066,11 @@ FGTexturedLayer::draw () glTexCoord2f(_texture.getMaxX(), _texture.getMaxY()); glVertex2f(w2, h2); glTexCoord2f(_texture.getMinX(), _texture.getMaxY()); glVertex2f(-w2, h2); glEnd(); + state.popStateSet(); + state.apply(); + state.setActiveTextureUnit(0); + state.setClientActiveTextureUnit(0); + } } @@ -988,7 +1081,7 @@ FGTexturedLayer::draw () //////////////////////////////////////////////////////////////////////// FGTextLayer::FGTextLayer (int w, int h) - : FGInstrumentLayer(w, h), _pointSize(14.0), _font_name("default.txf") + : FGInstrumentLayer(w, h), _pointSize(14.0), _font_name("Helvetica.txf") { _then.stamp(); _color[0] = _color[1] = _color[2] = 0.0; @@ -1005,7 +1098,7 @@ FGTextLayer::~FGTextLayer () } void -FGTextLayer::draw () +FGTextLayer::draw (osg::State& state) { if (test()) { glColor4fv(_color); @@ -1158,14 +1251,14 @@ FGSwitchLayer::FGSwitchLayer () } void -FGSwitchLayer::draw () +FGSwitchLayer::draw (osg::State& state) { if (test()) { transform(); int nLayers = _layers.size(); for (int i = 0; i < nLayers; i++) { if (_layers[i]->test()) { - _layers[i]->draw(); + _layers[i]->draw(state); return; } } @@ -1174,6 +1267,3 @@ FGSwitchLayer::draw () // end of panel.cxx - - -