mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-15 09:04:36 +00:00
788 lines
18 KiB
C++
788 lines
18 KiB
C++
/****************************************************************************
|
|
* MeshLab o o *
|
|
* A versatile mesh processing toolbox o o *
|
|
* _ O _ *
|
|
* Copyright(C) 2005-2008 \/)\/ *
|
|
* Visual Computing Lab /\/| *
|
|
* ISTI - Italian National Research Council | *
|
|
* \ *
|
|
* All rights reserved. *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
|
* for more details. *
|
|
* *
|
|
****************************************************************************/
|
|
|
|
#include "rfx_state.h"
|
|
|
|
// static members initialization
|
|
|
|
// the empty strings are "padding" for compatibility with RM enum
|
|
const char *RfxState::RenderStatesStrings[] = {
|
|
"GL_CurrentColor", "GL_SecondaryColor", "", "GL_ClearColor",
|
|
"GL_ClearDepth", "GL_ShadeModel", "GL_FrontFace", "GL_CullMode",
|
|
"GL_EdgeFlag",
|
|
"GL_DepthNear", "GL_DepthFar", "", "GL_FogColor", "GL_FogDensity", "GL_FogStart",
|
|
"GL_FogEnd", "GL_FogMode", "GL_PointSize", "GL_PointMin", "GL_PointMax",
|
|
"GL_PointSmooth", "GL_LineWidth", "GL_LineSmooth", "GL_PolyFrontMode",
|
|
"GL_PolyBackMode", "GL_PolySmooth", "GL_PolyOffsetFactor",
|
|
"GL_PolyOffsetUnits", "GL_PolyOffsetPoint", "GL_PolyOffsetLine",
|
|
"GL_PolyOffsetFill",
|
|
"GL_AlphaEnable", "GL_AlphaFunction", "GL_AlphaReference",
|
|
"GL_DepthEnable", "GL_DepthFunction", "GL_BlendEnable", "GL_BlendColor",
|
|
"GL_BlendSourceRGB", "GL_BlendDestRGB", "GL_BlendSourceAlpha",
|
|
"GL_BlendDestAlpha", "GL_BlendEquation", "GL_WriteMaskColor", "GL_WriteMaskDepth",
|
|
"GL_VertexProgramTwoSideARB", "GL_StencilEnable", "GL_StencilFunction",
|
|
"GL_StencilValueMask", "GL_StencilReference", "GL_StencilFail",
|
|
"GL_StencilPassDepthFail", "GL_StencilPassDepthPass", "GL_WriteMaskStencil",
|
|
"GL_ClearStencil"
|
|
};
|
|
|
|
const char *RfxState::RenderFunctionStrings[] = {
|
|
"NEVER", "LESS", "EQUAL", "LESS_EQUAL", "GREATER", "NOT_EQUAL",
|
|
"GREATER_EQUAL", "ALWAYS"
|
|
};
|
|
|
|
const char *RfxState::RenderColorStrings[] = {
|
|
"ZERO", "ONE", "SRC_COLOR", "INV_SRC_COLOR", "DEST_COLOR",
|
|
"INV_DEST_COLOR", "SRC_ALPHA", "INV_SRC_ALPHA", "DEST_ALPHA",
|
|
"INV_DEST_ALPHA", "CONST_COLOR", "INV_CONST_COLOR", "CONST_ALPHA",
|
|
"INV_CONST_ALPHA", "SRC_ALPHA_SATURATE"
|
|
};
|
|
|
|
const char *RfxState::TextureStatesStrings[] = {
|
|
"GL_TEXTURE_WRAP_S", "GL_TEXTURE_WRAP_T", "GL_TEXTURE_WRAP_R",
|
|
"GL_TEXTURE_MIN_FILTER", "GL_TEXTURE_MAG_FILTER",
|
|
"GL_TEXTURE_BORDER_COLOR", "GL_TEXTURE_MAX_ANISOTROPY_EXT",
|
|
"GL_TEXTURE_LOD_BIAS"
|
|
};
|
|
|
|
const char *RfxState::TextureWrapStrings[] = {
|
|
"GL_CLAMP", "GL_CLAMP_TO_EDGE", "GL_REPEAT", "GL_CLAMP_TO_BORDER",
|
|
"GL_MIRRORED_REPEAT"
|
|
};
|
|
|
|
// the empty string in 3rd position is for compatibility with RM enum
|
|
const char *RfxState::TextureFilterStrings[] = {
|
|
"GL_NEAREST", "GL_LINEAR", "", "GL_NEAREST_MIPMAP_NEAREST",
|
|
"GL_NEAREST_MIPMAP_LINEAR", "GL_LINEAR_MIPMAP_NEAREST",
|
|
"GL_LINEAR_MIPMAP_LINEAR"
|
|
};
|
|
|
|
|
|
RfxState::RfxState(StateType _type, int _state, long _value)
|
|
: state(_state), value(_value), type(_type)
|
|
{
|
|
}
|
|
|
|
void RfxState::SetEnvironment(GLint target)
|
|
{
|
|
if (type == RFX_SAMPLERSTATE)
|
|
SetTextureEnvironment(target);
|
|
else
|
|
SetGLEnvironment();
|
|
}
|
|
|
|
void RfxState::SetTextureEnvironment(GLint target)
|
|
{
|
|
switch (state) {
|
|
case GL_TextureWrapS:
|
|
glTexParameteri(target, GL_TEXTURE_WRAP_S, GLWrapMode());
|
|
break;
|
|
case GL_TextureWrapT:
|
|
glTexParameteri(target, GL_TEXTURE_WRAP_T, GLWrapMode());
|
|
break;
|
|
case GL_TextureWrapR:
|
|
glTexParameteri(target, GL_TEXTURE_WRAP_R, GLWrapMode());
|
|
break;
|
|
|
|
case GL_TextureMinify:
|
|
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GLFilterMode());
|
|
break;
|
|
case GL_TextureMagnify:
|
|
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GLFilterMode());
|
|
break;
|
|
|
|
case GL_TextureBorderColor:
|
|
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, DecodeColor(value));
|
|
break;
|
|
|
|
case GL_TextureMaxAnisotropyEXT:
|
|
glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, value);
|
|
break;
|
|
|
|
case GL_TextureLODBias:
|
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, value);
|
|
break;
|
|
|
|
default:
|
|
// do nothing, unsupported state
|
|
break;
|
|
}
|
|
}
|
|
|
|
inline GLint RfxState::GLWrapMode()
|
|
{
|
|
switch ((TextureWrapRfx)value) {
|
|
case GL_CLAMP_RFX:
|
|
return GL_CLAMP;
|
|
case GL_CLAMP_TO_EDGE_RFX:
|
|
return GL_CLAMP_TO_EDGE;
|
|
case GL_REPEAT_RFX:
|
|
return GL_REPEAT;
|
|
case GL_CLAMP_TO_BORDER_RFX:
|
|
return GL_CLAMP_TO_BORDER;
|
|
case GL_MIRRORED_REPEAT_RFX:
|
|
return GL_MIRRORED_REPEAT;
|
|
default:
|
|
return GL_CLAMP;
|
|
}
|
|
}
|
|
|
|
inline GLint RfxState::GLFilterMode()
|
|
{
|
|
switch ((TextureFilterRfx)value) {
|
|
case GL_NEAREST_RFX:
|
|
return GL_NEAREST;
|
|
case GL_LINEAR_RFX:
|
|
return GL_LINEAR;
|
|
case GL_NEAREST_MIPMAP_NEAREST_RFX:
|
|
return GL_NEAREST_MIPMAP_NEAREST;
|
|
case GL_NEAREST_MIPMAP_LINEAR_RFX:
|
|
return GL_NEAREST_MIPMAP_LINEAR;
|
|
case GL_LINEAR_MIPMAP_NEAREST_RFX:
|
|
return GL_LINEAR_MIPMAP_NEAREST;
|
|
case GL_LINEAR_MIPMAP_LINEAR_RFX:
|
|
return GL_LINEAR_MIPMAP_LINEAR;
|
|
default:
|
|
return GL_NEAREST;
|
|
}
|
|
}
|
|
|
|
inline GLint RfxState::GLFunctionMode()
|
|
{
|
|
switch ((FunctionRfx)value) {
|
|
case NEVER_RFX:
|
|
return GL_NEVER;
|
|
case LESS_RFX:
|
|
return GL_LESS;
|
|
case EQUAL_RFX:
|
|
return GL_EQUAL;
|
|
case LESS_EQUAL_RFX:
|
|
return GL_LEQUAL;
|
|
case GREATER_RFX:
|
|
return GL_GREATER;
|
|
case NOT_EQUAL_RFX:
|
|
return GL_NOTEQUAL;
|
|
case GREATER_EQUAL_RFX:
|
|
return GL_GEQUAL;
|
|
case ALWAYS_RFX:
|
|
return GL_ALWAYS;
|
|
default:
|
|
return GL_ALWAYS;
|
|
}
|
|
}
|
|
|
|
inline GLint RfxState::GLColorMode()
|
|
{
|
|
switch ((ColorRfx)value) {
|
|
case ZERO:
|
|
return GL_ZERO;
|
|
case ONE:
|
|
return GL_ONE;
|
|
case SRC_COLOR:
|
|
return GL_SRC_COLOR;
|
|
case INV_SRC_COLOR:
|
|
return GL_ONE_MINUS_SRC_COLOR;
|
|
case DEST_COLOR:
|
|
return GL_DST_COLOR;
|
|
case INV_DEST_COLOR:
|
|
return GL_ONE_MINUS_DST_COLOR;
|
|
case SRC_ALPHA:
|
|
return GL_SRC_ALPHA;
|
|
case INV_SRC_ALPHA:
|
|
return GL_ONE_MINUS_SRC_ALPHA;
|
|
case DEST_ALPHA:
|
|
return GL_DST_ALPHA;
|
|
case INV_DEST_ALPHA:
|
|
return GL_ONE_MINUS_DST_ALPHA;
|
|
case CONST_COLOR:
|
|
return GL_CONSTANT_COLOR;
|
|
case INV_CONST_COLOR:
|
|
return GL_ONE_MINUS_CONSTANT_COLOR;
|
|
case CONST_ALPHA:
|
|
return GL_CONSTANT_ALPHA;
|
|
case INV_CONST_ALPHA:
|
|
return GL_ONE_MINUS_CONSTANT_ALPHA;
|
|
case SRC_ALPHA_SATURATE:
|
|
return GL_SRC_ALPHA_SATURATE;
|
|
default:
|
|
return GL_ZERO;
|
|
}
|
|
}
|
|
|
|
void RfxState::SetGLEnvironment()
|
|
{
|
|
switch (state) {
|
|
case GL_CurrentColor: {
|
|
GLfloat *res = DecodeColor(value);
|
|
glColor3f(res[0], res[1], res[2]);
|
|
delete res;
|
|
}
|
|
|
|
case GL_SecondaryColor: {
|
|
GLfloat *res = DecodeColor(value);
|
|
glSecondaryColor3f(res[0], res[1], res[2]);
|
|
delete res;
|
|
break;
|
|
}
|
|
|
|
case GL_ClearColor: {
|
|
GLfloat *res = DecodeColor(value);
|
|
glClearColor(res[0], res[1], res[2], res[3]);
|
|
delete res;
|
|
break;
|
|
}
|
|
|
|
case GL_ClearDepth:
|
|
glClearDepth(value);
|
|
break;
|
|
|
|
case GL_ShadeModel:
|
|
glShadeModel((value == 1)? GL_FLAT : GL_SMOOTH);
|
|
break;
|
|
|
|
case GL_FrontFace:
|
|
glFrontFace((value == 1)? GL_CCW : GL_CW);
|
|
break;
|
|
|
|
case GL_CullMode:
|
|
if (value == 1) {
|
|
glDisable(GL_CULL_FACE);
|
|
} else {
|
|
glEnable(GL_CULL_FACE);
|
|
glCullFace((value == 2)? GL_FRONT :
|
|
((value == 3)? GL_BACK : GL_FRONT_AND_BACK));
|
|
}
|
|
break;
|
|
|
|
case GL_EdgeFlag:
|
|
glEdgeFlag(value);
|
|
break;
|
|
|
|
case GL_DepthNear:
|
|
case GL_DepthFar: {
|
|
GLfloat range[2];
|
|
glGetFloatv(GL_DEPTH_RANGE, range);
|
|
if (state == GL_DepthNear)
|
|
glDepthRange(value, range[1]);
|
|
else
|
|
glDepthRange(range[0], value);
|
|
break;
|
|
}
|
|
|
|
case GL_FogColor: {
|
|
glFogfv(GL_FOG_COLOR, DecodeColor(value));
|
|
break;
|
|
}
|
|
|
|
case GL_FogDensity:
|
|
glFogi(GL_FOG_DENSITY, value);
|
|
break;
|
|
|
|
case GL_FogStart:
|
|
glFogi(GL_FOG_START, value);
|
|
break;
|
|
|
|
case GL_FogEnd:
|
|
glFogi(GL_FOG_END, value);
|
|
break;
|
|
|
|
case GL_FogMode:
|
|
glEnable(GL_FOG);
|
|
switch ((GLint)value) {
|
|
case 1: // NONE
|
|
glDisable(GL_FOG);
|
|
break;
|
|
case 2: // LINEAR
|
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
|
break;
|
|
case 3: // EXP
|
|
glFogi(GL_FOG_MODE, GL_EXP);
|
|
break;
|
|
case 4: // EXP2
|
|
glFogi(GL_FOG_MODE, GL_EXP2);
|
|
break;
|
|
default: // UNKNOWN
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case GL_PointSize:
|
|
glPointSize(value);
|
|
break;
|
|
|
|
case GL_PointMin:
|
|
glPointParameterf(GL_POINT_SIZE_MIN, value);
|
|
break;
|
|
|
|
case GL_PointMax:
|
|
glPointParameterf(GL_POINT_SIZE_MAX_ARB, value);
|
|
break;
|
|
|
|
case GL_PointSmooth:
|
|
GLEnableDisable(GL_POINT_SMOOTH);
|
|
break;
|
|
|
|
case GL_LineWidth:
|
|
glLineWidth(value);
|
|
break;
|
|
|
|
case GL_LineSmooth:
|
|
GLEnableDisable(GL_LINE_SMOOTH);
|
|
break;
|
|
|
|
case GL_PolyFrontMode:
|
|
glPolygonMode(GL_FRONT, (value == 1)? GL_POINT :
|
|
((value == 2)? GL_LINE : GL_FILL));
|
|
break;
|
|
|
|
case GL_PolyBackMode:
|
|
glPolygonMode(GL_BACK, (value == 1)? GL_POINT :
|
|
((value == 2)? GL_LINE : GL_FILL));
|
|
break;
|
|
|
|
case GL_PolySmooth:
|
|
GLEnableDisable(GL_POLYGON_SMOOTH);
|
|
break;
|
|
|
|
case GL_PolyOffsetFactor: {
|
|
GLfloat units;
|
|
glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
|
|
glPolygonOffset(value, units);
|
|
break;
|
|
}
|
|
|
|
case GL_PolyOffsetUnits: {
|
|
GLfloat factor;
|
|
glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
|
|
glPolygonOffset(factor, value);
|
|
break;
|
|
}
|
|
|
|
case GL_PolyOffsetPoint:
|
|
GLEnableDisable(GL_POLYGON_OFFSET_POINT);
|
|
break;
|
|
|
|
case GL_PolyOffsetLine:
|
|
GLEnableDisable(GL_POLYGON_OFFSET_LINE);
|
|
break;
|
|
|
|
case GL_PolyOffsetFill:
|
|
GLEnableDisable(GL_POLYGON_OFFSET_FILL);
|
|
break;
|
|
|
|
case GL_AlphaEnable:
|
|
GLEnableDisable(GL_ALPHA_TEST);
|
|
break;
|
|
|
|
case GL_AlphaFunction: {
|
|
GLfloat ref;
|
|
glGetFloatv(GL_ALPHA_TEST_REF, &ref);
|
|
glAlphaFunc(GLFunctionMode(), ref);
|
|
break;
|
|
}
|
|
|
|
case GL_AlphaReference: {
|
|
GLint func;
|
|
glGetIntegerv(GL_ALPHA_TEST_FUNC, &func);
|
|
glAlphaFunc(func, value);
|
|
break;
|
|
}
|
|
|
|
case GL_DepthEnable:
|
|
GLEnableDisable(GL_DEPTH_TEST);
|
|
break;
|
|
|
|
case GL_DepthFunction:
|
|
glDepthFunc(GLFunctionMode());
|
|
break;
|
|
|
|
case GL_BlendEnable:
|
|
GLEnableDisable(GL_BLEND);
|
|
break;
|
|
|
|
case GL_BlendColor: {
|
|
GLfloat *res = DecodeColor(value);
|
|
glBlendColor(res[0], res[1], res[2], res[3]);
|
|
delete res;
|
|
break;
|
|
}
|
|
|
|
case GL_BlendSourceRGB:
|
|
case GL_BlendDestRGB:
|
|
case GL_BlendSourceAlpha:
|
|
case GL_BlendDestAlpha: {
|
|
GLint srcdst[4];
|
|
glGetIntegerv(GL_BLEND_SRC_RGB, &srcdst[0]);
|
|
glGetIntegerv(GL_BLEND_DST_RGB, &srcdst[1]);
|
|
glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcdst[2]);
|
|
glGetIntegerv(GL_BLEND_DST_ALPHA, &srcdst[3]);
|
|
|
|
glBlendFuncSeparate(
|
|
((state == GL_BlendSourceRGB)? GLColorMode() : srcdst[0]),
|
|
((state == GL_BlendDestRGB)? GLColorMode() : srcdst[1]),
|
|
((state == GL_BlendSourceAlpha)? GLColorMode() : srcdst[2]),
|
|
((state == GL_BlendDestAlpha)? GLColorMode() : srcdst[3]));
|
|
break;
|
|
}
|
|
|
|
case GL_BlendEquation:
|
|
switch ((GLint)value) {
|
|
case 1: // ADD
|
|
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
break;
|
|
case 2: // SUBTRACT
|
|
glBlendEquationSeparate(GL_FUNC_SUBTRACT, GL_FUNC_SUBTRACT);
|
|
break;
|
|
case 3: // REV_SUBTRACT
|
|
glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT);
|
|
break;
|
|
case 4: // MIN
|
|
glBlendEquationSeparate(GL_MIN, GL_MIN);
|
|
break;
|
|
case 5: // MAX
|
|
glBlendEquationSeparate(GL_MAX, GL_MAX);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case GL_WriteMaskColor: {
|
|
GLint val = (GLint)value;
|
|
GLboolean par[4];
|
|
par[3] = (val > 8)? GL_TRUE : GL_FALSE;
|
|
par[2] = (val -= (8 * par[3]) > 4)? GL_TRUE : GL_FALSE;
|
|
par[1] = (val -= (4 * par[2]) > 2)? GL_TRUE : GL_FALSE;
|
|
par[0] = (val -= (2 * par[1]) > 1)? GL_TRUE : GL_FALSE;
|
|
|
|
glColorMask(par[0], par[1], par[2], par[3]);
|
|
break;
|
|
}
|
|
|
|
case GL_WriteMaskDepth:
|
|
glDepthMask(value);
|
|
break;
|
|
|
|
case GL_VertexProgramTwoSideARB:
|
|
GLEnableDisable(GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
|
|
break;
|
|
|
|
case GL_StencilEnable:
|
|
GLEnableDisable(GL_STENCIL_TEST);
|
|
break;
|
|
|
|
case GL_StencilFunction:
|
|
case GL_StencilValueMask:
|
|
case GL_StencilReference: {
|
|
GLint StFun[3];
|
|
glGetIntegerv(GL_STENCIL_FUNC, &StFun[0]);
|
|
glGetIntegerv(GL_STENCIL_VALUE_MASK, &StFun[1]);
|
|
glGetIntegerv(GL_STENCIL_REF, &StFun[2]);
|
|
|
|
glStencilFunc(
|
|
(state == GL_StencilFunction)? GLFunctionMode() : StFun[0],
|
|
(state == GL_StencilValueMask)? value : StFun[1],
|
|
(state == GL_StencilReference)? value : StFun[2]);
|
|
break;
|
|
}
|
|
|
|
case GL_StencilFail:
|
|
case GL_StencilPassDepthFail:
|
|
case GL_StencilPassDepthPass: {
|
|
GLint StOp[3];
|
|
glGetIntegerv(GL_STENCIL_FAIL, &StOp[0]);
|
|
glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &StOp[1]);
|
|
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &StOp[2]);
|
|
|
|
// thanks god at least these values are equivalent to OpenGL ones,
|
|
// no mapping needed.
|
|
glStencilOp(
|
|
(state == GL_StencilFail)? value : StOp[0],
|
|
(state == GL_StencilPassDepthFail)? value : StOp[1],
|
|
(state == GL_StencilPassDepthPass)? value : StOp[2]);
|
|
break;
|
|
}
|
|
|
|
case GL_WriteMaskStencil:
|
|
glStencilMask(value);
|
|
break;
|
|
|
|
case GL_ClearStencil:
|
|
glClearStencil(value);
|
|
break;
|
|
|
|
default:
|
|
// do nothing, unsupported state
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLfloat* RfxState::DecodeColor(long val)
|
|
{
|
|
// decodes a color stored in a 32bit integer
|
|
// RM seems to "pack" an RGBA color this way:
|
|
// R: (0, 255) * 2^0 +
|
|
// G: (0, 255) * 2^8 +
|
|
// B: (0, 255) * 2^16 +
|
|
// A: (-1, -128) U (0, 127) * 2^24
|
|
|
|
enum Offsets { _R = 1, _G = 256, _B = 65536, _A = 16777216 };
|
|
GLfloat *color = new GLfloat[4];
|
|
|
|
// Alpha needs special care due to its range.
|
|
// remove Alpha component from value and remap in range [0, 255]
|
|
if (val > 0) {
|
|
color[3] = (val % _A == 0)? (short)(val / _A) : 0;
|
|
} else {
|
|
color[3] = 0.0f;
|
|
long negVal = val;
|
|
while (negVal < 0) {
|
|
color[3] -= 1.0f;
|
|
negVal += _A;
|
|
}
|
|
}
|
|
val -= (long)(_A * color[3]);
|
|
color[3] += ((color[3] < 0)? 256.0f : 0.0f);
|
|
|
|
// R, G and B components are easier to parse
|
|
color[2] = (val > _B)? (short)(val / _B) : 0;
|
|
color[1] = ((val -= (int)(_B * color[2])) > _G)? (short)(val / _G) : 0;
|
|
color[0] = ((val -= (int)(_G * color[1])) > _R)? (short)(val) : 0;
|
|
|
|
// now normalize in [0, 1] range
|
|
for (int i = 0; i < 4; ++i)
|
|
color[i] /= 255.0f;
|
|
|
|
return color;
|
|
}
|
|
|
|
inline void RfxState::GLEnableDisable(GLint GLmode)
|
|
{
|
|
if (value)
|
|
glEnable(GLmode);
|
|
else
|
|
glDisable(GLmode);
|
|
}
|
|
|
|
/***
|
|
* conversion functions from enum to strings for gui use
|
|
*/
|
|
QString RfxState::GetTextureValue()
|
|
{
|
|
switch (state) {
|
|
case GL_TextureWrapS:
|
|
case GL_TextureWrapT:
|
|
case GL_TextureWrapR:
|
|
return TextureWrapStrings[value - 1];
|
|
|
|
case GL_TextureMinify:
|
|
case GL_TextureMagnify:
|
|
return TextureFilterStrings[value];
|
|
|
|
case GL_TextureBorderColor: {
|
|
return ColorToString(DecodeColor(value));
|
|
}
|
|
|
|
case GL_TextureMaxAnisotropyEXT:
|
|
case GL_TextureLODBias:
|
|
return QString().setNum(value);
|
|
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
QString RfxState::GetRenderState()
|
|
{
|
|
// enum values are not contiguous, so play with offsets
|
|
// when looking up in strings table
|
|
|
|
if (state < 10)
|
|
return RenderStatesStrings[state - 1];
|
|
else if (state > 13 && state < 36)
|
|
return RenderStatesStrings[9 + (state - 14)];
|
|
else if (state > 40)
|
|
return RenderStatesStrings[31 + (state - 41)];
|
|
else
|
|
return "";
|
|
}
|
|
|
|
QString RfxState::GetRenderValue()
|
|
{
|
|
switch (state) {
|
|
case GL_CurrentColor:
|
|
case GL_SecondaryColor:
|
|
case GL_ClearColor:
|
|
case GL_FogColor:
|
|
case GL_BlendColor:
|
|
return ColorToString(DecodeColor(value));
|
|
|
|
case GL_ClearDepth:
|
|
case GL_DepthNear:
|
|
case GL_DepthFar:
|
|
case GL_FogDensity:
|
|
case GL_FogStart:
|
|
case GL_FogEnd:
|
|
case GL_PointSize:
|
|
case GL_PointMin:
|
|
case GL_PointMax:
|
|
case GL_LineWidth:
|
|
case GL_PolyOffsetFactor:
|
|
case GL_PolyOffsetUnits:
|
|
case GL_AlphaReference:
|
|
case GL_StencilValueMask:
|
|
case GL_StencilReference:
|
|
case GL_ClearStencil:
|
|
case GL_WriteMaskStencil:
|
|
return QString().setNum(value);
|
|
|
|
case GL_EdgeFlag:
|
|
case GL_PointSmooth:
|
|
case GL_LineSmooth:
|
|
case GL_PolySmooth:
|
|
case GL_PolyOffsetPoint:
|
|
case GL_PolyOffsetLine:
|
|
case GL_PolyOffsetFill:
|
|
case GL_AlphaEnable:
|
|
case GL_DepthEnable:
|
|
case GL_BlendEnable:
|
|
case GL_WriteMaskDepth:
|
|
case GL_VertexProgramTwoSideARB:
|
|
case GL_StencilEnable:
|
|
return (value == 1)? "TRUE" : "FALSE";
|
|
|
|
case GL_ShadeModel:
|
|
return (value == 1)? "FLAT_SHADE" : "SMOOTH_SHADE";
|
|
|
|
case GL_FrontFace:
|
|
return (value == 1)? "CCW" : "CW";
|
|
|
|
case GL_CullMode:
|
|
switch (value) {
|
|
case 1:
|
|
return "NONE";
|
|
case 2:
|
|
return "FRONT";
|
|
case 3:
|
|
return "BACK";
|
|
case 4:
|
|
return "FRONT_AND_BACK";
|
|
default:
|
|
return "";
|
|
}
|
|
|
|
case GL_FogMode:
|
|
switch (value) {
|
|
case 1:
|
|
return "NONE";
|
|
case 2:
|
|
return "LINEAR";
|
|
case 3:
|
|
return "EXP";
|
|
case 4:
|
|
return "EXP2";
|
|
default:
|
|
return "";
|
|
}
|
|
|
|
case GL_PolyFrontMode:
|
|
case GL_PolyBackMode:
|
|
return (value == 1)? "POINTS" : ((value == 2)? "LINES" : "FILL");
|
|
|
|
case GL_AlphaFunction:
|
|
case GL_DepthFunction:
|
|
case GL_StencilFunction:
|
|
return RenderFunctionStrings[value - 1];
|
|
|
|
case GL_BlendSourceRGB:
|
|
case GL_BlendDestRGB:
|
|
case GL_BlendSourceAlpha:
|
|
case GL_BlendDestAlpha:
|
|
return RenderColorStrings[value - 1];
|
|
|
|
case GL_BlendEquation:
|
|
switch (value) {
|
|
case 1:
|
|
return "ADD";
|
|
case 2:
|
|
return "SUBTRACT";
|
|
case 3:
|
|
return "REV_SUBTRACT";
|
|
case 4:
|
|
return "MIN";
|
|
case 5:
|
|
return "MAX";
|
|
default:
|
|
return "";
|
|
}
|
|
|
|
case GL_StencilFail:
|
|
case GL_StencilPassDepthFail:
|
|
case GL_StencilPassDepthPass:
|
|
switch (value) {
|
|
case GL_ZERO:
|
|
return "ZERO";
|
|
case GL_KEEP:
|
|
return "KEEP";
|
|
case GL_REPLACE:
|
|
return "REPLACE";
|
|
case GL_INCR:
|
|
return "INCR";
|
|
case GL_DECR:
|
|
return "DECR";
|
|
case GL_INVERT:
|
|
return "INVERT";
|
|
case GL_INCR_WRAP:
|
|
return "INCR_WRAP";
|
|
case GL_DECR_WRAP:
|
|
return "DECR_WRAP";
|
|
default:
|
|
return "";
|
|
}
|
|
|
|
case GL_WriteMaskColor: {
|
|
GLint val = (GLint)value;
|
|
QString retCol;
|
|
if (val > 8) {
|
|
retCol.append("ALPHA ");
|
|
val -= 8;
|
|
}
|
|
if (val > 4) {
|
|
retCol.append("BLUE ");
|
|
val -= 4;
|
|
}
|
|
if (val > 2) {
|
|
retCol.append("GREEN ");
|
|
val -= 2;
|
|
}
|
|
if (val > 1) {
|
|
retCol.append("RED");
|
|
val -= 1;
|
|
}
|
|
|
|
return retCol;
|
|
}
|
|
|
|
default:
|
|
return "";
|
|
}
|
|
}
|