mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
a few tinydisplay optimizations
This commit is contained in:
parent
faa94cf0b9
commit
979896da75
@ -51,6 +51,7 @@
|
||||
modifierButtons.I modifierButtons.h mouseButton.h \
|
||||
mouseData.I mouseData.h nameUniquifier.I nameUniquifier.h \
|
||||
nodeCachedReferenceCount.h nodeCachedReferenceCount.I \
|
||||
pbitops.I pbitops.h \
|
||||
portalMask.h \
|
||||
pta_double.h \
|
||||
pta_float.h pta_int.h \
|
||||
@ -98,6 +99,7 @@
|
||||
modifierButtons.cxx mouseButton.cxx mouseData.cxx \
|
||||
nameUniquifier.cxx \
|
||||
nodeCachedReferenceCount.cxx \
|
||||
pbitops.cxx \
|
||||
pta_double.cxx pta_float.cxx \
|
||||
pta_int.cxx pta_ushort.cxx \
|
||||
simpleHashMap.cxx \
|
||||
@ -156,6 +158,7 @@
|
||||
nameUniquifier.I nameUniquifier.h \
|
||||
nodeCachedReferenceCount.h nodeCachedReferenceCount.I \
|
||||
portalMask.h \
|
||||
pbitops.I pbitops.h \
|
||||
pta_double.h \
|
||||
pta_float.h pta_int.h pta_ushort.h \
|
||||
simpleHashMap.I simpleHashMap.h \
|
||||
|
@ -462,12 +462,7 @@ get_lowest_off_bit() const {
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
get_highest_on_bit() const {
|
||||
if (_word == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
WordType w = ::flood_bits_down(_word);
|
||||
return count_bits_in_word(w) - 1;
|
||||
return ::get_highest_on_bit(_word);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -871,88 +866,6 @@ init_type() {
|
||||
register_type(_type_handle, str.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: count_bits_in_word
|
||||
// Description: Returns the number of 1 bits in the indicated word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
count_bits_in_word(PN_uint32 x) {
|
||||
return (int)num_bits_on[x & 0xffff] + (int)num_bits_on[(x >> 16) & 0xffff];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: count_bits_in_word
|
||||
// Description: Returns the number of 1 bits in the indicated word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
count_bits_in_word(PN_uint64 x) {
|
||||
return count_bits_in_word((PN_uint32)x) + count_bits_in_word((PN_uint32)(x >> 32));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_down
|
||||
// Description: Returns a value such that every bit at or below the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint32
|
||||
flood_bits_down(PN_uint32 x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_down
|
||||
// Description: Returns a value such that every bit at or below the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint64
|
||||
flood_bits_down(PN_uint64 x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
x |= (x >> 32);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_up
|
||||
// Description: Returns a value such that every bit at or above the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint32
|
||||
flood_bits_up(PN_uint32 x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
x |= (x << 8);
|
||||
x |= (x << 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_up
|
||||
// Description: Returns a value such that every bit at or above the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint64
|
||||
flood_bits_up(PN_uint64 x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
x |= (x << 8);
|
||||
x |= (x << 16);
|
||||
x |= (x << 32);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::flood_up_in_place
|
||||
// Access: Published
|
||||
|
@ -22,5 +22,3 @@
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
unsigned char num_bits_on[65536];
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define BITMASK_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pbitops.h"
|
||||
#include "numeric_types.h"
|
||||
#include "typedObject.h"
|
||||
#include "indent.h"
|
||||
@ -151,16 +151,6 @@ private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE int count_bits_in_word(PN_uint32 x);
|
||||
INLINE int count_bits_in_word(PN_uint64 x);
|
||||
INLINE PN_uint32 flood_bits_down(PN_uint32 x);
|
||||
INLINE PN_uint64 flood_bits_down(PN_uint64 x);
|
||||
INLINE PN_uint32 flood_bits_up(PN_uint32 x);
|
||||
INLINE PN_uint64 flood_bits_up(PN_uint64 x);
|
||||
|
||||
// This table precomputes the number of on bits in each 16-bit word.
|
||||
extern EXPCL_PANDA_PUTIL unsigned char num_bits_on[65536];
|
||||
|
||||
#include "bitMask.I"
|
||||
|
||||
template<class WType, int nbits>
|
||||
|
146
panda/src/putil/pbitops.I
Normal file
146
panda/src/putil/pbitops.I
Normal file
@ -0,0 +1,146 @@
|
||||
// Filename: pbitops.I
|
||||
// Created by: drose (10May08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: count_bits_in_word
|
||||
// Description: Returns the number of 1 bits in the indicated word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
count_bits_in_word(PN_uint32 x) {
|
||||
return (int)num_bits_on[x & 0xffff] + (int)num_bits_on[(x >> 16) & 0xffff];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: count_bits_in_word
|
||||
// Description: Returns the number of 1 bits in the indicated word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
count_bits_in_word(PN_uint64 x) {
|
||||
return count_bits_in_word((PN_uint32)x) + count_bits_in_word((PN_uint32)(x >> 32));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_down
|
||||
// Description: Returns a value such that every bit at or below the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint32
|
||||
flood_bits_down(PN_uint32 x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_down
|
||||
// Description: Returns a value such that every bit at or below the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint64
|
||||
flood_bits_down(PN_uint64 x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
x |= (x >> 32);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_up
|
||||
// Description: Returns a value such that every bit at or above the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint32
|
||||
flood_bits_up(PN_uint32 x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
x |= (x << 8);
|
||||
x |= (x << 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flood_bits_up
|
||||
// Description: Returns a value such that every bit at or above the
|
||||
// highest bit in x is 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint64
|
||||
flood_bits_up(PN_uint64 x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
x |= (x << 8);
|
||||
x |= (x << 16);
|
||||
x |= (x << 32);
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_highest_on_bit
|
||||
// Description: Returns the index of the highest 1 bit in the word.
|
||||
// Returns -1 if there are no 1 bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
get_highest_on_bit(PN_uint32 x) {
|
||||
PN_uint32 w = flood_bits_down(x);
|
||||
return count_bits_in_word(w) - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_highest_on_bit
|
||||
// Description: Returns the index of the highest 1 bit in the word.
|
||||
// Returns -1 if there are no 1 bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
get_highest_on_bit(PN_uint64 x) {
|
||||
PN_uint64 w = flood_bits_down(x);
|
||||
return count_bits_in_word(w) - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_next_higher_bit
|
||||
// Description: Returns the smallest power of 2 greater than x.
|
||||
//
|
||||
// Returns the smallest number n such that (1 << n) is
|
||||
// larger than x.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
get_next_higher_bit(PN_uint32 x) {
|
||||
PN_uint32 w = flood_bits_down(x);
|
||||
return count_bits_in_word(w);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_next_higher_bit
|
||||
// Description: Returns the smallest power of 2 greater than x.
|
||||
//
|
||||
// Returns the smallest number n such that (1 << n) is
|
||||
// larger than x.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
get_next_higher_bit(PN_uint64 x) {
|
||||
PN_uint64 w = flood_bits_down(x);
|
||||
return count_bits_in_word(w);
|
||||
}
|
21
panda/src/putil/pbitops.cxx
Normal file
21
panda/src/putil/pbitops.cxx
Normal file
@ -0,0 +1,21 @@
|
||||
// Filename: pbitops.cxx
|
||||
// Created by: drose (10May08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pbitops.h"
|
||||
|
||||
unsigned char num_bits_on[65536];
|
49
panda/src/putil/pbitops.h
Normal file
49
panda/src/putil/pbitops.h
Normal file
@ -0,0 +1,49 @@
|
||||
// Filename: pbitops.h
|
||||
// Created by: drose (10May08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PBITOPS_H
|
||||
#define PBITOPS_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "numeric_types.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// This file defines a few low-level bit-operation routines, optimized
|
||||
// all to heck.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE int count_bits_in_word(PN_uint32 x);
|
||||
INLINE int count_bits_in_word(PN_uint64 x);
|
||||
|
||||
INLINE PN_uint32 flood_bits_down(PN_uint32 x);
|
||||
INLINE PN_uint64 flood_bits_down(PN_uint64 x);
|
||||
INLINE PN_uint32 flood_bits_up(PN_uint32 x);
|
||||
INLINE PN_uint64 flood_bits_up(PN_uint64 x);
|
||||
|
||||
INLINE int get_highest_on_bit(PN_uint32 x);
|
||||
INLINE int get_highest_on_bit(PN_uint64 x);
|
||||
|
||||
INLINE int get_next_higher_bit(PN_uint32 x);
|
||||
INLINE int get_next_higher_bit(PN_uint64 x);
|
||||
|
||||
// This table precomputes the number of on bits in each 16-bit word.
|
||||
extern EXPCL_PANDA_PUTIL unsigned char num_bits_on[65536];
|
||||
|
||||
#include "pbitops.I"
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#include "mouseData.cxx"
|
||||
#include "nameUniquifier.cxx"
|
||||
#include "nodeCachedReferenceCount.cxx"
|
||||
#include "pbitops.cxx"
|
||||
#include "pta_double.cxx"
|
||||
#include "pta_float.cxx"
|
||||
#include "pta_int.cxx"
|
||||
|
@ -70,6 +70,17 @@ ConfigVariableInt td_texture_ram
|
||||
"frame, even if this means this limit remains exceeded.) "
|
||||
"Set it to -1 for no limit."));
|
||||
|
||||
ConfigVariableBool td_ignore_mipmaps
|
||||
("td-ignore-mipmaps", false,
|
||||
PRC_DESC("Configure this true to disable use of mipmaps on the "
|
||||
"tinydisplay software renderer."));
|
||||
|
||||
ConfigVariableBool td_perspective_textures
|
||||
("td-perspective-textures", true,
|
||||
PRC_DESC("Configure this false to disable use of perspective-correct "
|
||||
"textures on the tinydisplay software renderer, for a small "
|
||||
"performance gain."));
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libtinydisplay
|
||||
// Description: Initializes the library. This must be called at
|
||||
|
@ -35,5 +35,7 @@ extern ConfigVariableInt x_wheel_up_button;
|
||||
extern ConfigVariableInt x_wheel_down_button;
|
||||
|
||||
extern ConfigVariableInt td_texture_ram;
|
||||
extern ConfigVariableBool td_ignore_mipmaps;
|
||||
extern ConfigVariableBool td_perspective_textures;
|
||||
|
||||
#endif
|
||||
|
@ -598,6 +598,15 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
}
|
||||
}
|
||||
|
||||
if (_c->texture_2d_enabled && _texture_replace) {
|
||||
// We don't need the vertex color or lighting calculation after
|
||||
// all, since the current texture will just hide all of that.
|
||||
needs_color = false;
|
||||
needs_normal = false;
|
||||
}
|
||||
|
||||
bool lighting_enabled = (needs_normal && _c->lighting_enabled);
|
||||
|
||||
for (i = 0; i < num_used_vertices; ++i) {
|
||||
GLVertex *v = &_vertices[i];
|
||||
const LVecBase4f &d = rvertex.get_data4f();
|
||||
@ -642,18 +651,18 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
|
||||
v->color = _c->current_color;
|
||||
|
||||
if (needs_normal) {
|
||||
if (lighting_enabled) {
|
||||
const LVecBase3f &d = rnormal.get_data3f();
|
||||
_c->current_normal.X = d[0];
|
||||
_c->current_normal.Y = d[1];
|
||||
_c->current_normal.Z = d[2];
|
||||
_c->current_normal.W = 0.0f;
|
||||
}
|
||||
|
||||
gl_vertex_transform(_c, v);
|
||||
|
||||
if (_c->lighting_enabled) {
|
||||
gl_vertex_transform(_c, v);
|
||||
gl_shade_vertex(_c, v);
|
||||
|
||||
} else {
|
||||
gl_vertex_transform(_c, v);
|
||||
}
|
||||
|
||||
if (v->clip_code == 0) {
|
||||
@ -666,16 +675,16 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
// Set up the appropriate function callback for filling triangles,
|
||||
// according to the current state.
|
||||
|
||||
int depth_write_state = 0;
|
||||
int depth_write_state = 0; // zon
|
||||
if (_target._depth_write->get_mode() != DepthWriteAttrib::M_on) {
|
||||
depth_write_state = 1;
|
||||
depth_write_state = 1; // zoff
|
||||
}
|
||||
|
||||
int color_write_state = 0;
|
||||
int color_write_state = 0; // noblend
|
||||
switch (_target._transparency->get_mode()) {
|
||||
case TransparencyAttrib::M_alpha:
|
||||
case TransparencyAttrib::M_dual:
|
||||
color_write_state = 1;
|
||||
color_write_state = 1; // blend
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -685,36 +694,36 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
unsigned int color_channels =
|
||||
_target._color_write->get_channels() & _color_write_mask;
|
||||
if (color_channels == ColorWriteAttrib::C_off) {
|
||||
color_write_state = 2;
|
||||
color_write_state = 2; // nocolor
|
||||
}
|
||||
|
||||
int alpha_test_state = 0;
|
||||
int alpha_test_state = 0; // anone
|
||||
switch (_target._alpha_test->get_mode()) {
|
||||
case AlphaTestAttrib::M_none:
|
||||
case AlphaTestAttrib::M_never:
|
||||
case AlphaTestAttrib::M_always:
|
||||
case AlphaTestAttrib::M_equal:
|
||||
case AlphaTestAttrib::M_not_equal:
|
||||
alpha_test_state = 0;
|
||||
alpha_test_state = 0; // anone
|
||||
break;
|
||||
|
||||
case AlphaTestAttrib::M_less:
|
||||
case AlphaTestAttrib::M_less_equal:
|
||||
alpha_test_state = 1;
|
||||
alpha_test_state = 1; // aless
|
||||
_c->zb->reference_alpha = (unsigned int)_target._alpha_test->get_reference_alpha() * 0xff00;
|
||||
break;
|
||||
|
||||
case AlphaTestAttrib::M_greater:
|
||||
case AlphaTestAttrib::M_greater_equal:
|
||||
alpha_test_state = 2;
|
||||
alpha_test_state = 2; // amore
|
||||
_c->zb->reference_alpha = (unsigned int)_target._alpha_test->get_reference_alpha() * 0xff00;
|
||||
break;
|
||||
}
|
||||
|
||||
int depth_test_state = 1;
|
||||
int depth_test_state = 1; // zless
|
||||
_c->depth_test = 1; // set this for ZB_line
|
||||
if (_target._depth_test->get_mode() == DepthTestAttrib::M_none) {
|
||||
depth_test_state = 0;
|
||||
depth_test_state = 0; // zless
|
||||
_c->depth_test = 0;
|
||||
}
|
||||
|
||||
@ -724,17 +733,17 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
// as well use the flat shading model.
|
||||
shade_model = ShadeModelAttrib::M_flat;
|
||||
}
|
||||
int shading_state = 2; // smooth
|
||||
int shade_model_state = 2; // smooth
|
||||
_c->smooth_shade_model = true;
|
||||
|
||||
if (shade_model == ShadeModelAttrib::M_flat) {
|
||||
_c->smooth_shade_model = false;
|
||||
shading_state = 1; // flat
|
||||
shade_model_state = 1; // flat
|
||||
if (_c->current_color.X == 1.0f &&
|
||||
_c->current_color.Y == 1.0f &&
|
||||
_c->current_color.Z == 1.0f &&
|
||||
_c->current_color.W == 1.0f) {
|
||||
shading_state = 0; // white
|
||||
shade_model_state = 0; // white
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,12 +752,18 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
if (_c->texture_2d_enabled) {
|
||||
texfilter_state = _texfilter_state;
|
||||
texturing_state = 2; // perspective-correct textures
|
||||
if (_c->matrix_model_projection_no_w_transform) {
|
||||
if (_c->matrix_model_projection_no_w_transform || !td_perspective_textures) {
|
||||
texturing_state = 1; // non-perspective-correct textures
|
||||
}
|
||||
|
||||
if (_texture_replace) {
|
||||
// If we're completely replacing the underlying color, then it
|
||||
// doesn't matter what the color is.
|
||||
shade_model_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_c->zb_fill_tri = fill_tri_funcs[depth_write_state][color_write_state][alpha_test_state][depth_test_state][texfilter_state][shading_state][texturing_state];
|
||||
_c->zb_fill_tri = fill_tri_funcs[depth_write_state][color_write_state][alpha_test_state][depth_test_state][texfilter_state][shade_model_state][texturing_state];
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1592,6 +1607,16 @@ do_issue_texture() {
|
||||
|
||||
// Then, turn on the current texture mode.
|
||||
apply_texture(tc);
|
||||
|
||||
// Set a few state cache values.
|
||||
_texfilter_state = 0; // nearest
|
||||
if (texture->uses_mipmaps() && !td_ignore_mipmaps) {
|
||||
_texfilter_state = 1; // mipmap
|
||||
}
|
||||
|
||||
// M_replace means M_replace; anything else is treated the same as
|
||||
// M_modulate.
|
||||
_texture_replace = (stage->get_mode() == TextureStage::M_replace);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1609,11 +1634,6 @@ apply_texture(TextureContext *tc) {
|
||||
_c->current_texture = gtc->_gltex;
|
||||
_c->texture_2d_enabled = true;
|
||||
|
||||
_texfilter_state = 0;
|
||||
if (gtc->get_texture()->uses_mipmaps()) {
|
||||
_texfilter_state = 1;
|
||||
}
|
||||
|
||||
GLTexture *gltex = gtc->_gltex;
|
||||
|
||||
if (gtc->was_image_modified() || gltex->num_levels == 0) {
|
||||
@ -1808,13 +1828,15 @@ setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int TinyGraphicsStateGuardian::
|
||||
get_tex_shift(int orig_size) {
|
||||
unsigned int filled = flood_bits_down((unsigned int)(orig_size - 1));
|
||||
int size = filled + 1;
|
||||
if (size != orig_size || size > _max_texture_dimension) {
|
||||
if ((orig_size & (orig_size - 1)) != 0) {
|
||||
// Not a power of 2.
|
||||
return -1;
|
||||
}
|
||||
if (orig_size > _max_texture_dimension) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count_bits_in_word((unsigned int)size - 1);
|
||||
return count_bits_in_word((unsigned int)orig_size - 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -136,6 +136,7 @@ private:
|
||||
};
|
||||
int _color_material_flags;
|
||||
int _texfilter_state;
|
||||
bool _texture_replace;
|
||||
|
||||
SimpleLru _textures_lru;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "zfeatures.h"
|
||||
#include "bitMask.h"
|
||||
#include "pbitops.h"
|
||||
|
||||
typedef unsigned short ZPOINT;
|
||||
#define ZB_Z_BITS 16
|
||||
@ -23,7 +23,7 @@ typedef unsigned short ZPOINT;
|
||||
/* This is the theoretical max number of bits we have available to
|
||||
shift down to achieve each next mipmap level, based on the size of
|
||||
a 32-bit int. We need to preallocate mipmap arrays of this size. */
|
||||
#define MAX_MIPMAP_LEVELS (32 - ZB_POINT_ST_FRAC_BITS)
|
||||
#define MAX_MIPMAP_LEVELS (32 - ZB_POINT_ST_FRAC_BITS + 1)
|
||||
|
||||
/* Returns the index within a texture level for the given (s, t) texel. */
|
||||
#define ZB_TEXEL(level, s, t) \
|
||||
@ -36,8 +36,15 @@ typedef unsigned short ZPOINT;
|
||||
#define ZB_LOOKUP_TEXTURE_NEAREST_MIPMAP(texture_levels, s, t, level) \
|
||||
ZB_LOOKUP_TEXTURE_NEAREST((texture_levels) + (level), (s) >> (level), (t) >> (level))
|
||||
|
||||
/* A special abs() function which doesn't require any branching
|
||||
instructions. Might not work on some exotic hardware. */
|
||||
|
||||
/* Also doesn't appear to be any faster in practice. Guess gcc is
|
||||
already doing the right thing. Is msvc? */
|
||||
//#define FAST_ABS(v) (((v) ^ ((v) >> (sizeof(v) * 8 - 1))) - ((v) >> (sizeof(v) * 8 - 1)))
|
||||
|
||||
#define DO_CALC_MIPMAP_LEVEL \
|
||||
mipmap_level = count_bits_in_word(flood_bits_down((unsigned int)max(abs(dsdx), abs(dtdx)) >> ZB_POINT_ST_FRAC_BITS))
|
||||
mipmap_level = get_next_higher_bit(((unsigned int)abs(dsdx) + (unsigned int)abs(dtdx)) >> ZB_POINT_ST_FRAC_BITS)
|
||||
|
||||
#if 0
|
||||
/* Experiment with bilinear filtering. Looks great, but seems to run
|
||||
|
@ -69,6 +69,8 @@
|
||||
return;
|
||||
fz = 1.0f / fz;
|
||||
|
||||
EARLY_OUT_FZ();
|
||||
|
||||
fdx1 *= fz;
|
||||
fdy1 *= fz;
|
||||
fdx2 *= fz;
|
||||
@ -378,6 +380,7 @@
|
||||
#undef INTERP_STZ
|
||||
|
||||
#undef EARLY_OUT
|
||||
#undef EARLY_OUT_FZ
|
||||
#undef DRAW_INIT
|
||||
#undef DRAW_LINE
|
||||
#undef PUT_PIXEL
|
||||
|
@ -30,7 +30,7 @@ Options = [
|
||||
# The various combinations of these options are explicit within
|
||||
# ztriangle_two.h.
|
||||
ExtraOptions = [
|
||||
# shading
|
||||
# shade model
|
||||
[ 'white', 'flat', 'smooth' ],
|
||||
|
||||
# texturing
|
||||
|
@ -7,18 +7,22 @@ static void FNAME(white_untextured) (ZBuffer *zb,
|
||||
{ \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
STORE_PIX(pp[_a], 0xffffffffUL, 0xffffUL, 0xffffUL, 0xffffUL, 0xffffUL); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
STORE_PIX(pp[_a], 0xffffffffUL, 0xffffUL, 0xffffUL, 0xffffUL, 0xffffUL); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
}
|
||||
|
||||
#include "ztriangle.h"
|
||||
@ -36,6 +40,10 @@ static void FNAME(flat_untextured) (ZBuffer *zb,
|
||||
{ \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
if (!ACMP(zb, p2->a)) { \
|
||||
@ -80,10 +88,14 @@ static void FNAME(smooth_untextured) (ZBuffer *zb,
|
||||
c2 = RGBA_TO_PIXEL(p2->r, p2->g, p2->b, p2->a); \
|
||||
if (c0 == c1 && c0 == c2) { \
|
||||
/* It's really a flat-shaded triangle. */ \
|
||||
FNAME(flat_untextured)(zb, p0, p1, p2); \
|
||||
FNAME(flat_untextured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
@ -120,16 +132,20 @@ static void FNAME(white_textured) (ZBuffer *zb,
|
||||
{ \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
texture_levels = zb->current_texture; \
|
||||
texture_levels = zb->current_texture; \
|
||||
}
|
||||
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
if (ACMP(zb, PIXEL_A(tmp))) { \
|
||||
STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
@ -156,37 +172,41 @@ static void FNAME(flat_textured) (ZBuffer *zb,
|
||||
{ \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
texture_levels = zb->current_texture; \
|
||||
texture_levels = zb->current_texture; \
|
||||
or0 = p2->r; \
|
||||
og0 = p2->g; \
|
||||
ob0 = p2->b; \
|
||||
oa0 = p2->a; \
|
||||
}
|
||||
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa0 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa0 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
}
|
||||
|
||||
#include "ztriangle.h"
|
||||
@ -201,55 +221,59 @@ static void FNAME(smooth_textured) (ZBuffer *zb,
|
||||
#define INTERP_ST
|
||||
#define INTERP_RGB
|
||||
|
||||
#define EARLY_OUT() \
|
||||
{ \
|
||||
int c0, c1, c2; \
|
||||
c0 = RGBA_TO_PIXEL(p0->r, p0->g, p0->b, p0->a); \
|
||||
c1 = RGBA_TO_PIXEL(p1->r, p1->g, p1->b, p1->a); \
|
||||
c2 = RGBA_TO_PIXEL(p2->r, p2->g, p2->b, p2->a); \
|
||||
if (c0 == c1 && c0 == c2) { \
|
||||
/* It's really a flat-shaded triangle. */ \
|
||||
if (c0 == 0xffffffff) { \
|
||||
/* Actually, it's a white triangle. */ \
|
||||
#define EARLY_OUT() \
|
||||
{ \
|
||||
int c0, c1, c2; \
|
||||
c0 = RGBA_TO_PIXEL(p0->r, p0->g, p0->b, p0->a); \
|
||||
c1 = RGBA_TO_PIXEL(p1->r, p1->g, p1->b, p1->a); \
|
||||
c2 = RGBA_TO_PIXEL(p2->r, p2->g, p2->b, p2->a); \
|
||||
if (c0 == c1 && c0 == c2) { \
|
||||
/* It's really a flat-shaded triangle. */ \
|
||||
if (c0 == 0xffffffff) { \
|
||||
/* Actually, it's a white triangle. */ \
|
||||
FNAME(white_textured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
FNAME(flat_textured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
FNAME(flat_textured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
texture_levels = zb->current_texture; \
|
||||
texture_levels = zb->current_texture; \
|
||||
}
|
||||
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa1 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
og1+=dgdx; \
|
||||
or1+=drdx; \
|
||||
ob1+=dbdx; \
|
||||
oa1+=dadx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa1 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
og1+=dgdx; \
|
||||
or1+=drdx; \
|
||||
ob1+=dbdx; \
|
||||
oa1+=dadx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
}
|
||||
|
||||
#include "ztriangle.h"
|
||||
@ -275,9 +299,19 @@ static void FNAME(white_perspective) (ZBuffer *zb,
|
||||
{ \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
if (fz > 0.001 || fz < -.001) { \
|
||||
/* This triangle is small enough not to worry about perspective \
|
||||
correction. */ \
|
||||
FNAME(white_textured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
texture_levels = zb->current_texture; \
|
||||
texture_levels = zb->current_texture; \
|
||||
fdzdx=(float)dzdx; \
|
||||
fndzdx=NB_INTERP * fdzdx; \
|
||||
ndszdx=NB_INTERP * dszdx; \
|
||||
@ -289,7 +323,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
if (ACMP(zb, PIXEL_A(tmp))) { \
|
||||
STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
@ -302,7 +336,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
|
||||
|
||||
#define DRAW_LINE() \
|
||||
{ \
|
||||
register ZPOINT *pz; \
|
||||
register ZPOINT *pz; \
|
||||
register PIXEL *pp; \
|
||||
register unsigned int s,t,z,zz; \
|
||||
register int n,dsdx,dtdx; \
|
||||
@ -320,11 +354,11 @@ static void FNAME(white_perspective) (ZBuffer *zb,
|
||||
float ss,tt; \
|
||||
ss=(sz * zinv); \
|
||||
tt=(tz * zinv); \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
|
||||
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
fz+=fndzdx; \
|
||||
zinv=1.0f / fz; \
|
||||
} \
|
||||
@ -346,11 +380,11 @@ static void FNAME(white_perspective) (ZBuffer *zb,
|
||||
float ss,tt; \
|
||||
ss=(sz * zinv); \
|
||||
tt=(tz * zinv); \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
|
||||
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
} \
|
||||
while (n>=0) { \
|
||||
PUT_PIXEL(0); \
|
||||
@ -383,9 +417,19 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
|
||||
{ \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
if (fz > 0.001 || fz < -.001) { \
|
||||
/* This triangle is small enough not to worry about perspective \
|
||||
correction. */ \
|
||||
FNAME(flat_textured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
texture_levels = zb->current_texture; \
|
||||
texture_levels = zb->current_texture; \
|
||||
fdzdx=(float)dzdx; \
|
||||
fndzdx=NB_INTERP * fdzdx; \
|
||||
ndszdx=NB_INTERP * dszdx; \
|
||||
@ -396,33 +440,33 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
|
||||
oa0 = p2->a; \
|
||||
}
|
||||
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa0 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa0 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or0 * PIXEL_R(tmp) >> 16, \
|
||||
og0 * PIXEL_G(tmp) >> 16, \
|
||||
ob0 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
}
|
||||
|
||||
#define DRAW_LINE() \
|
||||
{ \
|
||||
register ZPOINT *pz; \
|
||||
register ZPOINT *pz; \
|
||||
register PIXEL *pp; \
|
||||
register unsigned int s,t,z,zz; \
|
||||
register int n,dsdx,dtdx; \
|
||||
@ -445,11 +489,11 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
|
||||
float ss,tt; \
|
||||
ss=(sz * zinv); \
|
||||
tt=(tz * zinv); \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
|
||||
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
fz+=fndzdx; \
|
||||
zinv=1.0f / fz; \
|
||||
} \
|
||||
@ -471,11 +515,11 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
|
||||
float ss,tt; \
|
||||
ss=(sz * zinv); \
|
||||
tt=(tz * zinv); \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
|
||||
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
} \
|
||||
while (n>=0) { \
|
||||
PUT_PIXEL(0); \
|
||||
@ -502,64 +546,74 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
|
||||
#define INTERP_STZ
|
||||
#define INTERP_RGB
|
||||
|
||||
#define EARLY_OUT() \
|
||||
{ \
|
||||
int c0, c1, c2; \
|
||||
c0 = RGBA_TO_PIXEL(p0->r, p0->g, p0->b, p0->a); \
|
||||
c1 = RGBA_TO_PIXEL(p1->r, p1->g, p1->b, p1->a); \
|
||||
c2 = RGBA_TO_PIXEL(p2->r, p2->g, p2->b, p2->a); \
|
||||
if (c0 == c1 && c0 == c2) { \
|
||||
/* It's really a flat-shaded triangle. */ \
|
||||
if (c0 == 0xffffffff) { \
|
||||
/* Actually, it's a white triangle. */ \
|
||||
#define EARLY_OUT() \
|
||||
{ \
|
||||
int c0, c1, c2; \
|
||||
c0 = RGBA_TO_PIXEL(p0->r, p0->g, p0->b, p0->a); \
|
||||
c1 = RGBA_TO_PIXEL(p1->r, p1->g, p1->b, p1->a); \
|
||||
c2 = RGBA_TO_PIXEL(p2->r, p2->g, p2->b, p2->a); \
|
||||
if (c0 == c1 && c0 == c2) { \
|
||||
/* It's really a flat-shaded triangle. */ \
|
||||
if (c0 == 0xffffffff) { \
|
||||
/* Actually, it's a white triangle. */ \
|
||||
FNAME(white_perspective)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
FNAME(flat_perspective)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
FNAME(flat_perspective)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EARLY_OUT_FZ() \
|
||||
{ \
|
||||
if (fz > 0.001 || fz < -.001) { \
|
||||
/* This triangle is small enough not to worry about perspective \
|
||||
correction. */ \
|
||||
FNAME(smooth_textured)(zb, p0, p1, p2); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DRAW_INIT() \
|
||||
{ \
|
||||
texture_levels = zb->current_texture; \
|
||||
texture_levels = zb->current_texture; \
|
||||
fdzdx=(float)dzdx; \
|
||||
fndzdx=NB_INTERP * fdzdx; \
|
||||
ndszdx=NB_INTERP * dszdx; \
|
||||
ndtzdx=NB_INTERP * dtzdx; \
|
||||
}
|
||||
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa1 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
og1+=dgdx; \
|
||||
or1+=drdx; \
|
||||
ob1+=dbdx; \
|
||||
oa1+=dadx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
#define PUT_PIXEL(_a) \
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
int a = oa1 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a), \
|
||||
or1 * PIXEL_R(tmp) >> 16, \
|
||||
og1 * PIXEL_G(tmp) >> 16, \
|
||||
ob1 * PIXEL_B(tmp) >> 16, \
|
||||
a); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
} \
|
||||
} \
|
||||
z+=dzdx; \
|
||||
og1+=dgdx; \
|
||||
or1+=drdx; \
|
||||
ob1+=dbdx; \
|
||||
oa1+=dadx; \
|
||||
s+=dsdx; \
|
||||
t+=dtdx; \
|
||||
}
|
||||
|
||||
#define DRAW_LINE() \
|
||||
{ \
|
||||
register ZPOINT *pz; \
|
||||
register ZPOINT *pz; \
|
||||
register PIXEL *pp; \
|
||||
register unsigned int s,t,z,zz; \
|
||||
register int n,dsdx,dtdx; \
|
||||
@ -582,11 +636,11 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
|
||||
float ss,tt; \
|
||||
ss=(sz * zinv); \
|
||||
tt=(tz * zinv); \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
|
||||
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
fz+=fndzdx; \
|
||||
zinv=1.0f / fz; \
|
||||
} \
|
||||
@ -608,11 +662,11 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
|
||||
float ss,tt; \
|
||||
ss=(sz * zinv); \
|
||||
tt=(tz * zinv); \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
s=(unsigned int) ss; \
|
||||
t=(unsigned int) tt; \
|
||||
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
|
||||
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
CALC_MIPMAP_LEVEL; \
|
||||
} \
|
||||
while (n>=0) { \
|
||||
PUT_PIXEL(0); \
|
||||
|
Loading…
x
Reference in New Issue
Block a user