mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
texgen
This commit is contained in:
parent
ea2f07943a
commit
a9825fe78f
@ -636,27 +636,72 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
GeomVertexReader rcolor, rnormal;
|
||||
|
||||
// We now support up to 2-stage multitexturing.
|
||||
GeomVertexReader rtexcoord[MAX_TEXTURE_STAGES];
|
||||
bool needs_texcoord[MAX_TEXTURE_STAGES] = { false, false };
|
||||
bool needs_texmat[MAX_TEXTURE_STAGES] = { false, false };
|
||||
LMatrix4f texmat[MAX_TEXTURE_STAGES];
|
||||
const InternalName *texcoord_name[MAX_TEXTURE_STAGES] = {
|
||||
InternalName::get_texcoord(), InternalName::get_texcoord()
|
||||
};
|
||||
GenTexcoordFunc *texgen_func[MAX_TEXTURE_STAGES];
|
||||
TexCoordData tcdata[MAX_TEXTURE_STAGES];
|
||||
|
||||
const TexGenAttrib *target_tex_gen = DCAST(TexGenAttrib, _target_rs->get_attrib_def(TexGenAttrib::get_class_slot()));
|
||||
const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
|
||||
|
||||
int max_stage_index = _target_texture->get_num_on_ff_stages();
|
||||
for (int si = 0; si < max_stage_index; ++si) {
|
||||
TextureStage *stage = _target_texture->get_on_ff_stage(si);
|
||||
rtexcoord[si] = GeomVertexReader(data_reader, stage->get_texcoord_name(),
|
||||
force);
|
||||
rtexcoord[si].set_row(_min_vertex);
|
||||
needs_texcoord[si] = rtexcoord[si].has_column();
|
||||
|
||||
if (needs_texcoord[si]) {
|
||||
const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
|
||||
if (target_tex_matrix->has_stage(stage)) {
|
||||
needs_texmat[si] = true;
|
||||
texmat[si] = target_tex_matrix->get_mat(stage);
|
||||
switch (target_tex_gen->get_mode(stage)) {
|
||||
case TexGenAttrib::M_eye_sphere_map:
|
||||
tcdata[si]._r1 = GeomVertexReader(data_reader, InternalName::get_normal(),
|
||||
force);
|
||||
tcdata[si]._r2 = GeomVertexReader(data_reader, InternalName::get_vertex(),
|
||||
force);
|
||||
texgen_func[si] = &texgen_sphere_map;
|
||||
tcdata[si]._mat = _internal_transform->get_mat();
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_eye_position:
|
||||
tcdata[si]._r1 = GeomVertexReader(data_reader, InternalName::get_vertex(),
|
||||
force);
|
||||
texgen_func[si] = &texgen_texmat;
|
||||
{
|
||||
CPT(TransformState) eye_transform =
|
||||
_cs_transform->invert_compose(_internal_transform);
|
||||
tcdata[si]._mat = eye_transform->get_mat();
|
||||
}
|
||||
if (target_tex_matrix->has_stage(stage)) {
|
||||
tcdata[si]._mat = tcdata[si]._mat * target_tex_matrix->get_mat(stage);
|
||||
}
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_world_position:
|
||||
tcdata[si]._r1 = GeomVertexReader(data_reader, InternalName::get_vertex(),
|
||||
force);
|
||||
texgen_func[si] = &texgen_texmat;
|
||||
{
|
||||
CPT(TransformState) render_transform =
|
||||
_cs_transform->compose(_scene_setup->get_world_transform());
|
||||
CPT(TransformState) world_transform =
|
||||
_internal_transform->invert_compose(render_transform);
|
||||
tcdata[si]._mat = world_transform->get_mat();
|
||||
}
|
||||
if (target_tex_matrix->has_stage(stage)) {
|
||||
tcdata[si]._mat = tcdata[si]._mat * target_tex_matrix->get_mat(stage);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Fall through: use the standard texture coordinates.
|
||||
tcdata[si]._r1 = GeomVertexReader(data_reader, stage->get_texcoord_name(),
|
||||
force);
|
||||
texgen_func[si] = &texgen_simple;
|
||||
if (target_tex_matrix->has_stage(stage)) {
|
||||
texgen_func[si] = &texgen_texmat;
|
||||
tcdata[si]._mat = target_tex_matrix->get_mat(stage);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
tcdata[si]._r1.set_row(_min_vertex);
|
||||
tcdata[si]._r2.set_row(_min_vertex);
|
||||
if (!tcdata[si]._r1.has_column()) {
|
||||
texgen_func[si] = &texgen_null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -722,18 +767,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
|
||||
// Texture coordinates.
|
||||
for (int si = 0; si < max_stage_index; ++si) {
|
||||
if (needs_texmat[si]) {
|
||||
// Transform texcoords as a four-component vector for most generality.
|
||||
LVecBase4f d = rtexcoord[si].get_data4f() * texmat[si];
|
||||
v->tex_coord[si].v[0] = d[0];
|
||||
v->tex_coord[si].v[1] = d[1];
|
||||
|
||||
} else if (needs_texcoord[si]) {
|
||||
// No need to transform, so just extract as two-component.
|
||||
const LVecBase2f &d = rtexcoord[si].get_data2f();
|
||||
v->tex_coord[si].v[0] = d[0];
|
||||
v->tex_coord[si].v[1] = d[1];
|
||||
}
|
||||
TexCoordf d;
|
||||
(*texgen_func[si])(v->tex_coord[si], tcdata[si]);
|
||||
}
|
||||
|
||||
if (needs_color) {
|
||||
@ -2974,3 +3009,76 @@ get_tex_filter_func(Texture::FilterType filter) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TinyGraphicsStateGuardian::texgen_null
|
||||
// Access: Private, Static
|
||||
// Description: Generates invalid texture coordinates. Used when
|
||||
// texture coordinate params are invalid or unsupported.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TinyGraphicsStateGuardian::
|
||||
texgen_null(V2 &result, TinyGraphicsStateGuardian::TexCoordData &) {
|
||||
result.v[0] = 0.0;
|
||||
result.v[1] = 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TinyGraphicsStateGuardian::texgen_simple
|
||||
// Access: Private, Static
|
||||
// Description: Extracts a simple 2-d texture coordinate pair from
|
||||
// the vertex data, without applying any texture matrix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TinyGraphicsStateGuardian::
|
||||
texgen_simple(V2 &result, TinyGraphicsStateGuardian::TexCoordData &tcdata) {
|
||||
// No need to transform, so just extract as two-component.
|
||||
const LVecBase2f &d = tcdata._r1.get_data2f();
|
||||
result.v[0] = d[0];
|
||||
result.v[1] = d[1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TinyGraphicsStateGuardian::texgen_simple
|
||||
// Access: Private, Static
|
||||
// Description: Extracts a simple 2-d texture coordinate pair from
|
||||
// the vertex data, and then applies a texture matrix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TinyGraphicsStateGuardian::
|
||||
texgen_texmat(V2 &result, TinyGraphicsStateGuardian::TexCoordData &tcdata) {
|
||||
// Transform texcoords as a four-component vector for most generality.
|
||||
LVecBase4f d = tcdata._r1.get_data4f() * tcdata._mat;
|
||||
result.v[0] = d[0] / d[3];
|
||||
result.v[1] = d[1] / d[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TinyGraphicsStateGuardian::texgen_sphere_map
|
||||
// Access: Private, Static
|
||||
// Description: Computes appropriate sphere map texture coordinates
|
||||
// based on the eye normal coordinates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TinyGraphicsStateGuardian::
|
||||
texgen_sphere_map(V2 &result, TinyGraphicsStateGuardian::TexCoordData &tcdata) {
|
||||
// Get the normal and point in eye coordinates.
|
||||
LVector3f n = tcdata._mat.xform_vec(tcdata._r1.get_data3f());
|
||||
LVector3f u = tcdata._mat.xform_point(tcdata._r2.get_data3f());
|
||||
|
||||
// Normalize the vectors.
|
||||
n.normalize();
|
||||
u.normalize();
|
||||
|
||||
// Compute the reflection vector.
|
||||
LVector3f r = u - n * dot(n, u) * 2.0f;
|
||||
|
||||
// compute the denominator, m.
|
||||
float m = 2.0f * csqrt(r[0] * r[0] + r[1] * r[1] + (r[2] + 1.0f) * (r[2] + 1.0f));
|
||||
|
||||
// Now we can compute the s and t coordinates.
|
||||
result.v[0] = r[0] / m + 0.5f;
|
||||
result.v[1] = r[1] / m + 0.5f;
|
||||
|
||||
/*
|
||||
cerr << "n = " << n << " u = " << u << "\n"
|
||||
<< " r = " << r << "\n"
|
||||
<< " m = " << m << ", result = " << result.v[0] << " " << result.v[1]
|
||||
<< "\n";
|
||||
*/
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "zmath.h"
|
||||
#include "zbuffer.h"
|
||||
#include "zgl.h"
|
||||
#include "geomVertexReader.h"
|
||||
|
||||
class TinyTextureContext;
|
||||
|
||||
@ -127,6 +128,19 @@ private:
|
||||
|
||||
INLINE void clear_light_state();
|
||||
|
||||
// Methods used to generate texture coordinates.
|
||||
class TexCoordData {
|
||||
public:
|
||||
GeomVertexReader _r1;
|
||||
GeomVertexReader _r2;
|
||||
LMatrix4f _mat;
|
||||
};
|
||||
typedef void GenTexcoordFunc(V2 &result, TexCoordData &tcdata);
|
||||
|
||||
static void texgen_null(V2 &result, TexCoordData &tcdata);
|
||||
static void texgen_simple(V2 &result, TexCoordData &tcdata);
|
||||
static void texgen_texmat(V2 &result, TexCoordData &tcdata);
|
||||
static void texgen_sphere_map(V2 &result, TexCoordData &tcdata);
|
||||
public:
|
||||
// Filled in by the Tiny*GraphicsWindow at begin_frame().
|
||||
ZBuffer *_current_frame_buffer;
|
||||
|
@ -105,7 +105,7 @@ typedef struct GLVertex {
|
||||
int edge_flag;
|
||||
V3 normal;
|
||||
V4 coord;
|
||||
V4 tex_coord[MAX_TEXTURE_STAGES];
|
||||
V2 tex_coord[MAX_TEXTURE_STAGES];
|
||||
V4 color;
|
||||
|
||||
/* computed values */
|
||||
|
@ -15,6 +15,10 @@ typedef struct {
|
||||
float m[3][4];
|
||||
} M34;
|
||||
|
||||
typedef struct {
|
||||
float v[2];
|
||||
} V2;
|
||||
|
||||
typedef struct {
|
||||
float v[3];
|
||||
} V3;
|
||||
|
Loading…
x
Reference in New Issue
Block a user