Merge branch 'master' into input-overhaul

This commit is contained in:
rdb 2018-10-08 01:25:33 +02:00
commit 14042faa3d
15 changed files with 388 additions and 29 deletions

View File

@ -43,8 +43,9 @@ Building Panda3D
Windows
-------
We currently build using the Microsoft Visual C++ 2015 compiler. You will
also need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk),
You can build Panda3D with the Microsoft Visual C++ 2015 or 2017 compiler,
which can be downloaded for free from the [Visual Studio site](https://visualstudio.microsoft.com/downloads/).
You will also need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk),
and if you intend to target Windows XP, you will also need the
[Windows 7.1 SDK](https://www.microsoft.com/en-us/download/details.aspx?id=8279).
@ -58,11 +59,12 @@ http://rdb.name/thirdparty-vc14-x64.7z
http://rdb.name/thirdparty-vc14.7z
After acquiring these dependencies, you may simply build Panda3D from the
command prompt using the following command. (Add the `--windows-sdk=10`
option if you don't need to support Windows XP.)
command prompt using the following command. (Change `14.1` to `14` if you are
using Visual C++ 2015 instead of 2017. Add the `--windows-sdk=10` option if
you don't need to support Windows XP and did not install the Windows 7.1 SDK.)
```bash
makepanda\makepanda.bat --everything --installer --no-eigen --threads=2
makepanda\makepanda.bat --everything --installer --msvc-version=14.1 --no-eigen --threads=2
```
When the build succeeds, it will produce an .exe file that you can use to
@ -101,7 +103,7 @@ If you are on Ubuntu, this command should cover the most frequently
used third-party packages:
```bash
sudo apt-get install build-essential pkg-config python-dev libpng-dev libjpeg-dev libtiff-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libeigen3-dev libopenal-dev libode-dev libbullet-dev nvidia-cg-toolkit libgtk2.0-dev
sudo apt-get install build-essential pkg-config python-dev libpng-dev libjpeg-dev libtiff-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libeigen3-dev libopenal-dev libode-dev libbullet-dev nvidia-cg-toolkit libgtk2.0-dev libassimp-dev libopenexr-dev
```
Once Panda3D has built, you can either install the .deb or .rpm package that
@ -163,6 +165,36 @@ python3.6 makepanda/makepanda.py --everything --installer --no-egl --no-gles --n
If successful, this will produce a .pkg file in the root of the source
directory which you can install using `pkg install`.
Android
-------
Note: building on Android is very experimental and not guaranteed to work.
You can experimentally build the Android Python runner via the [termux](https://termux.com/)
shell. You will need to install [Termux](https://play.google.com/store/apps/details?id=com.termux)
and [Termux API](https://play.google.com/store/apps/details?id=com.termux.api)
from the Play Store. Many of the dependencies can be installed by running the
following command in the Termux shell:
```bash
pkg install python-dev termux-tools ndk-stl ndk-sysroot clang libvorbis-dev libopus-dev opusfile-dev openal-soft-dev freetype-dev harfbuzz-dev libpng-dev ecj4.6 dx patchelf aapt apksigner libcrypt-dev
```
Then, you can build and install the .apk right away using these commands:
```bash
python makepanda/makepanda.py --everything --target android-21 --installer
xdg-open panda3d.apk
```
To launch a Python program from Termux, you can use the `run_python.sh` script
inside the `panda/src/android` directory. It will launch Python in a separate
activity, load it with the Python script you passed as argument, and use a
socket for returning the command-line output to the Termux shell. Do note
that this requires the Python application to reside on the SD card and that
Termux needs to be set up with access to the SD card (using the
`termux-setup-storage` command).
Running Tests
=============

View File

@ -2943,7 +2943,7 @@ define_method(CPPInstance *function, InterrogateType &itype,
// specifically flag get_class_type() as published.
bool force_publish = false;
if (function->get_simple_name() == "get_class_type" &&
(function->_storage_class && CPPInstance::SC_static) != 0 &&
(function->_storage_class & CPPInstance::SC_static) != 0 &&
function->_vis <= V_public) {
force_publish = true;
}

View File

@ -235,8 +235,8 @@ PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute) {
"'%.100s' object has no attribute '%.200s'",
Py_TYPE(obj)->tp_name, attribute);
Py_INCREF(PyExc_TypeError);
PyErr_Restore(PyExc_TypeError, message, nullptr);
Py_INCREF(PyExc_AttributeError);
PyErr_Restore(PyExc_AttributeError, message, nullptr);
return nullptr;
}

View File

@ -21,6 +21,11 @@
load-file-type egg pandaegg
# If we built with Assimp support, we can enable the Assimp loader,
# which allows us to load many model formats natively.
load-file-type p3assimp
# These entries work very similar to load-file-type, except they are
# used by the MovieVideo and MovieAudio code to determine which module
# should be loaded in order to decode files of the given extension.

View File

@ -2884,6 +2884,9 @@ else:
# otherwise, disable it.
confautoprc = confautoprc.replace('#st#', '#')
if PkgSkip("ASSIMP"):
confautoprc = confautoprc.replace("load-file-type p3assimp", "#load-file-type p3assimp")
if (os.path.isfile("makepanda/myconfig.in")):
configprc = ReadFile("makepanda/myconfig.in")
else:

View File

@ -593,8 +593,7 @@ remove_all_windows() {
Windows old_windows;
old_windows.swap(_windows);
Windows::iterator wi;
for (wi = old_windows.begin(); wi != old_windows.end(); ++wi) {
GraphicsOutput *win = (*wi);
for (GraphicsOutput *win : old_windows) {
nassertv(win != nullptr);
do_remove_window(win, current_thread);
GraphicsStateGuardian *gsg = win->get_gsg();
@ -605,6 +604,14 @@ remove_all_windows() {
{
MutexHolder new_windows_holder(_new_windows_lock, current_thread);
for (GraphicsOutput *win : _new_windows) {
nassertv(win != nullptr);
do_remove_window(win, current_thread);
GraphicsStateGuardian *gsg = win->get_gsg();
if (gsg != nullptr) {
gsg->release_all();
}
}
_new_windows.clear();
}

View File

@ -36,7 +36,8 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
_munge_color(false),
_munge_color_scale(false),
_auto_shader(false),
_shader_skinning(false)
_shader_skinning(false),
_remove_material(false)
{
const ShaderAttrib *shader_attrib;
state->get_attrib_def(shader_attrib);
@ -94,6 +95,19 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
// effort to detect this contrived situation and handle it correctly.
}
}
// If we have no lights but do have a material, we will need to remove it so
// that it won't appear when we enable color scale via lighting.
const LightAttrib *light_attrib;
const MaterialAttrib *material_attrib;
if (get_gsg()->get_color_scale_via_lighting() &&
(!state->get_attrib(light_attrib) || !light_attrib->has_any_on_light()) &&
state->get_attrib(material_attrib) &&
material_attrib->get_material() != nullptr &&
shader_attrib->get_shader() == nullptr) {
_remove_material = true;
_should_munge_state = true;
}
}
/**
@ -291,6 +305,9 @@ compare_to_impl(const GeomMunger *other) const {
if (_auto_shader != om->_auto_shader) {
return (int)_auto_shader - (int)om->_auto_shader;
}
if (_remove_material != om->_remove_material) {
return (int)_remove_material - (int)om->_remove_material;
}
return StateMunger::compare_to_impl(other);
}
@ -344,5 +361,9 @@ munge_state_impl(const RenderState *state) {
munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_slot());
}
if (_remove_material) {
munged_state = munged_state->remove_attrib(MaterialAttrib::get_class_slot());
}
return munged_state;
}

View File

@ -55,6 +55,7 @@ private:
bool _munge_color_scale;
bool _auto_shader;
bool _shader_skinning;
bool _remove_material;
LColor _color;
LVecBase4 _color_scale;

View File

@ -99,6 +99,27 @@ PUBLISHED:
virtual void output(std::ostream &out) const;
PUBLISHED:
MAKE_PROPERTY(state, get_state);
MAKE_PROPERTY(alive, is_alive);
MAKE_PROPERTY(manager, get_manager);
// The name of this task.
MAKE_PROPERTY(name, get_name, set_name);
// This is a number guaranteed to be unique for each different AsyncTask
// object in the universe.
MAKE_PROPERTY(id, get_task_id);
MAKE_PROPERTY(task_chain, get_task_chain, set_task_chain);
MAKE_PROPERTY(sort, get_sort, set_sort);
MAKE_PROPERTY(priority, get_priority, set_priority);
MAKE_PROPERTY(done_event, get_done_event, set_done_event);
MAKE_PROPERTY(dt, get_dt);
MAKE_PROPERTY(max_dt, get_max_dt);
MAKE_PROPERTY(average_dt, get_average_dt);
protected:
void jump_to_task_chain(AsyncTaskManager *manager);
DoneStatus unlock_and_do_task();

View File

@ -61,9 +61,6 @@ PUBLISHED:
int __clear__();
PUBLISHED:
// The name of this task.
MAKE_PROPERTY(name, get_name, set_name);
// The amount of seconds that have elapsed since the task was started,
// according to the task manager's clock.
MAKE_PROPERTY(time, get_elapsed_time);
@ -88,10 +85,6 @@ PUBLISHED:
// according to the task manager's clock.
MAKE_PROPERTY(frame, get_elapsed_frames);
// This is a number guaranteed to be unique for each different AsyncTask
// object in the universe.
MAKE_PROPERTY(id, get_task_id);
// This is a special variable to hold the instance dictionary in which
// custom variables may be stored.
PyObject *__dict__;

View File

@ -283,6 +283,13 @@ begin_frame(FrameMode mode, Thread *current_thread) {
rebuild_bitplanes();
}
// The host window may not have had sRGB enabled, so we need to do this.
#ifndef OPENGLES
if (get_fb_properties().get_srgb_color()) {
glEnable(GL_FRAMEBUFFER_SRGB);
}
#endif
_gsg->set_current_properties(&get_fb_properties());
report_my_gl_errors();
return true;

View File

@ -69,14 +69,12 @@ PUBLISHED:
};
private:
enum {
// Period parameters
N = 624,
M = 397,
MATRIX_A = 0x9908b0dfUL, // constant vector a
UPPER_MASK = 0x80000000UL, // most significant w-r bits
LOWER_MASK = 0x7fffffffUL, // least significant r bits
};
// Period parameters
static const unsigned long N = 624;
static const unsigned long M = 397;
static const unsigned long MATRIX_A = 0x9908b0dfUL; // constant vector a
static const unsigned long UPPER_MASK = 0x80000000UL; // most significant w-r bits
static const unsigned long LOWER_MASK = 0x7fffffffUL; // least significant r bits
unsigned long mt[N]; // the array for the state vector
unsigned int mti; // mti==N+1 means mt[N] is not initialized

View File

@ -12,10 +12,12 @@
*/
#include "movieTypeRegistry.h"
#include "string_utils.h"
#include "config_movies.h"
#include "config_putil.h"
#include "load_dso.h"
#include "reMutexHolder.h"
using std::endl;
using std::string;

View File

@ -0,0 +1,271 @@
from panda3d import core
import pytest
TEST_COLOR = core.LColor(1, 127/255.0, 0, 127/255.0)
TEST_COLOR_SCALE = core.LVecBase4(0.5, 0.5, 0.5, 0.5)
TEST_SCALED_COLOR = core.LColor(TEST_COLOR)
TEST_SCALED_COLOR.componentwise_mult(TEST_COLOR_SCALE)
FUZZ = 0.02
@pytest.fixture(scope='session', params=[False, True], ids=["shader:off", "shader:auto"])
def shader_attrib(request):
"""Returns two ShaderAttribs: one with auto shader, one without."""
if request.param:
return core.ShaderAttrib.make_default().set_shader_auto(True)
else:
return core.ShaderAttrib.make_off()
@pytest.fixture(scope='session', params=["mat:off", "mat:empty", "mat:amb", "mat:diff", "mat:both"])
def material_attrib(request):
"""Returns two MaterialAttribs: one with material, one without. It
shouldn't really matter what we set them to, since the tests in here do
not use lighting, and therefore the material should be ignored."""
if request.param == "mat:off":
return core.MaterialAttrib.make_off()
elif request.param == "mat:empty":
return core.MaterialAttrib.make(core.Material())
elif request.param == "mat:amb":
mat = core.Material()
mat.ambient = (0.1, 1, 0.5, 1)
return core.MaterialAttrib.make(mat)
elif request.param == "mat:diff":
mat = core.Material()
mat.diffuse = (0.1, 1, 0.5, 1)
return core.MaterialAttrib.make(mat)
elif request.param == "mat:both":
mat = core.Material()
mat.diffuse = (0.1, 1, 0.5, 1)
mat.ambient = (0.1, 1, 0.5, 1)
return core.MaterialAttrib.make(mat)
@pytest.fixture(scope='module', params=[False, True], ids=["srgb:off", "srgb:on"])
def color_region(request, graphics_pipe):
"""Creates and returns a DisplayRegion with a depth buffer."""
engine = core.GraphicsEngine()
engine.set_threading_model("")
host_fbprops = core.FrameBufferProperties()
host_fbprops.force_hardware = True
host = engine.make_output(
graphics_pipe,
'host',
0,
host_fbprops,
core.WindowProperties.size(32, 32),
core.GraphicsPipe.BF_refuse_window,
)
engine.open_windows()
if host is None:
pytest.skip("GraphicsPipe cannot make offscreen buffers")
fbprops = core.FrameBufferProperties()
fbprops.force_hardware = True
fbprops.set_rgba_bits(8, 8, 8, 8)
fbprops.srgb_color = request.param
buffer = engine.make_output(
graphics_pipe,
'buffer',
0,
fbprops,
core.WindowProperties.size(32, 32),
core.GraphicsPipe.BF_refuse_window,
host.gsg,
host
)
engine.open_windows()
if buffer is None:
pytest.skip("Cannot make color buffer")
if fbprops.srgb_color != buffer.get_fb_properties().srgb_color:
pytest.skip("Cannot make buffer with required srgb_color setting")
buffer.set_clear_color_active(True)
buffer.set_clear_color((0, 0, 0, 1))
yield buffer.make_display_region()
if buffer is not None:
engine.remove_window(buffer)
def render_color_pixel(region, state, vertex_color=None):
"""Renders a fragment using the specified render settings, and returns the
resulting color value."""
# Set up the scene with a blank card rendering at specified distance.
scene = core.NodePath("root")
scene.set_attrib(core.DepthTestAttrib.make(core.RenderAttrib.M_always))
camera = scene.attach_new_node(core.Camera("camera"))
camera.node().get_lens(0).set_near_far(1, 3)
camera.node().set_cull_bounds(core.OmniBoundingVolume())
cm = core.CardMaker("card")
cm.set_frame(-1, 1, -1, 1)
if vertex_color is not None:
cm.set_color(vertex_color)
card = scene.attach_new_node(cm.generate())
card.set_state(state)
card.set_pos(0, 2, 0)
card.set_scale(60)
region.active = True
region.camera = camera
color_texture = core.Texture("color")
region.window.add_render_texture(color_texture,
core.GraphicsOutput.RTM_copy_ram,
core.GraphicsOutput.RTP_color)
region.window.engine.render_frame()
region.window.clear_render_textures()
col = core.LColor()
color_texture.peek().lookup(col, 0.5, 0.5)
return col
def test_color_write_mask(color_region):
state = core.RenderState.make(
core.ColorWriteAttrib.make(core.ColorWriteAttrib.C_green),
)
result = render_color_pixel(color_region, state)
assert result == (0, 1, 0, 1)
def test_color_empty(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state)
assert result == (1, 1, 1, 1)
def test_color_off(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorAttrib.make_off(),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state)
assert result == (1, 1, 1, 1)
def test_color_flat(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorAttrib.make_flat(TEST_COLOR),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state)
assert result.almost_equal(TEST_COLOR, FUZZ)
def test_color_vertex(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorAttrib.make_vertex(),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
assert result.almost_equal(TEST_COLOR, FUZZ)
def test_color_empty_vertex(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
assert result.almost_equal(TEST_COLOR, FUZZ)
def test_color_off_vertex(color_region, shader_attrib, material_attrib):
#XXX This behaviour is really odd.
state = core.RenderState.make(
core.ColorAttrib.make_off(),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
assert result.almost_equal(TEST_COLOR, FUZZ)
def test_scaled_color_empty(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state)
assert result == (1, 1, 1, 1)
def test_scaled_color_off(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorAttrib.make_off(),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state)
assert result == (1, 1, 1, 1)
def test_scaled_color_flat(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorAttrib.make_flat(TEST_COLOR),
core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state)
assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
def test_scaled_color_vertex(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorAttrib.make_vertex(),
core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
def test_scaled_color_empty_vertex(color_region, shader_attrib, material_attrib):
state = core.RenderState.make(
core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
def test_scaled_color_off_vertex(color_region, shader_attrib, material_attrib):
#XXX This behaviour is really odd.
state = core.RenderState.make(
core.ColorAttrib.make_off(),
core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
shader_attrib,
material_attrib,
)
result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)

View File

@ -91,8 +91,6 @@ def render_depth_pixel(region, distance, near, far, clear=None, write=True):
region.window.engine.render_frame()
region.window.clear_render_textures()
depth_texture.write("test2.png")
col = core.LColor()
depth_texture.peek().lookup(col, 0.5, 0.5)
return col[0]