Merge branch 'master' into cmake

This commit is contained in:
Sam Edwards 2018-11-01 22:33:04 -06:00
commit 62f7aabe91
20 changed files with 327 additions and 473 deletions

View File

@ -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

View File

@ -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);
}
/**

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}
}
/**

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}

View File

@ -93,7 +93,6 @@ private:
typedef pvector<CardID> CardIDs;
CardIDs _card_ids;
bool __is_dx9_1;
public:
static TypeHandle get_class_type() {

View File

@ -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);

View File

@ -17,7 +17,6 @@
#include "pandabase.h"
#include "winGraphicsWindow.h"
#include "dxGraphicsStateGuardian9.h"
#include "dxInput9.h"
#include "wdxGraphicsPipe9.h"
class wdxGraphicsPipe9;

View File

@ -16,7 +16,7 @@
#include "extension.h"
#include "py_panda.h"
#include "modelLoadRequest.h"
#include "asyncFuture.h"
#ifdef HAVE_PYTHON

View File

@ -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;

View File

@ -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;

View File

@ -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
{

View File

@ -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"

View File

@ -1 +0,0 @@
ATTACH panda