Merge branch 'master' into cmake

This commit is contained in:
Sam Edwards 2015-11-11 12:35:13 -08:00
commit b1a294631a
18 changed files with 316 additions and 77 deletions

View File

@ -4,6 +4,7 @@ from panda3d.core import *
from panda3d.direct import *
from direct.task import Task
from direct.showbase.DirectObject import DirectObject
from direct.directnotify.DirectNotifyGlobal import directNotify
def remove_task ( ):

View File

@ -3361,7 +3361,7 @@ class Packager:
self.currentPackage.addExtensionModules()
self.currentPackage.freezer.reset()
self.do_file('panda3d/_core.pyd', newDir='panda3d')
self.do_file('panda3d/core.pyd', newDir='panda3d')
# This is the key Python module that is imported at runtime to
# start an application running.

View File

@ -193,7 +193,7 @@ run_python() {
return 1;
}
// Set the __path__ such that it can find panda3d/_core.pyd, etc.
// Set the __path__ such that it can find panda3d/core.pyd, etc.
Filename panda3d_dir(dir, "panda3d");
string dir_str = panda3d_dir.to_os_specific();
PyModule_AddObject(panda3d_module, "__path__", Py_BuildValue("[s#]", dir_str.data(), dir_str.length()));

View File

@ -1,7 +1,7 @@
__all__ = ['register', 'sharedPackages',
'reloadSharedPackage', 'reloadSharedPackages']
from panda3d._core import Filename, VirtualFileSystem, VirtualFileMountSystem, OFileStream, copyStream
from panda3d.core import Filename, VirtualFileSystem, VirtualFileMountSystem, OFileStream, copyStream
import sys
import marshal
import imp

View File

@ -10,7 +10,7 @@ __all__ = [
'execfile',
]
import panda3d._core as core
from panda3d import core
import sys
import os
import io

View File

@ -19,6 +19,7 @@
#include "cppDeclaration.h"
#include "cppIdentifier.h"
#include "cppFunctionGroup.h"
///////////////////////////////////////////////////////////////////
// Class : CPPMakeSeq

View File

@ -3008,15 +3008,8 @@ close_gsg() {
// will be responsible for cleaning up anything we don't clean up
// explicitly. We'll just let them drop.
// However, if any objects have recently been released, we have to
// ensure they are actually deleted properly.
Thread *current_thread = Thread::get_current_thread();
_prepared_objects->begin_frame(this, current_thread);
_prepared_objects->end_frame(current_thread);
// We have to clear the list of timer queries, though, otherwise
// their destructors will cause a crash when they try to access
// the GSG object.
// Make sure that all the contexts belonging to the GSG are deleted.
_prepared_objects.clear();
#ifdef DO_PSTATS
_pending_timer_queries.clear();
#endif

View File

@ -409,20 +409,19 @@ rebuild_bitplanes() {
// Now create the FBO's.
_have_any_color = false;
_fbo.reserve(num_fbos);
for (int layer = 0; layer < num_fbos; ++layer) {
if (layer >= _fbo.size()) {
_fbo.push_back(0);
}
if (num_fbos > _fbo.size()) {
// Generate more FBO handles.
int start = _fbo.size();
_fbo.resize(num_fbos, 0);
glgsg->_glGenFramebuffers(num_fbos - start, &_fbo[start]);
}
for (int layer = 0; layer < num_fbos; ++layer) {
// Bind the FBO
if (_fbo[layer] == 0) {
glgsg->_glGenFramebuffers(1, &_fbo[layer]);
if (_fbo[layer] == 0) {
report_my_gl_errors();
return;
}
report_my_gl_errors();
return;
}
glgsg->bind_fbo(_fbo[layer]);
@ -1118,11 +1117,7 @@ generate_mipmaps() {
CLP(TextureContext) *gtc = *it;
if (gtc->_generate_mipmaps) {
glgsg->_state_texture = 0;
glgsg->update_texture(gtc, true);
glgsg->apply_texture(gtc);
glgsg->_glGenerateMipmap(gtc->_target);
glBindTexture(gtc->_target, 0);
glgsg->generate_mipmaps(gtc);
}
}

View File

@ -284,12 +284,14 @@ fix_component_ordering(PTA_uchar &new_image,
case GL_RGB:
switch (tex->get_component_type()) {
case Texture::T_unsigned_byte:
case Texture::T_byte:
new_image = PTA_uchar::empty_array(orig_image_size);
uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
result = new_image;
break;
case Texture::T_unsigned_short:
case Texture::T_short:
new_image = PTA_uchar::empty_array(orig_image_size);
ushort_bgr_to_rgb((unsigned short *)new_image.p(),
(const unsigned short *)orig_image,
@ -305,12 +307,14 @@ fix_component_ordering(PTA_uchar &new_image,
case GL_RGBA:
switch (tex->get_component_type()) {
case Texture::T_unsigned_byte:
case Texture::T_byte:
new_image = PTA_uchar::empty_array(orig_image_size);
uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
result = new_image;
break;
case Texture::T_unsigned_short:
case Texture::T_short:
new_image = PTA_uchar::empty_array(orig_image_size);
ushort_bgra_to_rgba((unsigned short *)new_image.p(),
(const unsigned short *)orig_image,
@ -1873,6 +1877,15 @@ reset() {
#endif // OPENGLES
#endif
#ifndef OPENGLES
if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) {
_glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)
get_extension_func("glGenerateTextureMipmap");
} else {
_glGenerateTextureMipmap = NULL;
}
#endif
_supports_framebuffer_multisample = false;
if ( has_extension("GL_EXT_framebuffer_multisample") ) {
_supports_framebuffer_multisample = true;
@ -4685,6 +4698,13 @@ void CLP(GraphicsStateGuardian)::
release_texture(TextureContext *tc) {
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
#ifndef OPENGLES
_textures_needing_fetch_barrier.erase(gtc);
_textures_needing_image_access_barrier.erase(gtc);
_textures_needing_update_barrier.erase(gtc);
_textures_needing_framebuffer_barrier.erase(gtc);
#endif
glDeleteTextures(1, &gtc->_index);
if (gtc->_buffer != 0) {
@ -7808,6 +7828,10 @@ get_component_type(Texture::ComponentType component_type) {
#ifndef OPENGLES_1
return GL_INT;
#endif
case Texture::T_byte:
return GL_BYTE;
case Texture::T_short:
return GL_SHORT;
default:
GLCAT.error() << "Invalid Texture::Type value!\n";
return GL_UNSIGNED_BYTE;
@ -8432,6 +8456,10 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
#ifndef OPENGLES
if (tex->get_component_type() == Texture::T_unsigned_short) {
return GL_RGBA16;
} else if (tex->get_component_type() == Texture::T_short) {
return GL_RGBA16_SNORM;
} else if (tex->get_component_type() == Texture::T_byte) {
return GL_RGBA8_SNORM;
} else
#endif
{
@ -8448,27 +8476,32 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
return force_sized ? GL_RGBA8 : GL_RGBA;
#else
case Texture::F_rgba8:
return GL_RGBA8;
if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGBA8;
} else {
return GL_RGBA8_SNORM;
}
case Texture::F_r8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) {
if (Texture::is_unsigned(tex->get_component_type())) {
return GL_R8UI;
} else {
return GL_R8I;
}
case Texture::F_rg8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) {
if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RG8UI;
} else {
return GL_RG8I;
}
case Texture::F_rgb8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) {
if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGB8UI;
} else {
return GL_RGB8I;
}
case Texture::F_rgba8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) {
if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGBA8UI;
} else {
return GL_RGBA8I;
@ -8480,17 +8513,24 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_rgba16:
if (tex->get_component_type() == Texture::T_float) {
return GL_RGBA16F;
} else {
} else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGBA16;
} else {
return GL_RGBA16_SNORM;
}
case Texture::F_rgba32:
return GL_RGBA32F;
#endif // OPENGLES
case Texture::F_rgb:
if (tex->get_component_type() == Texture::T_float) {
return GL_RGB16F;
} else {
switch (tex->get_component_type()) {
case Texture::T_float: return GL_RGB16F;
#ifndef OPENGLES
case Texture::T_unsigned_short: return GL_RGB16;
case Texture::T_short: return GL_RGB16_SNORM;
case Texture::T_byte: return GL_RGB8_SNORM;
#endif
default:
return force_sized ? GL_RGB8 : GL_RGB;
}
@ -8513,14 +8553,20 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
return GL_RGB16F;
#else
case Texture::F_rgb8:
return GL_RGB8;
if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGB8;
} else {
return GL_RGB8_SNORM;
}
case Texture::F_rgb12:
return GL_RGB12;
case Texture::F_rgb16:
if (tex->get_component_type() == Texture::T_float) {
return GL_RGB16F;
} else {
} else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGB16;
} else {
return GL_RGB16_SNORM;
}
#endif // OPENGLES
case Texture::F_rgb32:
@ -8540,14 +8586,18 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_r16:
if (tex->get_component_type() == Texture::T_float) {
return GL_R16F;
} else {
} else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_R16;
} else {
return GL_R16_SNORM;
}
case Texture::F_rg16:
if (tex->get_component_type() == Texture::T_float) {
return GL_RG16F;
} else {
} else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RG16;
} else {
return GL_RG16_SNORM;
}
#endif
@ -8560,7 +8610,14 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_red:
case Texture::F_green:
case Texture::F_blue:
return force_sized ? GL_R8 : GL_RED;
#ifndef OPENGLES
if (!Texture::is_unsigned(tex->get_component_type())) {
return GL_R8_SNORM;
} else
#endif
{
return force_sized ? GL_R8 : GL_RED;
}
#endif
case Texture::F_alpha:
@ -8574,6 +8631,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
#ifndef OPENGLES
if (tex->get_component_type() == Texture::T_float) {
return GL_LUMINANCE16F_ARB;
} else if (tex->get_component_type() == Texture::T_short) {
return GL_LUMINANCE16_SNORM;
} else if (tex->get_component_type() == Texture::T_unsigned_short) {
return GL_LUMINANCE16;
} else
@ -11710,6 +11769,31 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::generate_mipmaps
// Access: Protected
// Description: Causes mipmaps to be generated for an uploaded
// texture.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
generate_mipmaps(CLP(TextureContext) *gtc) {
#ifndef OPENGLES
if (_glGenerateTextureMipmap != NULL) {
// OpenGL 4.5 offers an easy way to do this without binding.
_glGenerateTextureMipmap(gtc->_index);
return;
}
#endif
if (_glGenerateMipmap != NULL) {
_state_texture = 0;
update_texture(gtc, true);
apply_texture(gtc);
_glGenerateMipmap(gtc->_target);
glBindTexture(gtc->_target, 0);
}
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::upload_simple_texture
// Access: Protected
@ -12117,15 +12201,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
break;
case GL_R8I:
type = Texture::T_byte;
format = Texture::F_r8i;
break;
case GL_RG8I:
type = Texture::T_byte;
format = Texture::F_rg8i;
break;
case GL_RGB8I:
type = Texture::T_byte;
format = Texture::F_rgb8i;
break;
case GL_RGBA8I:
type = Texture::T_byte;
format = Texture::F_rgba8i;
break;
@ -12195,6 +12283,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
type = Texture::T_unsigned_short;
format = Texture::F_r16;
break;
case GL_RGB16_SNORM:
type = Texture::T_short;
format = Texture::F_rgb16;
break;
case GL_RG16_SNORM:
type = Texture::T_short;
format = Texture::F_rg16;
break;
case GL_R16_SNORM:
type = Texture::T_short;
format = Texture::F_r16;
break;
#endif
#ifndef OPENGLES

View File

@ -546,6 +546,7 @@ protected:
GLenum component_type,
bool one_page_only, int z,
Texture::CompressionMode image_compression);
void generate_mipmaps(CLP(TextureContext) *gtc);
bool upload_simple_texture(CLP(TextureContext) *gtc);
size_t get_texture_memory_size(CLP(TextureContext) *gtc);
@ -794,6 +795,10 @@ public:
PFNGLGENERATEMIPMAPEXTPROC _glGenerateMipmap;
PFNGLBINDPROGRAMARBPROC _glBindProgram;
#ifndef OPENGLES
PFNGLGENERATETEXTUREMIPMAPPROC _glGenerateTextureMipmap;
#endif
bool _supports_framebuffer_multisample;
bool _supports_framebuffer_multisample_coverage_nv;
INLINE bool get_supports_framebuffer_multisample();

View File

@ -2479,6 +2479,15 @@ glsl_report_program_errors(GLuint program, bool fatal) {
////////////////////////////////////////////////////////////////////
bool CLP(ShaderContext)::
glsl_compile_shader(Shader::ShaderType type) {
static const char *types[] = {"", "vertex ", "fragment ", "geometry ",
"tessellation control ", "tessellation evaluation ", "compute ", ""};
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Compiling GLSL " << types[type] << "shader "
<< _shader->get_filename(type) << "\n";
}
GLuint handle = 0;
switch (type) {
case Shader::ST_vertex:
@ -2514,7 +2523,7 @@ glsl_compile_shader(Shader::ShaderType type) {
}
if (!handle) {
GLCAT.error()
<< "Could not create a GLSL shader of the requested type.\n";
<< "Could not create a GLSL " << types[type] << "shader.\n";
_glgsg->report_my_gl_errors();
return false;
}
@ -2533,8 +2542,8 @@ glsl_compile_shader(Shader::ShaderType type) {
if (status != GL_TRUE) {
GLCAT.error()
<< "An error occurred while compiling GLSL shader "
<< _shader->get_filename(type) << ":\n";
<< "An error occurred while compiling GLSL " << types[type]
<< "shader " << _shader->get_filename(type) << ":\n";
glsl_report_shader_errors(handle, type, true);
_glgsg->_glDeleteShader(handle);
_glgsg->report_my_gl_errors();
@ -2629,12 +2638,18 @@ glsl_compile_and_link() {
}
#endif
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Linking GLSL shader " << _shader->get_filename() << "\n";
}
_glgsg->_glLinkProgram(_glsl_program);
GLint status;
_glgsg->_glGetProgramiv(_glsl_program, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
GLCAT.error() << "An error occurred while linking GLSL shader program!\n";
GLCAT.error() << "An error occurred while linking GLSL shader "
<< _shader->get_filename() << "\n";
glsl_report_program_errors(_glsl_program, true);
return false;
}

View File

@ -23,15 +23,6 @@ TypeHandle CLP(TextureContext)::_type_handle;
////////////////////////////////////////////////////////////////////
CLP(TextureContext)::
~CLP(TextureContext)() {
#ifndef OPENGLES
if (gl_enable_memory_barriers) {
_glgsg->_textures_needing_fetch_barrier.erase(this);
_glgsg->_textures_needing_image_access_barrier.erase(this);
_glgsg->_textures_needing_update_barrier.erase(this);
_glgsg->_textures_needing_framebuffer_barrier.erase(this);
}
#endif
// Don't call glDeleteTextures; we may not have an active context.
}

View File

@ -1552,10 +1552,12 @@ write(ostream &out, int indent_level) const {
switch (cdata->_component_type) {
case T_unsigned_byte:
case T_byte:
out << " bytes";
break;
case T_unsigned_short:
case T_short:
out << " shorts";
break;
@ -2001,6 +2003,10 @@ format_component_type(ComponentType ct) {
return "unsigned_int_24_8";
case T_int:
return "int";
case T_byte:
return "unsigned_byte";
case T_short:
return "short";
}
return "**invalid**";
@ -2024,6 +2030,10 @@ string_component_type(const string &str) {
return T_unsigned_int_24_8;
} else if (cmp_nocase(str, "int") == 0) {
return T_int;
} else if (cmp_nocase(str, "byte") == 0) {
return T_byte;
} else if (cmp_nocase(str, "short") == 0) {
return T_short;
}
gobj_cat->error()
@ -2411,6 +2421,19 @@ make_texture() {
return new Texture;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::is_unsigned
// Access: Public, Static
// Description: Returns true if the indicated component type is
// unsigned, false otherwise.
////////////////////////////////////////////////////////////////////
bool Texture::
is_unsigned(Texture::ComponentType ctype) {
return (ctype == T_unsigned_byte ||
ctype == T_unsigned_short ||
ctype == T_unsigned_int_24_8);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::is_specific
// Access: Public, Static
@ -4525,6 +4548,48 @@ do_get_clear_data(const CData *cdata, unsigned char *into) const {
}
break;
}
case T_byte:
{
LColor scaled = cdata->_clear_color.fmin(LColor(1)).fmax(LColor(-1));
scaled *= 127;
switch (cdata->_num_components) {
case 2:
into[1] = (char)scaled[1];
case 1:
into[0] = (char)scaled[0];
break;
case 4:
into[3] = (char)scaled[3];
case 3: // BGR <-> RGB
into[0] = (char)scaled[2];
into[1] = (char)scaled[1];
into[2] = (char)scaled[0];
break;
}
break;
}
case T_short:
{
LColor scaled = cdata->_clear_color.fmin(LColor(1)).fmax(LColor(-1));
scaled *= 32767;
switch (cdata->_num_components) {
case 2:
((short *)into)[1] = (short)scaled[1];
case 1:
((short *)into)[0] = (short)scaled[0];
break;
case 4:
((short *)into)[3] = (short)scaled[3];
case 3: // BGR <-> RGB
((short *)into)[0] = (short)scaled[2];
((short *)into)[1] = (short)scaled[1];
((short *)into)[2] = (short)scaled[0];
break;
}
break;
}
}
return cdata->_num_components * cdata->_component_width;
@ -5222,10 +5287,12 @@ do_set_component_type(CData *cdata, Texture::ComponentType component_type) {
switch (component_type) {
case T_unsigned_byte:
case T_byte:
cdata->_component_width = 1;
break;
case T_unsigned_short:
case T_short:
cdata->_component_width = 2;
break;

View File

@ -93,6 +93,8 @@ PUBLISHED:
T_float,
T_unsigned_int_24_8, // Packed
T_int,
T_byte,
T_short,
};
enum Format {
@ -527,6 +529,7 @@ public:
static PT(Texture) make_texture();
public:
static bool is_unsigned(ComponentType ctype);
static bool is_specific(CompressionMode compression);
static bool has_alpha(Format format);
static bool has_binary_alpha(Format format);

View File

@ -587,33 +587,16 @@ assemble_text() {
if (placement->_properties != properties) {
// Get a new set of properties for future glyphs.
properties = placement->_properties;
text_state = RenderState::make_empty();
shadow_state = RenderState::make_empty();
text_state = properties->get_text_state();
shadow_xform = LMatrix4::ident_mat();
if (properties->has_text_color()) {
text_state = text_state->add_attrib(ColorAttrib::make_flat(properties->get_text_color()));
if (properties->get_text_color()[3] != 1.0) {
text_state = text_state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
}
}
if (properties->has_bin()) {
text_state = text_state->add_attrib(CullBinAttrib::make(properties->get_bin(), properties->get_draw_order() + 2));
}
if (properties->has_shadow()) {
shadow_state = shadow_state->add_attrib(ColorAttrib::make_flat(properties->get_shadow_color()));
if (properties->get_shadow_color()[3] != 1.0) {
shadow_state = shadow_state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
}
if (properties->has_bin()) {
shadow_state = shadow_state->add_attrib(CullBinAttrib::make(properties->get_bin(), properties->get_draw_order() + 1));
}
shadow_state = properties->get_shadow_state();
LVector2 offset = properties->get_shadow();
shadow_xform = LMatrix4::translate_mat(offset[0], 0.0f, -offset[1]);
} else {
shadow_state.clear();
}
}

View File

@ -550,6 +550,7 @@ INLINE void TextProperties::
set_text_color(const LColor &text_color) {
_text_color = text_color;
_specified |= F_has_text_color;
_text_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -562,6 +563,7 @@ INLINE void TextProperties::
clear_text_color() {
_text_color.set(1.0f, 1.0f, 1.0f, 1.0f);
_specified &= ~F_has_text_color;
_text_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -603,6 +605,7 @@ INLINE void TextProperties::
set_shadow_color(const LColor &shadow_color) {
_shadow_color = shadow_color;
_specified |= F_has_shadow_color;
_shadow_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -614,6 +617,7 @@ INLINE void TextProperties::
clear_shadow_color() {
_shadow_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_specified &= ~F_has_shadow_color;
_shadow_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -711,6 +715,8 @@ INLINE void TextProperties::
set_bin(const string &bin) {
_bin = bin;
_specified |= F_has_bin;
_text_state.clear();
_shadow_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -725,6 +731,8 @@ INLINE void TextProperties::
clear_bin() {
_bin = string();
_specified &= ~F_has_bin;
_text_state.clear();
_shadow_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -768,6 +776,8 @@ INLINE int TextProperties::
set_draw_order(int draw_order) {
_draw_order = draw_order;
_specified |= F_has_draw_order;
_text_state.clear();
_shadow_state.clear();
return _draw_order + 3;
}
@ -780,6 +790,8 @@ INLINE void TextProperties::
clear_draw_order() {
_draw_order = 1;
_specified &= ~F_has_draw_order;
_text_state.clear();
_shadow_state.clear();
}
////////////////////////////////////////////////////////////////////

View File

@ -19,6 +19,9 @@
#include "staticTextFont.h"
#include "bamFile.h"
#include "fontPool.h"
#include "colorAttrib.h"
#include "cullBinAttrib.h"
#include "transparencyAttrib.h"
PT(TextFont) TextProperties::_default_font;
bool TextProperties::_loaded_default_font = false;
@ -61,6 +64,8 @@ TextProperties() {
TextProperties::
TextProperties(const TextProperties &copy) {
(*this) = copy;
_text_state = copy._text_state;
_shadow_state = copy._shadow_state;
}
////////////////////////////////////////////////////////////////////
@ -91,6 +96,9 @@ operator = (const TextProperties &copy) {
_glyph_scale = copy._glyph_scale;
_glyph_shift = copy._glyph_shift;
_text_scale = copy._text_scale;
_text_state.clear();
_shadow_state.clear();
}
////////////////////////////////////////////////////////////////////
@ -372,6 +380,62 @@ write(ostream &out, int indent_level) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: TextProperties::get_text_state
// Access: Public
// Description: Returns a RenderState object suitable for rendering
// text with these properties.
////////////////////////////////////////////////////////////////////
const RenderState *TextProperties::
get_text_state() const {
if (!_text_state.is_null()) {
return _text_state;
}
CPT(RenderState) state = RenderState::make_empty();
if (has_text_color()) {
state = state->add_attrib(ColorAttrib::make_flat(get_text_color()));
if (get_text_color()[3] != 1.0) {
state = state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
}
}
if (has_bin()) {
state = state->add_attrib(CullBinAttrib::make(get_bin(), get_draw_order() + 2));
}
swap(_text_state, state);
return _text_state;
}
////////////////////////////////////////////////////////////////////
// Function: TextProperties::get_shadow_state
// Access: Public
// Description: Returns a RenderState object suitable for rendering
// the shadow of this text with these properties.
////////////////////////////////////////////////////////////////////
const RenderState *TextProperties::
get_shadow_state() const {
if (!_shadow_state.is_null()) {
return _shadow_state;
}
CPT(RenderState) state = RenderState::make_empty();
state = state->add_attrib(ColorAttrib::make_flat(get_shadow_color()));
if (get_shadow_color()[3] != 1.0) {
state = state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
}
if (has_bin()) {
state = state->add_attrib(CullBinAttrib::make(get_bin(), get_draw_order() + 1));
}
swap(_shadow_state, state);
return _shadow_state;
}
////////////////////////////////////////////////////////////////////
// Function: TextProperties::load_default_font
// Access: Private, Static

View File

@ -21,6 +21,7 @@
#include "luse.h"
#include "textFont.h"
#include "pointerTo.h"
#include "renderState.h"
////////////////////////////////////////////////////////////////////
// Class : TextProperties
@ -169,6 +170,10 @@ PUBLISHED:
void write(ostream &out, int indent_level = 0) const;
public:
const RenderState *get_text_state() const;
const RenderState *get_shadow_state() const;
private:
static void load_default_font();
@ -216,6 +221,9 @@ private:
PN_stdfloat _glyph_shift;
PN_stdfloat _text_scale;
mutable CPT(RenderState) _text_state;
mutable CPT(RenderState) _shadow_state;
static PT(TextFont) _default_font;
static bool _loaded_default_font;