diff --git a/direct/src/configfiles/direct.init b/direct/src/configfiles/direct.init deleted file mode 100644 index 16eb87325c..0000000000 --- a/direct/src/configfiles/direct.init +++ /dev/null @@ -1,9 +0,0 @@ -ATTACH dmodels -ATTACH panda -MODREL ETC_PATH etc -DOCSH set parent=`dirname $DIRECT` -DOCSH if ( ${?PANDA_ROOT} ) then -DOCSH setenv PYTHONPATH "${PYTHONPATH};"`cygpath -w "$parent"` -DOCSH else -DOCSH setenv PYTHONPATH "${PYTHONPATH}:$parent" -DOCSH endif diff --git a/dtool/src/cppparser/cppStructType.cxx b/dtool/src/cppparser/cppStructType.cxx index d0707c4404..745abab586 100644 --- a/dtool/src/cppparser/cppStructType.cxx +++ b/dtool/src/cppparser/cppStructType.cxx @@ -306,7 +306,6 @@ is_trivial() const { } // Now look for functions that are virtual or con/destructors. - bool is_default_constructible = true; CPPScope::Functions::const_iterator fi; for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) { CPPFunctionGroup *fgroup = (*fi).second; @@ -343,9 +342,6 @@ is_trivial() const { // Same for the default constructor. return false; } - // The presence of a non-default constructor makes the class not - // default-constructible. - is_default_constructible = false; } if (fgroup->_name == "operator =") { @@ -356,7 +352,7 @@ is_trivial() const { } // Finally, the class must be default-constructible. - return is_default_constructible; + return is_default_constructible(V_public); } /** diff --git a/dtool/src/interrogate/interrogateBuilder.cxx b/dtool/src/interrogate/interrogateBuilder.cxx index 15607c95ea..b740d59e1a 100644 --- a/dtool/src/interrogate/interrogateBuilder.cxx +++ b/dtool/src/interrogate/interrogateBuilder.cxx @@ -1389,7 +1389,8 @@ scan_element(CPPInstance *element, CPPStructType *struct_type, // We can only generate a getter and a setter if we can talk about the // type it is. - if (parameter_type->as_struct_type() != nullptr) { + if (parameter_type->as_struct_type() != nullptr && + !parameter_type->is_trivial()) { // Wrap the type in a const reference. parameter_type = TypeManager::wrap_const_reference(parameter_type); } diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index 976bfd84f5..1dab5196da 100644 --- a/makepanda/installer.nsi +++ b/makepanda/installer.nsi @@ -589,7 +589,6 @@ Section "3ds Max plug-ins" SecMaxPlugins File /nonfatal /r "${BUILT}\plugins\*.dle" File /nonfatal /r "${BUILT}\plugins\*.dlo" File /nonfatal /r "${BUILT}\plugins\*.ms" - File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT" SectionEnd !endif @@ -604,7 +603,6 @@ Section "Maya plug-ins" SecMayaPlugins SetOutPath $INSTDIR\plugins File /nonfatal /r "${BUILT}\plugins\*.mll" File /nonfatal /r "${BUILT}\plugins\*.mel" - File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT" SectionEnd !endif diff --git a/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm b/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm index 26d4dbdf71..b584d02a2c 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm @@ -134,6 +134,12 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for if (accelerated) { properties.set_force_hardware(1); } + + // Cautiously setting this to true. It appears that macOS framebuffers are + // sRGB-capable, but I don't really know how to verify this. + if (color_size == 32 && !color_float) { + properties.set_srgb_color(true); + } } /** diff --git a/panda/src/collide/collisionHandlerQueue.cxx b/panda/src/collide/collisionHandlerQueue.cxx index 75761362bd..0f6acaba52 100644 --- a/panda/src/collide/collisionHandlerQueue.cxx +++ b/panda/src/collide/collisionHandlerQueue.cxx @@ -22,10 +22,15 @@ class CollisionEntrySorter { public: CollisionEntrySorter(CollisionEntry *entry) { _entry = entry; - LVector3 vec = - entry->get_surface_point(entry->get_from_node_path()) - - entry->get_from()->get_collision_origin(); - _dist2 = vec.length_squared(); + if (entry->has_surface_point()) { + LVector3 vec = + entry->get_surface_point(entry->get_from_node_path()) - + entry->get_from()->get_collision_origin(); + _dist2 = vec.length_squared(); + } + else { + _dist2 = make_inf((PN_stdfloat)0); + } } bool operator < (const CollisionEntrySorter &other) const { return _dist2 < other._dist2; diff --git a/panda/src/configfiles/panda.init b/panda/src/configfiles/panda.init deleted file mode 100644 index 6256527d14..0000000000 --- a/panda/src/configfiles/panda.init +++ /dev/null @@ -1,10 +0,0 @@ -SETABS PANDA_VER 0.8 -MODREL ETC_PATH built/etc -DOCSH if ( ! $?CFG_PATH ) then -DOCSH setenv CFG_PATH ~ -DOCSH setenv CFG_PATH ". ${CFG_PATH} /usr/local/etc" -DOCSH endif -DOSH if [ -z "$CFG_PATH" ]; then -DOSH CFG_PATH=". $HOME /usr/local/etc" -DOSH export CFG_PATH -DOSH fi diff --git a/panda/src/dxgsg9/dxInput9.cxx b/panda/src/dxgsg9/dxInput9.cxx deleted file mode 100644 index 17d5b2f88e..0000000000 --- a/panda/src/dxgsg9/dxInput9.cxx +++ /dev/null @@ -1,269 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file dxInput9.cxx - * @author angelina jolie - * @date 1999-10-07 - */ - -#include "config_wdxdisplay9.h" -#include "dxInput9.h" - -#define AXIS_RESOLUTION 2000 // use this many levels of resolution by default (could be more if needed and device supported it) -#define AXIS_RANGE_CENTERED // if defined, axis range is centered on 0, instead of starting on 0 - -using std::endl; - -BOOL CALLBACK EnumGameCtrlsCallback( const DIDEVICEINSTANCE* pdidInstance, - VOID* pContext ) { - DI_DeviceInfos *pDevInfos = (DI_DeviceInfos *)pContext; - - (*pDevInfos).push_back(*pdidInstance); - - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "Found DevType 0x" << (void*)pdidInstance->dwDevType << ": " << pdidInstance->tszInstanceName << ": " << pdidInstance->tszProductName <Unacquire(); - SAFE_RELEASE(_DeviceList[i]); - } - - // bugbug: need to handle this if(_JoystickPollTimer!=NULL) KillTimer(...) - - SAFE_RELEASE(_pDInput9); - if(_hDInputDLL) { - FreeLibrary(_hDInputDLL); - _hDInputDLL=nullptr; - } -} - -bool DInput9Info::InitDirectInput() { - HRESULT hr; - - // assumes dx9 exists use dynamic load so non-dinput programs don't have - // to load dinput - #define DLLNAME "dinput9.dll" - #define DINPUTCREATE "DirectInput9Create" - - HINSTANCE _hDInputDLL = LoadLibrary(DLLNAME); - if(_hDInputDLL == 0) { - wdxdisplay_cat.fatal() << "LoadLibrary(" << DLLNAME <<") failed!, error=" << GetLastError() << endl; - exit(1); - } - - typedef HRESULT (WINAPI * LPDIRECTINPUT9CREATE)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); - LPDIRECTINPUT9CREATE pDInputCreate9; - - pDInputCreate9 = (LPDIRECTINPUT9CREATE) GetProcAddress(_hDInputDLL,DINPUTCREATE); - if(pDInputCreate9 == nullptr) { - wdxdisplay_cat.fatal() << "GetProcAddr failed for " << DINPUTCREATE << endl; - exit(1); - } - - // Register with the DirectInput subsystem and get a pointer to a - // IDirectInput interface we can use. Create a DInput object - if( FAILED( hr = (*pDInputCreate9)(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, - IID_IDirectInput9, (VOID**)&_pDInput9, nullptr ) ) ) { - wdxdisplay_cat.error() << DINPUTCREATE << "failed" << D3DERRORSTRING(hr); - return false; - } - - // enum all the joysticks,etc (but not keybdmouse) - if( FAILED( hr = _pDInput9->EnumDevices(DI9DEVCLASS_GAMECTRL, - EnumGameCtrlsCallback, - (LPVOID)&_DevInfos, DIEDFL_ATTACHEDONLY ) ) ) { - wdxdisplay_cat.error() << "EnumDevices failed" << D3DERRORSTRING(hr); - return false; - } - - return true; -} - -bool DInput9Info::CreateJoystickOrPad(HWND _window) { - bool bFoundDev = false; - UINT devnum=0; - char *errstr=nullptr; - - // look through the list for the first joystick or gamepad - for(;devnum<_DevInfos.size();devnum++) { - DWORD devType = GET_DIDEVICE_TYPE(_DevInfos[devnum].dwDevType); - if((devType==DI9DEVTYPE_GAMEPAD) ||(devType==DI9DEVTYPE_JOYSTICK)) { - bFoundDev=true; - break; - } - } - - if(!bFoundDev) { - wdxdisplay_cat.error() << "Cant find an attached Joystick or GamePad!\n"; - return false; - } - - LPDIRECTINPUTDEVICE9 pJoyDevice; - - // Obtain an interface to the enumerated joystick. - HRESULT hr = _pDInput9->CreateDevice(_DevInfos[devnum].guidInstance, &pJoyDevice, nullptr ); - if(FAILED(hr)) { - errstr="CreateDevice"; - goto handle_error; - } - - assert(pJoyDevice!=nullptr); - _DeviceList.push_back(pJoyDevice); - - // Set the data format to "simple joystick" - a predefined data format A - // data format specifies which controls on a device we are interested in, - // and how they should be reported. This tells DInput that we will be - // passing a DIJOYSTATE2 structure to - // IDirectInputDevice::GetDeviceState(). - hr = pJoyDevice->SetDataFormat(&c_dfDIJoystick2); - if(FAILED(hr)) { - errstr="SetDataFormat"; - goto handle_error; - } - - // must be called AFTER SetDataFormat to get all the proper flags - DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps); - hr = pJoyDevice->GetCapabilities(&DIDevCaps); - assert(SUCCEEDED(hr)); - - _DevCaps.push_back(DIDevCaps); - - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "Joy/Pad has " << DIDevCaps.dwAxes << " Axes, " << DIDevCaps.dwButtons << " Buttons, " << DIDevCaps.dwPOVs << " POVs" << endl; - - // Set the cooperative level to let DInput know how this device should - // interact with the system and with other DInput applications. - hr = pJoyDevice->SetCooperativeLevel( _window, DISCL_EXCLUSIVE | DISCL_FOREGROUND); - if(FAILED(hr)) { - errstr="SetCooperativeLevel"; - goto handle_error; - } - - // set the minmax values property for discovered axes. - hr = pJoyDevice->EnumObjects(EnumObjectsCallbackJoystick, (LPVOID)pJoyDevice, DIDFT_AXIS); - if(FAILED(hr)) { - errstr="EnumObjects"; - goto handle_error; - } - - return true; - - handle_error: - wdxdisplay_cat.error() << errstr << " failed for (" << _DevInfos[devnum].tszInstanceName << ":" << _DevInfos[devnum].tszProductName << ")" << D3DERRORSTRING(hr); - return false; -} - -// --------------------------------------------------------------------------- -// -- Name: EnumObjectsCallback() Desc: Callback function for enumerating -// objects (axes, buttons, POVs) on a joystick. This function enables user -// interface elements for objects that are found to exist, and scales axes -// minmax values. ----------------------------------------------------------- -// ------------------ -BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi, - VOID* pContext ) { - - LPDIRECTINPUTDEVICE9 pJoyDevice = (LPDIRECTINPUTDEVICE9) pContext; - HRESULT hr; - - // For axes that are returned, set the DIPROP_RANGE property for the - // enumerated axis in order to scale minmax values. - if( pdidoi->dwType & DIDFT_AXIS ) { - DIPROPRANGE diprg; - diprg.diph.dwSize = sizeof(DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYID; - diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis - - #ifdef AXIS_RANGE_CENTERED - diprg.lMin = -AXIS_RESOLUTION/2; - diprg.lMax = +AXIS_RESOLUTION/2; - #else - diprg.lMin = 0; - diprg.lMax = +AXIS_RESOLUTION; - #endif - - // Set the range for the axis - hr = pJoyDevice->SetProperty( DIPROP_RANGE, &diprg.diph); - if(FAILED(hr)) { - wdxdisplay_cat.error() << "SetProperty on axis failed" << D3DERRORSTRING(hr); - return DIENUM_STOP; - } - } - - return DIENUM_CONTINUE; -} - -bool DInput9Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) { - LPDIRECTINPUTDEVICE9 pJoystick = _DeviceList[devnum]; - assert(pJoystick!=nullptr); - HRESULT hr; - char *errstr; - - // Poll the device to read the current state - - hr = pJoystick->Poll(); - - if( FAILED(hr) ) { - // DInput is telling us that the input stream has been interrupted. - // We aren't tracking any state between polls, so we don't have any - // special reset that needs to be done. We just re-acquire and try - // again. - - if((hr==DIERR_NOTACQUIRED)||(hr == DIERR_INPUTLOST)) { - hr = pJoystick->Acquire(); - - if(FAILED(hr)) { - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "Acquire failed" << D3DERRORSTRING(hr); - - // hr may be DIERR_OTHERAPPHASPRIO or other errors. This may - // occur when the app is minimized or in the process of - // switching, so just try again later - return false; - } - - hr = pJoystick->Poll(); - if(FAILED(hr)) { - // should never happen! - errstr = "Poll after successful Acquire failed"; - goto handle_error; - } - } else { - errstr = "Unknown Poll failure"; - goto handle_error; - } - } - - // should we make a vector of devstate dataformats to generalize this fn - // for all device types? - - // Get the input's device state - hr = pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js); - if(FAILED(hr)) { - errstr = "GetDeviceState failed"; - goto handle_error; - } - - return true; - - handle_error: - wdxdisplay_cat.fatal() << errstr << D3DERRORSTRING(hr); - return false; -} diff --git a/panda/src/dxgsg9/dxInput9.h b/panda/src/dxgsg9/dxInput9.h deleted file mode 100644 index 9614a2627d..0000000000 --- a/panda/src/dxgsg9/dxInput9.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file dxInput9.h - * @author blllyjo - * @date 1999-10-07 - */ - -#ifndef DXINPUT9_H -#define DXINPUT9_H - -#define DIRECTINPUT_VERSION 0x900 -#include -typedef std::vector DI_DeviceInfos; -typedef std::vector DI_DeviceObjInfos; - -class DInput9Info { -public: - DInput9Info(); - ~DInput9Info(); - bool InitDirectInput(); - bool CreateJoystickOrPad(HWND _window); - bool ReadJoystick(int devnum, DIJOYSTATE2 &js); - - HINSTANCE _hDInputDLL; - UINT_PTR _JoystickPollTimer; - LPDIRECTINPUT8 _pDInput9; - DI_DeviceInfos _DevInfos; - // arrays for all created devices. Should probably put these together in a - // struct, along with the data fmt info - std::vector _DeviceList; - std::vector _DevCaps; -}; - -#endif diff --git a/panda/src/dxgsg9/dxgsg9base.h b/panda/src/dxgsg9/dxgsg9base.h index b0e2b9dfef..430876dff5 100644 --- a/panda/src/dxgsg9/dxgsg9base.h +++ b/panda/src/dxgsg9/dxgsg9base.h @@ -211,7 +211,6 @@ struct DXScreenData { bool _is_tnl_device; bool _can_use_hw_vertex_shaders; bool _can_use_pixel_shaders; - bool _is_dx9_1; UINT _supported_screen_depths_mask; UINT _supported_tex_formats_mask; bool _supports_rgba16f_texture_format; diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 6c85c6652f..8cb8b9782f 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -193,30 +193,10 @@ init() { } // Create a Direct3D object. + __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION); - // these were taken from the 8.0 and 8.1 d3d8.h SDK headers - __is_dx9_1 = false; - -#define D3D_SDK_VERSION_9_0 D3D_SDK_VERSION -#define D3D_SDK_VERSION_9_1 D3D_SDK_VERSION - - // are we using 9.0 or 9.1? - WIN32_FIND_DATA TempFindData; - HANDLE hFind; - char tmppath[_MAX_PATH + 128]; - GetSystemDirectory(tmppath, MAX_PATH); - strcat(tmppath, "\\dpnhpast.dll"); - hFind = FindFirstFile (tmppath, &TempFindData); - if (hFind != INVALID_HANDLE_VALUE) { - FindClose(hFind); -// ??? This was from DX8 __is_dx9_1 = true; - __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_1); - } else { - __is_dx9_1 = false; - __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_0); - } if (__d3d9 == nullptr) { - wdxdisplay9_cat.error() << "Direct3DCreate9(9." << (__is_dx9_1 ? "1" : "0") << ") failed!, error = " << GetLastError() << endl; + wdxdisplay9_cat.error() << "Direct3DCreate9 failed!, error = " << GetLastError() << endl; // release_gsg(); goto error; } @@ -361,11 +341,13 @@ find_all_card_memavails() { if (!ISPOW2(dwVidMemTotal)) { // assume they wont return a proper max value, so round up to next pow // of 2 - UINT count = 0; - while ((dwVidMemTotal >> count) != 0x0) { - count++; + int count = get_next_higher_bit((uint32_t)(dwVidMemTotal - 1u)); + if (count >= 32u) { + // Maximum value that fits in a UINT. + dwVidMemTotal = 0xffffffffu; + } else { + dwVidMemTotal = (1u << count); } - dwVidMemTotal = (1 << count); } } diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.h b/panda/src/dxgsg9/wdxGraphicsPipe9.h index 2d9eea18b0..ff25433e79 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.h +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.h @@ -93,7 +93,6 @@ private: typedef pvector CardIDs; CardIDs _card_ids; - bool __is_dx9_1; public: static TypeHandle get_class_type() { diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index 3207c81189..07a265a97c 100644 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -878,7 +878,7 @@ choose_device() { LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion; wdxdisplay9_cat.info() - << "D3D9." << (dxpipe->__is_dx9_1 ?"1":"0") << " Adapter[" << i << "]: " << adapter_info.Description + << "D3D9 Adapter[" << i << "]: " << adapter_info.Description << ", Driver: " << adapter_info.Driver << ", DriverVersion: (" << HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "." << HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart) @@ -979,7 +979,6 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) { nassertr(_dxgsg != nullptr, false); _wcontext._d3d9 = _d3d9; - _wcontext._is_dx9_1 = dxpipe->__is_dx9_1; _wcontext._card_id = device_info->cardID; // could this change by end? bool bWantStencil = (_fb_properties.get_stencil_bits() > 0); diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.h b/panda/src/dxgsg9/wdxGraphicsWindow9.h index 391fb9d7e9..42a6fe6763 100644 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.h +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.h @@ -17,7 +17,6 @@ #include "pandabase.h" #include "winGraphicsWindow.h" #include "dxGraphicsStateGuardian9.h" -#include "dxInput9.h" #include "wdxGraphicsPipe9.h" class wdxGraphicsPipe9; diff --git a/panda/src/event/asyncFuture_ext.h b/panda/src/event/asyncFuture_ext.h index 21786ee17b..94f0b3d60b 100644 --- a/panda/src/event/asyncFuture_ext.h +++ b/panda/src/event/asyncFuture_ext.h @@ -16,7 +16,7 @@ #include "extension.h" #include "py_panda.h" -#include "modelLoadRequest.h" +#include "asyncFuture.h" #ifdef HAVE_PYTHON diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 220bd56ed2..4b635b00e7 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2468,6 +2468,96 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { return true; } +/** + * Loads the shader from the given string(s). Returns a boolean indicating + * success or failure. + */ +bool Shader:: +load(const ShaderFile &sbody, BamCacheRecord *record) { + _filename = ShaderFile("created-shader"); + _fullpath = Filename(); + _text._separate = sbody._separate; + + if (sbody._separate) { + if (_language == SL_none) { + shader_cat.error() + << "No shader language was specified!\n"; + return false; + } + + if (!sbody._vertex.empty() && + !do_load_source(_text._vertex, sbody._vertex, record)) { + return false; + } + if (!sbody._fragment.empty() && + !do_load_source(_text._fragment, sbody._fragment, record)) { + return false; + } + if (!sbody._geometry.empty() && + !do_load_source(_text._geometry, sbody._geometry, record)) { + return false; + } + if (!sbody._tess_control.empty() && + !do_load_source(_text._tess_control, sbody._tess_control, record)) { + return false; + } + if (!sbody._tess_evaluation.empty() && + !do_load_source(_text._tess_evaluation, sbody._tess_evaluation, record)) { + return false; + } + if (!sbody._compute.empty() && + !do_load_source(_text._compute, sbody._compute, record)) { + return false; + } + + } else { + if (!do_load_source(_text._shared, sbody._shared, record)) { + return false; + } + + // Determine which language the shader is written in. + if (_language == SL_none) { + string header; + parse_init(); + parse_line(header, true, true); + if (header == "//Cg") { + _language = SL_Cg; + } else { + shader_cat.error() + << "Unable to determine shader language of " << sbody._shared << "\n"; + return false; + } + } else if (_language == SL_GLSL) { + shader_cat.error() + << "GLSL shaders must have separate shader bodies!\n"; + return false; + } + + // Determine which language the shader is written in. + if (_language == SL_Cg) { +#ifdef HAVE_CG + cg_get_profile_from_header(_default_caps); + + if (!cg_analyze_shader(_default_caps)) { + shader_cat.error() + << "Shader encountered an error.\n"; + return false; + } +#else + shader_cat.error() + << "Tried to load Cg shader, but no Cg support is enabled.\n"; +#endif + } else { + shader_cat.error() + << "Shader is not in a supported shader-language.\n"; + return false; + } + } + + _loaded = true; + return true; +} + /** * Reads the shader file from the given path into the given string. * @@ -2476,37 +2566,85 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { */ bool Shader:: do_read_source(string &into, const Filename &fn, BamCacheRecord *record) { + VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); + PT(VirtualFile) vf = vfs->find_file(fn, get_model_path()); + if (vf == nullptr) { + shader_cat.error() + << "Could not find shader file: " << fn << "\n"; + return false; + } + if (_language == SL_GLSL && glsl_preprocess) { - // Preprocess the GLSL file as we read it. - std::set open_files; - ostringstream sstr; - if (!r_preprocess_source(sstr, fn, Filename(), open_files, record)) { + istream *source = vf->open_read_file(true); + if (source == nullptr) { + shader_cat.error() + << "Could not open shader file: " << fn << "\n"; return false; } + + // Preprocess the GLSL file as we read it. + shader_cat.info() + << "Preprocessing shader file: " << fn << "\n"; + + std::set open_files; + ostringstream sstr; + if (!r_preprocess_source(sstr, *source, fn, vf->get_filename(), open_files, record)) { + vf->close_read_file(source); + return false; + } + vf->close_read_file(source); into = sstr.str(); } else { shader_cat.info() << "Reading shader file: " << fn << "\n"; - VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); - PT(VirtualFile) vf = vfs->find_file(fn, get_model_path()); - if (vf == nullptr) { - shader_cat.error() - << "Could not find shader file: " << fn << "\n"; - return false; - } - if (!vf->read_file(into, true)) { shader_cat.error() << "Could not read shader file: " << fn << "\n"; return false; } + } - if (record != nullptr) { - record->add_dependent_file(vf); + if (record != nullptr) { + record->add_dependent_file(vf); + } + + _last_modified = std::max(_last_modified, vf->get_timestamp()); + _source_files.push_back(vf->get_filename()); + + // Strip trailing whitespace. + while (!into.empty() && isspace(into[into.size() - 1])) { + into.resize(into.size() - 1); + } + + // Except add back a newline at the end, which is needed by Intel drivers. + into += "\n"; + + return true; +} + +/** + * Loads the shader file from the given string into the given string, + * performing any pre-processing on it that may be necessary. + * + * Returns false if there was an error with this shader bad enough to consider + * it 'invalid'. + */ +bool Shader:: +do_load_source(string &into, const std::string &source, BamCacheRecord *record) { + if (_language == SL_GLSL && glsl_preprocess) { + // Preprocess the GLSL file as we read it. + std::set open_files; + std::ostringstream sstr; + std::istringstream in(source); + if (!r_preprocess_source(sstr, in, Filename("created-shader"), Filename(), + open_files, record)) { + return false; } - _last_modified = std::max(_last_modified, vf->get_timestamp()); - _source_files.push_back(vf->get_filename()); + into = sstr.str(); + + } else { + into = source; } // Strip trailing whitespace. @@ -2528,10 +2666,10 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) { * recursive includes. */ bool Shader:: -r_preprocess_source(ostream &out, const Filename &fn, - const Filename &source_dir, - std::set &once_files, - BamCacheRecord *record, int depth) { +r_preprocess_include(ostream &out, const Filename &fn, + const Filename &source_dir, + std::set &once_files, + BamCacheRecord *record, int depth) { if (depth > glsl_include_recursion_limit) { shader_cat.error() @@ -2549,7 +2687,7 @@ r_preprocess_source(ostream &out, const Filename &fn, PT(VirtualFile) vf = vfs->find_file(fn, path); if (vf == nullptr) { shader_cat.error() - << "Could not find shader file: " << fn << "\n"; + << "Could not find shader include: " << fn << "\n"; return false; } @@ -2562,7 +2700,7 @@ r_preprocess_source(ostream &out, const Filename &fn, istream *source = vf->open_read_file(true); if (source == nullptr) { shader_cat.error() - << "Could not open shader file: " << fn << "\n"; + << "Could not open shader include: " << fn << "\n"; return false; } @@ -2578,34 +2716,52 @@ r_preprocess_source(ostream &out, const Filename &fn, // than that, unfortunately. Don't do this for the top-level file, though. // We don't want anything to get in before a potential #version directive. int fileno = 0; - if (depth > 0) { - fileno = 2048 + _included_files.size(); - // Write it into the vector so that we can substitute it later when we are - // parsing the GLSL error log. Don't store the full filename because it - // would just be too long to display. - _included_files.push_back(fn); + fileno = 2048 + _included_files.size(); - out << "#line 1 " << fileno << " // " << fn << "\n"; - if (shader_cat.is_debug()) { - shader_cat.debug() - << "Preprocessing shader include " << fileno << ": " << fn << "\n"; - } - } else { - shader_cat.info() - << "Preprocessing shader file: " << fn << "\n"; + // Write it into the vector so that we can substitute it later when we are + // parsing the GLSL error log. Don't store the full filename because it + // would just be too long to display. + _included_files.push_back(fn); + + if (shader_cat.is_debug()) { + shader_cat.debug() + << "Preprocessing shader include " << fileno << ": " << fn << "\n"; } + bool result = r_preprocess_source(out, *source, fn, full_fn, once_files, record, fileno, depth); + vf->close_read_file(source); + return result; +} + +/** + * Loads a given GLSL stream line by line, processing any #pragma include and + * once statements, as well as removing any comments. + * + * The set keeps track of which files we have already included, for checking + * recursive includes. + */ +bool Shader:: +r_preprocess_source(ostream &out, istream &in, const Filename &fn, + const Filename &full_fn, std::set &once_files, + BamCacheRecord *record, int fileno, int depth) { + // Iterate over the lines for things we may need to preprocess. string line; int ext_google_include = 0; // 1 = warn, 2 = enable int ext_google_line = 0; bool had_include = false; int lineno = 0; - while (std::getline(*source, line)) { + bool write_line_directive = (fileno != 0); + + while (std::getline(in, line)) { ++lineno; if (line.empty()) { - out.put('\n'); + // We still write a newline to make sure the line numbering remains + // consistent, unless we are about to write a #line directive anyway. + if (!write_line_directive) { + out.put('\n'); + } continue; } @@ -2615,9 +2771,11 @@ r_preprocess_source(ostream &out, const Filename &fn, line.resize(line.size() - 1); string line2; - if (std::getline(*source, line2)) { + if (std::getline(in, line2)) { line += line2; - out.put('\n'); + if (!write_line_directive) { + out.put('\n'); + } ++lineno; } else { break; @@ -2644,8 +2802,10 @@ r_preprocess_source(ostream &out, const Filename &fn, size_t block_end = line2.find("*/"); while (block_end == string::npos) { // Didn't find it - look in the next line. - if (std::getline(*source, line2)) { - out.put('\n'); + if (std::getline(in, line2)) { + if (!write_line_directive) { + out.put('\n'); + } ++lineno; block_end = line2.find("*/"); } else { @@ -2663,10 +2823,21 @@ r_preprocess_source(ostream &out, const Filename &fn, line.resize(line.size() - 1); } + if (line.empty()) { + if (!write_line_directive) { + out.put('\n'); + } + continue; + } + // Check if this line contains a #directive. char directive[64]; if (line.size() < 8 || sscanf(line.c_str(), " # %63s", directive) != 1) { // Nope. Just pass the line through unmodified. + if (write_line_directive) { + out << "#line " << lineno << " " << fileno << " // " << fn << "\n"; + write_line_directive = false; + } out << line << "\n"; continue; } @@ -2703,7 +2874,7 @@ r_preprocess_source(ostream &out, const Filename &fn, } // OK, great. Process the include. - if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) { + if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) { // An error occurred. Pass on the failure. shader_cat.error(false) << "included at line " << lineno << " of file " << fn << ":\n " << line << "\n"; @@ -2711,8 +2882,9 @@ r_preprocess_source(ostream &out, const Filename &fn, } // Restore the line counter. - out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n"; + write_line_directive = true; had_include = true; + continue; } else if (strcmp(pragma, "once") == 0) { // Do a stricter syntax check, just to be extra safe. @@ -2724,26 +2896,35 @@ r_preprocess_source(ostream &out, const Filename &fn, return false; } - once_files.insert(full_fn); + if (fileno == 0) { + shader_cat.warning() + << "#pragma once in main file at line " + << lineno << " of file " << fn +#ifndef NDEBUG + << ":\n " << line +#endif + << "\n"; + } - } else { - // Forward it, the driver will ignore it if it doesn't know it. - out << line << "\n"; + if (!full_fn.empty()) { + once_files.insert(full_fn); + } + continue; } + // Otherwise, just pass it through to the driver. } else if (strcmp(directive, "endif") == 0) { // Check for an #endif after an include. We have to restore the line // number in case the include happened under an #if block. - out << line << "\n"; if (had_include) { - out << "#line " << (lineno + 1) << " " << fileno << "\n"; + write_line_directive = true; } } else if (strcmp(directive, "extension") == 0) { // Check for special preprocessing extensions. char extension[256]; char behavior[9]; - if (sscanf(line.c_str(), " # extension%*[ \t]%255s%*[ \t]:%*[ \t]%8s", extension, behavior) == 2) { + if (sscanf(line.c_str(), " # extension%*[ \t]%255[^: \t] : %8s", extension, behavior) == 2) { // Parse the behavior string. int mode; if (strcmp(behavior, "require") == 0 || strcmp(behavior, "enable") == 0) { @@ -2769,7 +2950,8 @@ r_preprocess_source(ostream &out, const Filename &fn, } ext_google_include = mode; ext_google_line = mode; - out << line << "\n"; + // Still pass it through to the driver, so it can enable other + // extensions. } else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) { // Enable the Google extension support for #include statements. @@ -2777,14 +2959,12 @@ r_preprocess_source(ostream &out, const Filename &fn, // This matches the behavior of Khronos' glslang reference compiler. ext_google_include = mode; ext_google_line = mode; + continue; } else if (strcmp(extension, "GL_GOOGLE_cpp_style_line_directive") == 0) { // Enables strings in #line statements. ext_google_line = mode; - - } else { - // It's an extension the driver should worry about. - out << line << "\n"; + continue; } } else { shader_cat.error() @@ -2792,6 +2972,7 @@ r_preprocess_source(ostream &out, const Filename &fn, << lineno << " of file " << fn << ":\n " << line << "\n"; return false; } + } else if (ext_google_include > 0 && strcmp(directive, "include") == 0) { // Warn about extension use if requested. if (ext_google_include == 1) { @@ -2821,7 +3002,7 @@ r_preprocess_source(ostream &out, const Filename &fn, // OK, great. Process the include. Filename source_dir = full_fn.get_dirname(); - if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) { + if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) { // An error occurred. Pass on the failure. shader_cat.error(false) << "included at line " << lineno << " of file " << fn << ":\n " << line << "\n"; @@ -2829,8 +3010,9 @@ r_preprocess_source(ostream &out, const Filename &fn, } // Restore the line counter. - out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n"; + write_line_directive = true; had_include = true; + continue; } else if (ext_google_line > 0 && strcmp(directive, "line") == 0) { // It's a #line directive. See if it uses a string instead of number. @@ -2854,18 +3036,17 @@ r_preprocess_source(ostream &out, const Filename &fn, _included_files.push_back(Filename(filestr)); out << "#line " << lineno << " " << fileno << " // " << filestr << "\n"; - - } else { - // We couldn't parse the #line directive. Pass it through unmodified. - out << line << "\n"; + continue; } - } else { - // Different directive (eg. #version). Leave it untouched. - out << line << "\n"; } + + if (write_line_directive) { + out << "#line " << lineno << " " << fileno << " // " << fn << "\n"; + write_line_directive = false; + } + out << line << "\n"; } - vf->close_read_file(source); return true; } @@ -3227,28 +3408,26 @@ make(string body, ShaderLanguage lang) { if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); - shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); - -#ifdef HAVE_CG - if (lang == SL_Cg) { - shader->cg_get_profile_from_header(_default_caps); - - if (!shader->cg_analyze_shader(_default_caps)) { - shader_cat.error() - << "Shader encountered an error.\n"; - return nullptr; - } + if (!shader->load(sbody)) { + return nullptr; } -#endif if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } if (dump_generated_shaders) { @@ -3290,26 +3469,27 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry, if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); - -#ifdef HAVE_CG - if (lang == SL_Cg) { - if (!shader->cg_analyze_shader(_default_caps)) { - shader_cat.error() - << "Shader encountered an error.\n"; - return nullptr; - } + if (!shader->load(sbody)) { + return nullptr; } -#endif if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } return shader; @@ -3333,16 +3513,27 @@ make_compute(ShaderLanguage lang, string body) { if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); + if (!shader->load(sbody)) { + return nullptr; + } if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } return shader; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 67906210f6..35971b243b 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -616,11 +616,18 @@ private: Shader(ShaderLanguage lang); bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr); + bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr); bool do_read_source(std::string &into, const Filename &fn, BamCacheRecord *record); - bool r_preprocess_source(std::ostream &out, const Filename &fn, - const Filename &source_dir, + bool do_load_source(std::string &into, const std::string &source, BamCacheRecord *record); + bool r_preprocess_include(std::ostream &out, const Filename &fn, + const Filename &source_dir, + std::set &open_files, + BamCacheRecord *record, int depth); + bool r_preprocess_source(std::ostream &out, std::istream &in, + const Filename &fn, const Filename &full_fn, std::set &open_files, - BamCacheRecord *record, int depth = 0); + BamCacheRecord *record, + int fileno = 0, int depth = 0); bool check_modified() const; diff --git a/panda/src/pipeline/cycleData.h b/panda/src/pipeline/cycleData.h index ef21ad7a33..c2bcef4073 100644 --- a/panda/src/pipeline/cycleData.h +++ b/panda/src/pipeline/cycleData.h @@ -44,7 +44,7 @@ class EXPCL_PANDA_PIPELINE CycleData : public NodeReferenceCount // If we are *not* compiling in pipelining support, the CycleData object is // stored directly within its containing classes, and hence should not be a // ReferenceCount object. -class EXPCL_PANDA_PIPELINE CycleData +class EXPCL_PANDA_PIPELINE CycleData : public MemoryBase #endif // DO_PIPELINING { diff --git a/panda/src/windisplay/winDetectDx9.cxx b/panda/src/windisplay/winDetectDx9.cxx index 2e293950f6..4be10f0492 100644 --- a/panda/src/windisplay/winDetectDx9.cxx +++ b/panda/src/windisplay/winDetectDx9.cxx @@ -18,6 +18,7 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif +#undef Configure #include #include "graphicsStateGuardian.h" #include "graphicsPipe.h" diff --git a/pandatool/src/configfiles/pandatool.init b/pandatool/src/configfiles/pandatool.init deleted file mode 100644 index 615e010d42..0000000000 --- a/pandatool/src/configfiles/pandatool.init +++ /dev/null @@ -1 +0,0 @@ -ATTACH panda