fiddly bits

This commit is contained in:
David Rose 2008-05-03 00:37:47 +00:00
parent 66ec7e16d8
commit 230d7825d3
13 changed files with 84 additions and 493 deletions

View File

@ -612,6 +612,19 @@ get_alpha_scale_texture_stage() {
return _alpha_scale_texture_stage;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_runtime_color_scale
// Access: Published
// Description: Returns true if this particular GSG can implement (or
// would prefer to implement) set color and/or color
// scale directly, without requiring any munging of
// vertices or tricks with lighting.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_runtime_color_scale() const {
return _runtime_color_scale;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_coordinate_system
// Access: Published

View File

@ -201,6 +201,10 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
// scaling.
_alpha_scale_via_texture = alpha_scale_via_texture;
// Few GSG's can do this, since it requires touching each vertex as
// it is rendered.
_runtime_color_scale = false;
_stencil_render_states = 0;
// The default is no shader support.

View File

@ -103,7 +103,7 @@ PUBLISHED:
virtual INLINE int get_max_vertices_per_primitive() const;
INLINE int get_max_texture_stages() const;
INLINE int get_max_texture_dimension() const;
virtual INLINE int get_max_texture_dimension() const;
INLINE int get_max_3d_texture_dimension() const;
INLINE int get_max_cube_map_dimension() const;
@ -142,6 +142,7 @@ PUBLISHED:
INLINE bool get_color_scale_via_lighting() const;
INLINE bool get_alpha_scale_via_texture() const;
INLINE bool get_alpha_scale_via_texture(const TextureAttrib *tex_attrib) const;
INLINE bool get_runtime_color_scale() const;
INLINE static TextureStage *get_alpha_scale_texture_stage();
@ -397,6 +398,7 @@ protected:
int _supported_geom_rendering;
bool _color_scale_via_lighting;
bool _alpha_scale_via_texture;
bool _runtime_color_scale;
int _stereo_buffer_mask;

View File

@ -48,46 +48,49 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
_munge_color = false;
_munge_color_scale = false;
CPT(ColorAttrib) color_attrib = state->get_color();
CPT(ColorScaleAttrib) color_scale_attrib = state->get_color_scale();
if (!get_gsg()->get_runtime_color_scale()) {
// We might need to munge the colors.
CPT(ColorAttrib) color_attrib = state->get_color();
CPT(ColorScaleAttrib) color_scale_attrib = state->get_color_scale();
if (color_attrib != (ColorAttrib *)NULL &&
color_attrib->get_color_type() == ColorAttrib::T_flat) {
if (!get_gsg()->get_color_scale_via_lighting()) {
// We only need to munge the color directly if the GSG says it
// can't cheat the color via lighting (presumably, in this case,
// by applying a material).
_color = color_attrib->get_color();
if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
color_scale_attrib->has_scale()) {
const LVecBase4f &cs = color_scale_attrib->get_scale();
_color.set(_color[0] * cs[0],
_color[1] * cs[1],
_color[2] * cs[2],
_color[3] * cs[3]);
if (color_attrib != (ColorAttrib *)NULL &&
color_attrib->get_color_type() == ColorAttrib::T_flat) {
if (!get_gsg()->get_color_scale_via_lighting()) {
// We only need to munge the color directly if the GSG says it
// can't cheat the color via lighting (presumably, in this case,
// by applying a material).
_color = color_attrib->get_color();
if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
color_scale_attrib->has_scale()) {
const LVecBase4f &cs = color_scale_attrib->get_scale();
_color.set(_color[0] * cs[0],
_color[1] * cs[1],
_color[2] * cs[2],
_color[3] * cs[3]);
}
_munge_color = true;
}
_munge_color = true;
} else if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
color_scale_attrib->has_scale()) {
_color_scale = color_scale_attrib->get_scale();
CPT(TextureAttrib) tex_attrib = state->get_texture();
// If the GSG says it can't cheat this RGB or alpha scale, we have
// to apply the color scale directly.
if ((color_scale_attrib->has_rgb_scale() && !get_gsg()->get_color_scale_via_lighting()) ||
(color_scale_attrib->has_alpha_scale() && !get_gsg()->get_alpha_scale_via_texture(tex_attrib))) {
_munge_color_scale = true;
}
// Known bug: if there is a material on an object that would
// obscure the effect of color_scale, we scale the lighting
// anyway, thus applying the effect even if it should be obscured.
// It doesn't seem worth the effort to detect this contrived
// situation and handle it correctly.
}
} else if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
color_scale_attrib->has_scale()) {
_color_scale = color_scale_attrib->get_scale();
CPT(TextureAttrib) tex_attrib = state->get_texture();
// If the GSG says it can't cheat this RGB or alpha scale, we have
// to apply the color scale directly.
if ((color_scale_attrib->has_rgb_scale() && !get_gsg()->get_color_scale_via_lighting()) ||
(color_scale_attrib->has_alpha_scale() && !get_gsg()->get_alpha_scale_via_texture(tex_attrib))) {
_munge_color_scale = true;
}
// Known bug: if there is a material on an object that would
// obscure the effect of color_scale, we scale the lighting
// anyway, thus applying the effect even if it should be obscured.
// It doesn't seem worth the effort to detect this contrived
// situation and handle it correctly.
}
}

View File

@ -73,7 +73,9 @@ ConfigVariableInt max_texture_dimension
"texture sizes for limited graphics cards. When this is greater "
"than zero, each texture image loaded from a file (but only those "
"loaded from a file) will be automatically scaled down, if "
"necessary, so that neither dimension is larger than this value."));
"necessary, so that neither dimension is larger than this value. "
"If this is less than zero, the size limit is taken from the "
"primary GSG. If this is exactly zero, there is no limit."));
ConfigVariableDouble texture_scale
("texture-scale", 1.0,

View File

@ -2960,9 +2960,20 @@ consider_rescale(PNMImage &pnmimage, const string &name) {
break;
}
if (max_texture_dimension > 0 && !exclude) {
new_x_size = min(new_x_size, (int)max_texture_dimension);
new_y_size = min(new_y_size, (int)max_texture_dimension);
if (!exclude) {
int max_dimension = max_texture_dimension;
if (max_dimension < 0) {
GraphicsStateGuardianBase *gsg = GraphicsStateGuardianBase::get_default_gsg();
if (gsg != (GraphicsStateGuardianBase *)NULL) {
max_dimension = gsg->get_max_texture_dimension();
}
}
if (max_dimension > 0) {
new_x_size = min(new_x_size, (int)max_dimension);
new_y_size = min(new_y_size, (int)max_dimension);
}
}
if (pnmimage.get_x_size() != new_x_size ||

View File

@ -116,6 +116,8 @@ PUBLISHED:
virtual int get_max_vertices_per_array() const=0;
virtual int get_max_vertices_per_primitive() const=0;
virtual int get_max_texture_dimension() const=0;
virtual bool get_supports_multisample() const=0;
virtual int get_supported_geom_rendering() const=0;
virtual bool get_supports_occlusion_query() const=0;

View File

@ -28,6 +28,7 @@
#include "geomVertexWriter.h"
#include "textureAttrib.h"
#include "transparencyAttrib.h"
#include "colorAttrib.h"
#include "renderState.h"
#include "config_gobj.h"
@ -163,6 +164,7 @@ make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin,
_state = RenderState::make(TextureAttrib::make(_page),
TransparencyAttrib::make(TransparencyAttrib::M_alpha));
_state = _state->add_attrib(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f)), -1);
_advance = advance / font_pixels_per_unit;
}

View File

@ -1,9 +1,9 @@
#define BUILD_DIRECTORY $[HAVE_TINYSDGL]
//#define BUILDING_DLL BUILDING_PANDATINYSDGL
#define BUILD_DIRECTORY $[HAVE_SDL]
//#define BUILDING_DLL BUILDING_TINYDISPLAY
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
dtoolutil:c dtoolbase:c dtool:m
#define USE_PACKAGES tinysdgl
#define USE_PACKAGES sdl
#begin lib_target
#define TARGET tinydisplay
@ -18,8 +18,6 @@
tinyGraphicsWindow.h tinyGraphicsWindow.I tinyGraphicsWindow.cxx \
tinyGraphicsStateGuardian.h tinyGraphicsStateGuardian.I \
tinyGraphicsStateGuardian.cxx \
tinyImmediateModeSender.h tinyImmediateModeSender.I \
tinyImmediateModeSender.cxx \
tinyTextureContext.I tinyTextureContext.cxx tinyTextureContext.h \
api.c arrays.c clear.c clip.c error.c get.c \
glu.c image_util.c init.c light.c list.c \

View File

@ -23,7 +23,6 @@
#include "graphicsStateGuardian.h"
#include "tinyGraphicsPipe.h"
#include "tinyImmediateModeSender.h"
#include "tinygl.h"
extern "C" {

View File

@ -1,101 +0,0 @@
// Filename: glImmediateModeSender_src.I
// Created by: drose (15Aug05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TinyImmediateModeSender::
TinyImmediateModeSender() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender::Constructor
// Access: Public
// Description: The ComponentSender becomes the owner of the
// GeomVertexReader pointer, and will delete it when it
// is done.
////////////////////////////////////////////////////////////////////
INLINE TinyImmediateModeSender::ComponentSender::
ComponentSender(GeomVertexReader *reader) :
_reader(reader)
{
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender::set_vertex
// Access: Public
// Description: Specifies the vertex index of the next vertex to
// send. If this is not called, the next consecutive
// vertex will be sent.
////////////////////////////////////////////////////////////////////
INLINE void TinyImmediateModeSender::ComponentSender::
set_vertex(int vertex_index) {
_reader->set_row(vertex_index);
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender1f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TinyImmediateModeSender::ComponentSender1f::
ComponentSender1f(GeomVertexReader *reader, Func1f *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender2f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TinyImmediateModeSender::ComponentSender2f::
ComponentSender2f(GeomVertexReader *reader, Func2f *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender3f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TinyImmediateModeSender::ComponentSender3f::
ComponentSender3f(GeomVertexReader *reader, Func3f *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender4f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TinyImmediateModeSender::ComponentSender4f::
ComponentSender4f(GeomVertexReader *reader, Func4f *func) :
ComponentSender(reader),
_func(func)
{
}

View File

@ -1,232 +0,0 @@
// Filename: glImmediateModeSender_src.cxx
// Created by: drose (15Aug05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "tinyImmediateModeSender.h"
#include "config_tinydisplay.h"
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
TinyImmediateModeSender::
~TinyImmediateModeSender() {
clear();
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::clear
// Access: Public
// Description: Removes (and deletes) all of the senders from the
// object.
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::
clear() {
ComponentSenders::iterator si;
for (si = _senders.begin(); si != _senders.end(); ++si) {
delete (*si);
}
_senders.clear();
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::set_vertex
// Access: Public
// Description: Specifies the vertex index of the next vertex to
// send. If this is not called, the next consecutive
// vertex will be sent.
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::
set_vertex(int vertex_index) {
ComponentSenders::iterator si;
for (si = _senders.begin(); si != _senders.end(); ++si) {
(*si)->set_vertex(vertex_index);
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::issue_vertex
// Access: Public
// Description: Sends the next vertex to the OpenGL API.
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::
issue_vertex() {
ComponentSenders::iterator si;
for (si = _senders.begin(); si != _senders.end(); ++si) {
(*si)->issue_vertex();
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::add_column
// Access: Public
// Description: Creates a new ComponentSender for the named data
// column, if it exists in the vertex data, and adds it
// to the list of senders for this object.
//
// The four function pointers are the four variants on
// the function pointer for the possible number of
// components of the data column. The appropriate
// pointer will be used, depending on the number of
// components the data column actually uses.
//
// The return value is true if the column is added,
// false if it is not for some reason (for instance, the
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool TinyImmediateModeSender::
add_column(const GeomVertexDataPipelineReader *data_reader, const InternalName *name,
Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f) {
if (data_reader->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
case 1:
if (func1f != (Func1f *)NULL) {
sender = new ComponentSender1f(reader, func1f);
}
break;
case 2:
if (func2f != (Func2f *)NULL) {
sender = new ComponentSender2f(reader, func2f);
}
break;
case 3:
if (func3f != (Func3f *)NULL) {
sender = new ComponentSender3f(reader, func3f);
}
break;
case 4:
if (func4f != (Func4f *)NULL) {
sender = new ComponentSender4f(reader, func4f);
}
break;
}
if (sender != (ComponentSender *)NULL) {
// Ok, we've got a valid sender; add it to the list.
_senders.push_back(sender);
return true;
} else {
// We didn't get a valid sender; clean up and return.
delete reader;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::add_sender
// Access: Public
// Description: Adds a new ComponentSender to the list of senders for
// this object. The GLImmediateModeSender object
// becomes the owner of the ComponentSender pointer and
// will delete it when it is done.
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::
add_sender(ComponentSender *sender) {
_senders.push_back(sender);
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
TinyImmediateModeSender::ComponentSender::
~ComponentSender() {
delete _reader;
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender1f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::ComponentSender1f::
issue_vertex() {
float d = _reader->get_data1f();
#ifndef NDEBUG
if (tinydisplay_cat.is_spam()) {
tinydisplay_cat.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(d);
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender2f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::ComponentSender2f::
issue_vertex() {
const LVecBase2f &d = _reader->get_data2f();
#ifndef NDEBUG
if (tinydisplay_cat.is_spam()) {
tinydisplay_cat.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(d[0], d[1]);
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender3f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::ComponentSender3f::
issue_vertex() {
const LVecBase3f &d = _reader->get_data3f();
#ifndef NDEBUG
if (tinydisplay_cat.is_spam()) {
tinydisplay_cat.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(d[0], d[1], d[2]);
}
////////////////////////////////////////////////////////////////////
// Function: TinyImmediateModeSender::ComponentSender4f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void TinyImmediateModeSender::ComponentSender4f::
issue_vertex() {
const LVecBase4f &d = _reader->get_data4f();
#ifndef NDEBUG
if (tinydisplay_cat.is_spam()) {
tinydisplay_cat.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(d[0], d[1], d[2], d[3]);
}

View File

@ -1,112 +0,0 @@
// Filename: tinyImmediateModeSender.h
// Created by: drose (29Apr08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef TINYIMMEDIATEMODESENDER_H
#define TINYIMMEDIATEMODESENDER_H
#include "pandabase.h"
#include "geomVertexReader.h"
#include "tinygl.h"
////////////////////////////////////////////////////////////////////
// Class : TinyImmediateModeSender
// Description : This class collects together a handful of objects
// that will issue immediate-mode commands like
// glVertex, glTexCoord, etc., for the purposes of
// sending an object's vertices using the immediate mode
// functions.
//
// Since unlike OpenGL, TinyGL prefers the
// immediate-mode interface, this is used all of the
// time.
////////////////////////////////////////////////////////////////////
class TinyImmediateModeSender {
public:
INLINE TinyImmediateModeSender();
~TinyImmediateModeSender();
void clear();
void set_vertex(int vertex_index);
void issue_vertex();
class ComponentSender;
typedef void Func1f(GLfloat a);
typedef void Func2f(GLfloat a, GLfloat b);
typedef void Func3f(GLfloat a, GLfloat b, GLfloat c);
typedef void Func4f(GLfloat a, GLfloat b, GLfloat c, GLfloat d);
bool add_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, Func1f *func1f,
Func2f *func2f, Func3f *func3f, Func4f *func4f);
void add_sender(ComponentSender *sender);
public:
class ComponentSender {
public:
INLINE ComponentSender(GeomVertexReader *reader);
virtual ~ComponentSender();
INLINE void set_vertex(int vertex_index);
virtual void issue_vertex()=0;
protected:
GeomVertexReader *_reader;
};
class ComponentSender1f : public ComponentSender {
public:
INLINE ComponentSender1f(GeomVertexReader *reader, Func1f *func);
virtual void issue_vertex();
private:
Func1f *_func;
};
class ComponentSender2f : public ComponentSender {
public:
INLINE ComponentSender2f(GeomVertexReader *reader, Func2f *func);
virtual void issue_vertex();
private:
Func2f *_func;
};
class ComponentSender3f : public ComponentSender {
public:
INLINE ComponentSender3f(GeomVertexReader *reader, Func3f *func);
virtual void issue_vertex();
private:
Func3f *_func;
};
class ComponentSender4f : public ComponentSender {
public:
INLINE ComponentSender4f(GeomVertexReader *reader, Func4f *func);
virtual void issue_vertex();
private:
Func4f *_func;
};
private:
typedef pvector<ComponentSender *> ComponentSenders;
ComponentSenders _senders;
};
#include "tinyImmediateModeSender.I"
#endif // SUPPORT_IMMEDIATE_MODE