mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Merge branch 'master' into cmake
This commit is contained in:
commit
62f7aabe91
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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 <<endl;
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
extern BOOL CALLBACK EnumObjectsCallbackJoystick(const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext);
|
||||
|
||||
DInput9Info::DInput9Info() {
|
||||
_pDInput9 = nullptr;
|
||||
_hDInputDLL = nullptr;
|
||||
_JoystickPollTimer = nullptr;
|
||||
}
|
||||
|
||||
DInput9Info::~DInput9Info() {
|
||||
for(UINT i=0;i<_DeviceList.size();i++) {
|
||||
_DeviceList[i]->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;
|
||||
}
|
@ -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 <dinput.h>
|
||||
typedef std::vector<DIDEVICEINSTANCE> DI_DeviceInfos;
|
||||
typedef std::vector<DIDEVICEOBJECTINSTANCE> 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<LPDIRECTINPUTDEVICE8> _DeviceList;
|
||||
std::vector<DIDEVCAPS> _DevCaps;
|
||||
};
|
||||
|
||||
#endif
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,6 @@ private:
|
||||
|
||||
typedef pvector<CardID> CardIDs;
|
||||
CardIDs _card_ids;
|
||||
bool __is_dx9_1;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -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);
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "pandabase.h"
|
||||
#include "winGraphicsWindow.h"
|
||||
#include "dxGraphicsStateGuardian9.h"
|
||||
#include "dxInput9.h"
|
||||
#include "wdxGraphicsPipe9.h"
|
||||
|
||||
class wdxGraphicsPipe9;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "extension.h"
|
||||
#include "py_panda.h"
|
||||
#include "modelLoadRequest.h"
|
||||
#include "asyncFuture.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
|
@ -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<Filename> 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<Filename> 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<Filename> 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<Filename> &once_files,
|
||||
BamCacheRecord *record, int depth) {
|
||||
r_preprocess_include(ostream &out, const Filename &fn,
|
||||
const Filename &source_dir,
|
||||
std::set<Filename> &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<Filename> &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;
|
||||
|
@ -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<Filename> &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<Filename> &open_files,
|
||||
BamCacheRecord *record, int depth = 0);
|
||||
BamCacheRecord *record,
|
||||
int fileno = 0, int depth = 0);
|
||||
|
||||
bool check_modified() const;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -18,6 +18,7 @@
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#undef Configure
|
||||
#include <d3d9.h>
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "graphicsPipe.h"
|
||||
|
@ -1 +0,0 @@
|
||||
ATTACH panda
|
Loading…
x
Reference in New Issue
Block a user