mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 11:55:08 +00:00
LibGL+LibSoftGPU: Implement texture coordinate generation
Texture coordinate generation is the concept of automatically generating vertex texture coordinates instead of using the provided coordinates (i.e. `glTexCoord`). This commit implements support for: * The `GL_TEXTURE_GEN_Q/R/S/T` capabilities * The `GL_OBJECT_LINEAR`, `GL_EYE_LINEAR`, `GL_SPHERE_MAP`, `GL_REFLECTION_MAP` and `GL_NORMAL_MAP` modes * Object and eye plane coefficients (write-only at the moment) This changeset allows Tux Racer to render its terrain :^)
This commit is contained in:
parent
69da279073
commit
c19632128c
5 changed files with 236 additions and 8 deletions
|
@ -652,6 +652,13 @@ void SoftwareGLContext::gl_enable(GLenum capability)
|
||||||
m_active_texture_unit->set_texture_cube_map_enabled(true);
|
m_active_texture_unit->set_texture_cube_map_enabled(true);
|
||||||
m_sampler_config_is_dirty = true;
|
m_sampler_config_is_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
case GL_TEXTURE_GEN_Q:
|
||||||
|
case GL_TEXTURE_GEN_R:
|
||||||
|
case GL_TEXTURE_GEN_S:
|
||||||
|
case GL_TEXTURE_GEN_T:
|
||||||
|
texture_coordinate_generation(capability).enabled = true;
|
||||||
|
m_texcoord_generation_dirty = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
||||||
}
|
}
|
||||||
|
@ -728,6 +735,13 @@ void SoftwareGLContext::gl_disable(GLenum capability)
|
||||||
m_active_texture_unit->set_texture_cube_map_enabled(false);
|
m_active_texture_unit->set_texture_cube_map_enabled(false);
|
||||||
m_sampler_config_is_dirty = true;
|
m_sampler_config_is_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
case GL_TEXTURE_GEN_Q:
|
||||||
|
case GL_TEXTURE_GEN_R:
|
||||||
|
case GL_TEXTURE_GEN_S:
|
||||||
|
case GL_TEXTURE_GEN_T:
|
||||||
|
texture_coordinate_generation(capability).enabled = false;
|
||||||
|
m_texcoord_generation_dirty = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
||||||
}
|
}
|
||||||
|
@ -763,6 +777,11 @@ GLboolean SoftwareGLContext::gl_is_enabled(GLenum capability)
|
||||||
return rasterizer_options.scissor_enabled;
|
return rasterizer_options.scissor_enabled;
|
||||||
case GL_STENCIL_TEST:
|
case GL_STENCIL_TEST:
|
||||||
return m_stencil_test_enabled;
|
return m_stencil_test_enabled;
|
||||||
|
case GL_TEXTURE_GEN_Q:
|
||||||
|
case GL_TEXTURE_GEN_R:
|
||||||
|
case GL_TEXTURE_GEN_S:
|
||||||
|
case GL_TEXTURE_GEN_T:
|
||||||
|
return texture_coordinate_generation(capability).enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_VALUE_WITH_ERROR_IF(true, GL_INVALID_ENUM, 0);
|
RETURN_VALUE_WITH_ERROR_IF(true, GL_INVALID_ENUM, 0);
|
||||||
|
@ -2743,8 +2762,11 @@ void SoftwareGLContext::gl_tex_gen(GLenum coord, GLenum pname, GLint param)
|
||||||
&& param != GL_REFLECTION_MAP,
|
&& param != GL_REFLECTION_MAP,
|
||||||
GL_INVALID_ENUM);
|
GL_INVALID_ENUM);
|
||||||
RETURN_WITH_ERROR_IF((coord == GL_R || coord == GL_Q) && param == GL_SPHERE_MAP, GL_INVALID_ENUM);
|
RETURN_WITH_ERROR_IF((coord == GL_R || coord == GL_Q) && param == GL_SPHERE_MAP, GL_INVALID_ENUM);
|
||||||
|
RETURN_WITH_ERROR_IF(coord == GL_Q && (param == GL_REFLECTION_MAP || param == GL_NORMAL_MAP), GL_INVALID_ENUM);
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "gl_tex_gen({:#x}, {:#x}, {}): unimplemented", coord, pname, param);
|
GLenum const capability = GL_TEXTURE_GEN_S + (coord - GL_S);
|
||||||
|
texture_coordinate_generation(capability).generation_mode = param;
|
||||||
|
m_texcoord_generation_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* params)
|
void SoftwareGLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* params)
|
||||||
|
@ -2758,6 +2780,8 @@ void SoftwareGLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat co
|
||||||
&& pname != GL_EYE_PLANE,
|
&& pname != GL_EYE_PLANE,
|
||||||
GL_INVALID_ENUM);
|
GL_INVALID_ENUM);
|
||||||
|
|
||||||
|
GLenum const capability = GL_TEXTURE_GEN_S + (coord - GL_S);
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_TEXTURE_GEN_MODE: {
|
case GL_TEXTURE_GEN_MODE: {
|
||||||
auto param = static_cast<GLenum>(params[0]);
|
auto param = static_cast<GLenum>(params[0]);
|
||||||
|
@ -2768,24 +2792,32 @@ void SoftwareGLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat co
|
||||||
&& param != GL_REFLECTION_MAP,
|
&& param != GL_REFLECTION_MAP,
|
||||||
GL_INVALID_ENUM);
|
GL_INVALID_ENUM);
|
||||||
RETURN_WITH_ERROR_IF((coord == GL_R || coord == GL_Q) && param == GL_SPHERE_MAP, GL_INVALID_ENUM);
|
RETURN_WITH_ERROR_IF((coord == GL_R || coord == GL_Q) && param == GL_SPHERE_MAP, GL_INVALID_ENUM);
|
||||||
|
RETURN_WITH_ERROR_IF(coord == GL_Q && (param == GL_REFLECTION_MAP || param == GL_NORMAL_MAP), GL_INVALID_ENUM);
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "gl_tex_gen_floatv({:#x}, {:#x}, {:p}): unimplemented", coord, pname, params);
|
texture_coordinate_generation(capability).generation_mode = param;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_OBJECT_PLANE:
|
case GL_OBJECT_PLANE:
|
||||||
|
texture_coordinate_generation(capability).object_plane_coefficients = { params[0], params[1], params[2], params[3] };
|
||||||
|
break;
|
||||||
case GL_EYE_PLANE: {
|
case GL_EYE_PLANE: {
|
||||||
GLfloat coefficient_p1 = params[0];
|
auto inverted_model_view_matrix = m_model_view_matrix.inverse();
|
||||||
GLfloat coefficient_p2 = params[1];
|
auto input_coefficients = FloatVector4 { params[0], params[1], params[2], params[3] };
|
||||||
GLfloat coefficient_p3 = params[2];
|
|
||||||
GLfloat coefficient_p4 = params[3];
|
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "gl_tex_gen_floatv({:#x}, {:#x}, {:p}): unimplemented coefficients {} {} {} {}",
|
// Note: we are allowed to store transformed coefficients here, according to the documentation on
|
||||||
coord, pname, params, coefficient_p1, coefficient_p2, coefficient_p3, coefficient_p4);
|
// `glGetTexGen`:
|
||||||
|
//
|
||||||
|
// "The returned values are those maintained in eye coordinates. They are not equal to the values
|
||||||
|
// specified using glTexGen, unless the modelview matrix was identity when glTexGen was called."
|
||||||
|
|
||||||
|
texture_coordinate_generation(capability).eye_plane_coefficients = inverted_model_view_matrix * input_coefficients;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_texcoord_generation_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::present()
|
void SoftwareGLContext::present()
|
||||||
|
@ -2796,6 +2828,7 @@ void SoftwareGLContext::present()
|
||||||
void SoftwareGLContext::sync_device_config()
|
void SoftwareGLContext::sync_device_config()
|
||||||
{
|
{
|
||||||
sync_device_sampler_config();
|
sync_device_sampler_config();
|
||||||
|
sync_device_texcoord_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::sync_device_sampler_config()
|
void SoftwareGLContext::sync_device_sampler_config()
|
||||||
|
@ -2915,4 +2948,65 @@ void SoftwareGLContext::sync_device_sampler_config()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftwareGLContext::sync_device_texcoord_config()
|
||||||
|
{
|
||||||
|
if (!m_texcoord_generation_dirty)
|
||||||
|
return;
|
||||||
|
m_texcoord_generation_dirty = false;
|
||||||
|
|
||||||
|
auto options = m_rasterizer.options();
|
||||||
|
|
||||||
|
u8 enabled_coordinates = SoftGPU::TexCoordGenerationCoordinate::None;
|
||||||
|
for (GLenum capability = GL_TEXTURE_GEN_S; capability <= GL_TEXTURE_GEN_Q; ++capability) {
|
||||||
|
auto const context_coordinate_config = texture_coordinate_generation(capability);
|
||||||
|
if (!context_coordinate_config.enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SoftGPU::TexCoordGenerationConfig* texcoord_generation_config;
|
||||||
|
switch (capability) {
|
||||||
|
case GL_TEXTURE_GEN_S:
|
||||||
|
enabled_coordinates |= SoftGPU::TexCoordGenerationCoordinate::S;
|
||||||
|
texcoord_generation_config = &options.texcoord_generation_config[0];
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_GEN_T:
|
||||||
|
enabled_coordinates |= SoftGPU::TexCoordGenerationCoordinate::T;
|
||||||
|
texcoord_generation_config = &options.texcoord_generation_config[1];
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_GEN_R:
|
||||||
|
enabled_coordinates |= SoftGPU::TexCoordGenerationCoordinate::R;
|
||||||
|
texcoord_generation_config = &options.texcoord_generation_config[2];
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_GEN_Q:
|
||||||
|
enabled_coordinates |= SoftGPU::TexCoordGenerationCoordinate::Q;
|
||||||
|
texcoord_generation_config = &options.texcoord_generation_config[3];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (context_coordinate_config.generation_mode) {
|
||||||
|
case GL_OBJECT_LINEAR:
|
||||||
|
texcoord_generation_config->mode = SoftGPU::TexCoordGenerationMode::ObjectLinear;
|
||||||
|
texcoord_generation_config->coefficients = context_coordinate_config.object_plane_coefficients;
|
||||||
|
break;
|
||||||
|
case GL_EYE_LINEAR:
|
||||||
|
texcoord_generation_config->mode = SoftGPU::TexCoordGenerationMode::EyeLinear;
|
||||||
|
texcoord_generation_config->coefficients = context_coordinate_config.eye_plane_coefficients;
|
||||||
|
break;
|
||||||
|
case GL_SPHERE_MAP:
|
||||||
|
texcoord_generation_config->mode = SoftGPU::TexCoordGenerationMode::SphereMap;
|
||||||
|
break;
|
||||||
|
case GL_REFLECTION_MAP:
|
||||||
|
texcoord_generation_config->mode = SoftGPU::TexCoordGenerationMode::ReflectionMap;
|
||||||
|
break;
|
||||||
|
case GL_NORMAL_MAP:
|
||||||
|
texcoord_generation_config->mode = SoftGPU::TexCoordGenerationMode::NormalMap;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options.texcoord_generation_enabled_coordinates = enabled_coordinates;
|
||||||
|
|
||||||
|
m_rasterizer.set_options(options);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void sync_device_config();
|
void sync_device_config();
|
||||||
void sync_device_sampler_config();
|
void sync_device_sampler_config();
|
||||||
|
void sync_device_texcoord_config();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -243,6 +244,42 @@ private:
|
||||||
Vector<TextureUnit, 32> m_texture_units;
|
Vector<TextureUnit, 32> m_texture_units;
|
||||||
TextureUnit* m_active_texture_unit;
|
TextureUnit* m_active_texture_unit;
|
||||||
|
|
||||||
|
// Texture coordinate generation state
|
||||||
|
struct TextureCoordinateGeneration {
|
||||||
|
bool enabled { false };
|
||||||
|
GLenum generation_mode { GL_EYE_LINEAR };
|
||||||
|
FloatVector4 object_plane_coefficients;
|
||||||
|
FloatVector4 eye_plane_coefficients;
|
||||||
|
};
|
||||||
|
Array<TextureCoordinateGeneration, 4> m_texture_coordinate_generation {
|
||||||
|
// S
|
||||||
|
TextureCoordinateGeneration {
|
||||||
|
.object_plane_coefficients = { 1.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
.eye_plane_coefficients = { 1.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
},
|
||||||
|
// T
|
||||||
|
TextureCoordinateGeneration {
|
||||||
|
.object_plane_coefficients = { 0.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
.eye_plane_coefficients = { 0.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
},
|
||||||
|
// R
|
||||||
|
TextureCoordinateGeneration {
|
||||||
|
.object_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
.eye_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
},
|
||||||
|
// Q
|
||||||
|
TextureCoordinateGeneration {
|
||||||
|
.object_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
.eye_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
bool m_texcoord_generation_dirty { true };
|
||||||
|
|
||||||
|
ALWAYS_INLINE TextureCoordinateGeneration& texture_coordinate_generation(GLenum capability)
|
||||||
|
{
|
||||||
|
return m_texture_coordinate_generation[capability - GL_TEXTURE_GEN_S];
|
||||||
|
}
|
||||||
|
|
||||||
SoftGPU::Device m_rasterizer;
|
SoftGPU::Device m_rasterizer;
|
||||||
SoftGPU::DeviceInfo const m_device_info;
|
SoftGPU::DeviceInfo const m_device_info;
|
||||||
bool m_sampler_config_is_dirty { true };
|
bool m_sampler_config_is_dirty { true };
|
||||||
|
|
|
@ -533,6 +533,72 @@ DeviceInfo Device::info() const
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void generate_texture_coordinates(Vertex& vertex, RasterizerOptions const& options)
|
||||||
|
{
|
||||||
|
auto generate_coordinate = [&](size_t config_index) -> float {
|
||||||
|
auto mode = options.texcoord_generation_config[config_index].mode;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case TexCoordGenerationMode::ObjectLinear: {
|
||||||
|
auto coefficients = options.texcoord_generation_config[config_index].coefficients;
|
||||||
|
return coefficients.dot(vertex.position);
|
||||||
|
}
|
||||||
|
case TexCoordGenerationMode::EyeLinear: {
|
||||||
|
auto coefficients = options.texcoord_generation_config[config_index].coefficients;
|
||||||
|
return coefficients.dot(vertex.eye_coordinates);
|
||||||
|
}
|
||||||
|
case TexCoordGenerationMode::SphereMap: {
|
||||||
|
auto const eye_unit = vertex.eye_coordinates.normalized();
|
||||||
|
FloatVector3 const eye_unit_xyz = { eye_unit.x(), eye_unit.y(), eye_unit.z() };
|
||||||
|
auto const normal = vertex.normal;
|
||||||
|
auto reflection = eye_unit_xyz - normal * 2 * normal.dot(eye_unit_xyz);
|
||||||
|
reflection.set_z(reflection.z() + 1);
|
||||||
|
auto const reflection_value = (config_index == 0) ? reflection.x() : reflection.y();
|
||||||
|
return reflection_value / (2 * reflection.length()) + 0.5f;
|
||||||
|
}
|
||||||
|
case TexCoordGenerationMode::ReflectionMap: {
|
||||||
|
auto const eye_unit = vertex.eye_coordinates.normalized();
|
||||||
|
FloatVector3 const eye_unit_xyz = { eye_unit.x(), eye_unit.y(), eye_unit.z() };
|
||||||
|
auto const normal = vertex.normal;
|
||||||
|
auto reflection = eye_unit_xyz - normal * 2 * normal.dot(eye_unit_xyz);
|
||||||
|
switch (config_index) {
|
||||||
|
case 0:
|
||||||
|
return reflection.x();
|
||||||
|
case 1:
|
||||||
|
return reflection.y();
|
||||||
|
case 2:
|
||||||
|
return reflection.z();
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case TexCoordGenerationMode::NormalMap: {
|
||||||
|
auto const normal = vertex.normal;
|
||||||
|
switch (config_index) {
|
||||||
|
case 0:
|
||||||
|
return normal.x();
|
||||||
|
case 1:
|
||||||
|
return normal.y();
|
||||||
|
case 2:
|
||||||
|
return normal.z();
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto const enabled_coords = options.texcoord_generation_enabled_coordinates;
|
||||||
|
vertex.tex_coord = {
|
||||||
|
((enabled_coords & TexCoordGenerationCoordinate::S) > 0) ? generate_coordinate(0) : vertex.tex_coord.x(),
|
||||||
|
((enabled_coords & TexCoordGenerationCoordinate::T) > 0) ? generate_coordinate(1) : vertex.tex_coord.y(),
|
||||||
|
((enabled_coords & TexCoordGenerationCoordinate::R) > 0) ? generate_coordinate(2) : vertex.tex_coord.z(),
|
||||||
|
((enabled_coords & TexCoordGenerationCoordinate::Q) > 0) ? generate_coordinate(3) : vertex.tex_coord.w(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix3x3 const& normal_transform,
|
void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix3x3 const& normal_transform,
|
||||||
FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector<Vertex> const& vertices,
|
FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector<Vertex> const& vertices,
|
||||||
Vector<size_t> const& enabled_texture_units)
|
Vector<size_t> const& enabled_texture_units)
|
||||||
|
@ -703,6 +769,13 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
|
||||||
triangle.vertices[2].normal.normalize();
|
triangle.vertices[2].normal.normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate texture coordinates if at least one coordinate is enabled
|
||||||
|
if (m_options.texcoord_generation_enabled_coordinates != TexCoordGenerationCoordinate::None) {
|
||||||
|
generate_texture_coordinates(triangle.vertices[0], m_options);
|
||||||
|
generate_texture_coordinates(triangle.vertices[1], m_options);
|
||||||
|
generate_texture_coordinates(triangle.vertices[2], m_options);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply texture transformation
|
// Apply texture transformation
|
||||||
// FIXME: implement multi-texturing: texcoords should be stored per texture unit
|
// FIXME: implement multi-texturing: texcoords should be stored per texture unit
|
||||||
triangle.vertices[0].tex_coord = texture_transform * triangle.vertices[0].tex_coord;
|
triangle.vertices[0].tex_coord = texture_transform * triangle.vertices[0].tex_coord;
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
|
|
||||||
namespace SoftGPU {
|
namespace SoftGPU {
|
||||||
|
|
||||||
|
struct TexCoordGenerationConfig {
|
||||||
|
TexCoordGenerationMode mode { TexCoordGenerationMode::EyeLinear };
|
||||||
|
FloatVector4 coefficients {};
|
||||||
|
};
|
||||||
|
|
||||||
struct RasterizerOptions {
|
struct RasterizerOptions {
|
||||||
bool shade_smooth { true };
|
bool shade_smooth { true };
|
||||||
bool enable_depth_test { false };
|
bool enable_depth_test { false };
|
||||||
|
@ -57,6 +62,8 @@ struct RasterizerOptions {
|
||||||
WindingOrder front_face { WindingOrder::CounterClockwise };
|
WindingOrder front_face { WindingOrder::CounterClockwise };
|
||||||
bool cull_back { true };
|
bool cull_back { true };
|
||||||
bool cull_front { false };
|
bool cull_front { false };
|
||||||
|
u8 texcoord_generation_enabled_coordinates { TexCoordGenerationCoordinate::None };
|
||||||
|
Array<TexCoordGenerationConfig, 4> texcoord_generation_config {};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static constexpr size_t const num_samplers = 32;
|
inline static constexpr size_t const num_samplers = 32;
|
||||||
|
|
|
@ -68,4 +68,21 @@ enum class PrimitiveType {
|
||||||
Quads,
|
Quads,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TexCoordGenerationCoordinate {
|
||||||
|
None = 0x0,
|
||||||
|
S = 0x1,
|
||||||
|
T = 0x2,
|
||||||
|
R = 0x4,
|
||||||
|
Q = 0x8,
|
||||||
|
All = 0xF,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TexCoordGenerationMode {
|
||||||
|
ObjectLinear,
|
||||||
|
EyeLinear,
|
||||||
|
SphereMap,
|
||||||
|
ReflectionMap,
|
||||||
|
NormalMap,
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue