blob: ce2247bca6100c64bca7ceb84f7e5a8e6b5527ba [file] [log] [blame]
/*
Copyright (c) 2011-2013 NVIDIA Corporation
Copyright (c) 2011-2012 Cass Everitt
Copyright (c) 2012 Scott Nations
Copyright (c) 2012 Mathias Schott
Copyright (c) 2012 Nigel Stewart
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Regal push / pop attrib
Nigel Stewart, Scott Nations
*/
#ifndef __REGAL_PPA_H__
#define __REGAL_PPA_H__
#include "RegalUtil.h"
#if REGAL_EMULATION
REGAL_GLOBAL_BEGIN
#include <vector>
#include <GL/Regal.h>
#include "RegalState.h"
#include "RegalEmu.h"
#include "RegalLog.h"
#include "RegalToken.h"
#include "RegalContext.h"
#include "RegalContextInfo.h"
REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
namespace Emu {
// Work in progress...
struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transform, State::Hint,
State::Enable, State::List, State::AccumBuffer, State::Scissor, State::Viewport, State::Line,
State::Multisample, State::Eval, State::Fog, State::Point, State::PolygonStipple, State::ColorBuffer,
State::PixelMode
{
void Init(RegalContext &ctx)
{
UNUSED_PARAMETER(ctx);
activeTextureUnit = 0;
}
void Cleanup(RegalContext &ctx)
{
UNUSED_PARAMETER(ctx);
}
void PushAttrib(RegalContext *ctx, GLbitfield mask)
{
maskStack.push_back(mask);
if (mask&GL_DEPTH_BUFFER_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_DEPTH_BUFFER_BIT ",State::Depth::toString());
depthStack.push_back(State::Depth());
depthStack.back() = *this;
mask &= ~GL_DEPTH_BUFFER_BIT;
}
if (mask&GL_STENCIL_BUFFER_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_STENCIL_BUFFER_BIT ",State::Stencil::toString());
stencilStack.push_back(State::Stencil());
stencilStack.back() = *this;
mask &= ~GL_STENCIL_BUFFER_BIT;
}
if (mask&GL_POLYGON_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_POLYGON_BIT ",State::Polygon::toString());
polygonStack.push_back(State::Polygon());
polygonStack.back() = *this;
mask &= ~GL_POLYGON_BIT;
}
if (mask&GL_TRANSFORM_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_TRANSFORM_BIT ",State::Transform::toString());
transformStack.push_back(State::Transform());
transformStack.back() = *this;
mask &= ~GL_TRANSFORM_BIT;
}
if (mask&GL_HINT_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_HINT_BIT ",State::Hint::toString());
hintStack.push_back(State::Hint());
hintStack.back() = *this;
mask &= ~GL_HINT_BIT;
}
if (mask&GL_ENABLE_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_ENABLE_BIT ",State::Enable::toString());
enableStack.push_back(State::Enable());
enableStack.back() = *this;
mask &= ~GL_ENABLE_BIT;
}
if (mask&GL_LIST_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_LIST_BIT ",State::List::toString());
listStack.push_back(State::List());
listStack.back() = *this;
mask &= ~GL_LIST_BIT;
}
if (mask&GL_ACCUM_BUFFER_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_ACCUM_BUFFER_BIT ",State::AccumBuffer::toString());
accumBufferStack.push_back(State::AccumBuffer());
accumBufferStack.back() = *this;
mask &= ~GL_ACCUM_BUFFER_BIT;
}
if (mask&GL_SCISSOR_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_SCISSOR_BIT ",State::Scissor::toString());
if (!State::Scissor::defined())
State::Scissor::define(ctx->dispatcher.emulation);
scissorStack.push_back(State::Scissor());
scissorStack.back() = *this;
mask &= ~GL_SCISSOR_BIT;
}
if (mask&GL_VIEWPORT_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_VIEWPORT_BIT ",State::Viewport::toString());
if (!State::Viewport::defined())
State::Viewport::define(ctx->dispatcher.emulation);
viewportStack.push_back(State::Viewport());
viewportStack.back() = *this;
mask &= ~GL_VIEWPORT_BIT;
}
if (mask&GL_LINE_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_LINE_BIT ",State::Line::toString());
lineStack.push_back(State::Line());
lineStack.back() = *this;
mask &= ~GL_LINE_BIT;
}
if (mask&GL_MULTISAMPLE_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_MULTISAMPLE_BIT ",State::Multisample::toString());
multisampleStack.push_back(State::Multisample());
multisampleStack.back() = *this;
mask &= ~GL_MULTISAMPLE_BIT;
}
if (mask&GL_EVAL_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_EVAL_BIT ",State::Eval::toString());
evalStack.push_back(State::Eval());
evalStack.back() = *this;
mask &= ~GL_EVAL_BIT;
}
if (mask&GL_FOG_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_FOG_BIT ",State::Fog::toString());
fogStack.push_back(State::Fog());
fogStack.back() = *this;
mask &= ~GL_FOG_BIT;
}
if (mask&GL_POINT_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_POINT_BIT ",State::Point::toString());
pointStack.push_back(State::Point());
pointStack.back() = *this;
mask &= ~GL_POINT_BIT;
}
if (mask&GL_POLYGON_STIPPLE_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_POLYGON_STIPPLE_BIT ",State::PolygonStipple::toString());
polygonStippleStack.push_back(State::PolygonStipple());
polygonStippleStack.back() = *this;
mask &= ~GL_POLYGON_STIPPLE_BIT;
}
if (mask&GL_COLOR_BUFFER_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_COLOR_BUFFER_BIT ",State::ColorBuffer::toString());
if (!State::ColorBuffer::defined())
State::ColorBuffer::define(ctx->dispatcher.emulation);
colorBufferStack.push_back(State::ColorBuffer());
colorBufferStack.back() = *this;
mask &= ~GL_COLOR_BUFFER_BIT;
}
if (mask&GL_PIXEL_MODE_BIT)
{
Internal("Regal::Ppa::PushAttrib GL_PIXEL_MODE_BIT ",State::PixelMode::toString());
if (!State::PixelMode::defined())
State::PixelMode::define(ctx->dispatcher.emulation);
pixelModeStack.push_back(State::PixelMode());
pixelModeStack.back() = *this;
mask &= ~GL_PIXEL_MODE_BIT;
}
// Pass the rest through, for now
RegalAssert(ctx);
if (ctx->info->core || ctx->info->es1 || ctx->info->es2)
return;
if (mask)
ctx->dispatcher.emulation.glPushAttrib(mask);
}
void PopAttrib(RegalContext *ctx)
{
RegalAssert(ctx);
RegalAssert(maskStack.size());
if (maskStack.size())
{
GLbitfield mask = maskStack.back();
maskStack.pop_back();
if (mask&GL_DEPTH_BUFFER_BIT)
{
RegalAssert(depthStack.size());
State::Depth::swap(depthStack.back());
depthStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_DEPTH_BUFFER_BIT ",State::Depth::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Depth::set(ctx->dispatcher.emulation);
mask &= ~GL_DEPTH_BUFFER_BIT;
}
if (mask&GL_STENCIL_BUFFER_BIT)
{
RegalAssert(stencilStack.size());
State::Stencil::swap(stencilStack.back());
stencilStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_STENCIL_BUFFER_BIT ",State::Stencil::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Stencil::set(ctx->dispatcher.emulation);
mask &= ~GL_STENCIL_BUFFER_BIT;
}
if (mask&GL_POLYGON_BIT)
{
RegalAssert(polygonStack.size());
State::Polygon::swap(polygonStack.back());
polygonStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_POLYGON_BIT ",State::Polygon::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Polygon::set(ctx->dispatcher.emulation);
mask &= ~GL_POLYGON_BIT;
}
if (mask&GL_TRANSFORM_BIT)
{
RegalAssert(transformStack.size());
State::Transform::swap(transformStack.back());
Internal("Regal::Ppa::PopAttrib GL_TRANSFORM_BIT ",State::Transform::toString());
State::Transform::transition(ctx->dispatcher.emulation, transformStack.back());
transformStack.pop_back();
mask &= ~GL_TRANSFORM_BIT;
}
if (mask&GL_HINT_BIT)
{
RegalAssert(hintStack.size());
State::Hint::swap(hintStack.back());
hintStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_HINT_BIT ",State::Hint::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Hint::set(ctx->dispatcher.emulation);
mask &= ~GL_HINT_BIT;
}
if (mask&GL_ENABLE_BIT)
{
RegalAssert(enableStack.size());
State::Enable::swap(enableStack.back());
enableStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_ENABLE_BIT ",State::Enable::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Enable::set(ctx->dispatcher.emulation);
mask &= ~GL_ENABLE_BIT;
}
if (mask&GL_LIST_BIT)
{
RegalAssert(listStack.size());
State::List::swap(listStack.back());
listStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_LIST_BIT ",State::List::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::List::set(ctx->dispatcher.emulation);
mask &= ~GL_LIST_BIT;
}
if (mask&GL_ACCUM_BUFFER_BIT)
{
RegalAssert(accumBufferStack.size());
State::AccumBuffer::swap(accumBufferStack.back());
accumBufferStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_ACCUM_BUFFER_BIT ",State::AccumBuffer::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::AccumBuffer::set(ctx->dispatcher.emulation);
mask &= ~GL_ACCUM_BUFFER_BIT;
}
if (mask&GL_SCISSOR_BIT)
{
RegalAssert(scissorStack.size());
State::Scissor::swap(scissorStack.back());
scissorStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_SCISSOR_BIT ",State::Scissor::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
if (!State::Scissor::defined())
State::Scissor::define(ctx->dispatcher.emulation);
State::Scissor::set(ctx->dispatcher.emulation);
mask &= ~GL_SCISSOR_BIT;
}
if (mask&GL_VIEWPORT_BIT)
{
RegalAssert(viewportStack.size());
State::Viewport::swap(viewportStack.back());
viewportStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_VIEWPORT_BIT ",State::Viewport::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
if (!State::Viewport::defined())
State::Viewport::define(ctx->dispatcher.emulation);
State::Viewport::set(ctx->dispatcher.emulation);
mask &= ~GL_VIEWPORT_BIT;
}
if (mask&GL_LINE_BIT)
{
RegalAssert(lineStack.size());
State::Line::swap(lineStack.back());
lineStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_LINE_BIT ",State::Line::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Line::set(ctx->dispatcher.emulation);
mask &= ~GL_LINE_BIT;
}
if (mask&GL_MULTISAMPLE_BIT)
{
RegalAssert(multisampleStack.size());
State::Multisample::swap(multisampleStack.back());
multisampleStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_MULTISAMPLE_BIT ",State::Multisample::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Multisample::set(ctx->dispatcher.emulation);
mask &= ~GL_MULTISAMPLE_BIT;
}
if (mask&GL_EVAL_BIT)
{
RegalAssert(evalStack.size());
State::Eval::swap(evalStack.back());
evalStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_EVAL_BIT ",State::Eval::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Eval::set(ctx->dispatcher.emulation);
mask &= ~GL_EVAL_BIT;
}
if (mask&GL_FOG_BIT)
{
RegalAssert(fogStack.size());
State::Fog::swap(fogStack.back());
fogStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_FOG_BIT ",State::Fog::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Fog::set(ctx->dispatcher.emulation);
mask &= ~GL_FOG_BIT;
}
if (mask&GL_POINT_BIT)
{
RegalAssert(pointStack.size());
State::Point::swap(pointStack.back());
pointStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_POINT_BIT ",State::Point::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::Point::set(ctx->dispatcher.emulation);
mask &= ~GL_POINT_BIT;
}
if (mask&GL_POLYGON_STIPPLE_BIT)
{
RegalAssert(polygonStippleStack.size());
State::PolygonStipple::swap(polygonStippleStack.back());
polygonStippleStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_POLYGON_STIPPLE_BIT ",State::PolygonStipple::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
State::PolygonStipple::set(ctx->dispatcher.emulation);
mask &= ~GL_POLYGON_STIPPLE_BIT;
}
if (mask&GL_COLOR_BUFFER_BIT)
{
RegalAssert(colorBufferStack.size());
State::ColorBuffer::swap(colorBufferStack.back());
colorBufferStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_COLOR_BUFFER_BIT ",State::ColorBuffer::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
if (!State::ColorBuffer::defined())
State::ColorBuffer::define(ctx->dispatcher.emulation);
State::ColorBuffer::set(ctx->dispatcher.emulation);
mask &= ~GL_COLOR_BUFFER_BIT;
}
if (mask&GL_PIXEL_MODE_BIT)
{
RegalAssert(pixelModeStack.size());
State::PixelMode::swap(pixelModeStack.back());
pixelModeStack.pop_back();
Internal("Regal::Ppa::PopAttrib GL_PIXEL_MODE_BIT ",State::PixelMode::toString());
// Ideally we'd only set the state that has changed
// since the glPushAttrib() - revisit
if (!State::PixelMode::defined())
State::PixelMode::define(ctx->dispatcher.emulation);
State::PixelMode::set(ctx->dispatcher.emulation);
mask &= ~GL_PIXEL_MODE_BIT;
}
// Pass the rest through, for now
if (ctx->info->core || ctx->info->es1 || ctx->info->es2)
return;
if (mask)
ctx->dispatcher.emulation.glPopAttrib();
}
}
template <typename T> bool Get(RegalContext *ctx, GLenum pname, T *params)
{
RegalAssert(ctx);
if (ctx->info->core || ctx->info->es1 || ctx->info->es2)
{
switch (pname)
{
case GL_ACCUM_RED_BITS:
case GL_ACCUM_GREEN_BITS:
case GL_ACCUM_BLUE_BITS:
case GL_ACCUM_ALPHA_BITS:
if (params) {
params[0] = 32;
}
break;
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
case GL_INDEX_BITS:
case GL_STENCIL_BITS:
if (params) {
params[0] = 8;
}
break;
case GL_DEPTH_BITS:
if (params) {
params[0] = 24;
}
break;
case GL_AUX_BUFFERS:
case GL_LINE_STIPPLE:
case GL_MAX_PIXEL_MAP_TABLE:
case GL_MAX_NAME_STACK_DEPTH:
case GL_MAX_LIST_NESTING:
case GL_MAX_EVAL_ORDER:
case GL_MAX_ATTRIB_STACK_DEPTH:
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
if (params)
params[0] = 0;
break;
default:
return false;
}
return true;
}
return false;
}
bool SetEnable(RegalContext *ctx, GLenum cap, GLboolean enabled)
{
switch (cap)
{
case GL_ALPHA_TEST: State::Enable::alphaTest = State::ColorBuffer::alphaTest = enabled; break;
case GL_AUTO_NORMAL: State::Enable::autoNormal = enabled; break;
case GL_CLIP_DISTANCE0:
case GL_CLIP_DISTANCE1:
case GL_CLIP_DISTANCE2:
case GL_CLIP_DISTANCE3:
case GL_CLIP_DISTANCE4:
case GL_CLIP_DISTANCE5:
case GL_CLIP_DISTANCE6:
case GL_CLIP_DISTANCE7: State::Enable::clipDistance[cap-GL_CLIP_DISTANCE0] = enabled; break;
case GL_COLOR_LOGIC_OP: State::Enable::colorLogicOp = State::ColorBuffer::colorLogicOp = enabled; break;
case GL_COLOR_MATERIAL: State::Enable::colorMaterial = enabled; break;
case GL_COLOR_SUM: State::Enable::colorSum = enabled; break;
case GL_COLOR_TABLE: State::Enable::colorTable = State::PixelMode::colorTable = enabled; break;
case GL_CONVOLUTION_1D: State::Enable::convolution1d = State::PixelMode::convolution1d = enabled; break;
case GL_CONVOLUTION_2D: State::Enable::convolution2d = State::PixelMode::convolution2d = enabled; break;
case GL_CULL_FACE: State::Enable::cullFace = enabled;
State::Polygon::cullEnable = enabled; break;
case GL_DEPTH_CLAMP: State::Enable::depthClamp = enabled;
State::Transform::depthClamp = enabled; break;
case GL_DEPTH_TEST: State::Depth::enable = enabled;
State::Enable::depthTest = enabled; break;
case GL_DITHER: State::Enable::dither = State::ColorBuffer::dither = enabled; break;
case GL_FOG: State::Enable::fog = enabled; break;
case GL_FRAMEBUFFER_SRGB: State::Enable::framebufferSRGB = State::ColorBuffer::framebufferSRGB = enabled; break;
case GL_HISTOGRAM: State::Enable::histogram = State::PixelMode::histogram = enabled; break;
case GL_INDEX_LOGIC_OP: State::Enable::indexLogicOp = State::ColorBuffer::indexLogicOp = enabled; break;
case GL_LIGHT0:
case GL_LIGHT1:
case GL_LIGHT2:
case GL_LIGHT3:
case GL_LIGHT4:
case GL_LIGHT5:
case GL_LIGHT6:
case GL_LIGHT7: State::Enable::light[cap-GL_LIGHT0] = enabled; break;
case GL_LIGHTING: State::Enable::lighting = enabled; break;
case GL_LINE_SMOOTH: State::Enable::lineSmooth = State::Line::smooth = enabled; break;
case GL_LINE_STIPPLE: State::Enable::lineStipple = State::Line::stipple = enabled; break;
case GL_MAP1_COLOR_4: State::Enable::map1Color4 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_INDEX: State::Enable::map1Index = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_NORMAL: State::Enable::map1Normal = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_TEXTURE_COORD_1: State::Enable::map1TextureCoord1 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_TEXTURE_COORD_2: State::Enable::map1TextureCoord2 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_TEXTURE_COORD_3: State::Enable::map1TextureCoord3 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_TEXTURE_COORD_4: State::Enable::map1TextureCoord4 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_VERTEX_3: State::Enable::map1Vertex3 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP1_VERTEX_4: State::Enable::map1Vertex4 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled; break;
case GL_MAP2_COLOR_4: State::Enable::map2Color4 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_INDEX: State::Enable::map2Index = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_NORMAL: State::Enable::map2Normal = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_TEXTURE_COORD_1: State::Enable::map2TextureCoord1 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_TEXTURE_COORD_2: State::Enable::map2TextureCoord2 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_TEXTURE_COORD_3: State::Enable::map2TextureCoord3 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_TEXTURE_COORD_4: State::Enable::map2TextureCoord4 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_VERTEX_3: State::Enable::map2Vertex3 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MAP2_VERTEX_4: State::Enable::map2Vertex4 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled; break;
case GL_MINMAX: State::Enable::minmax = State::PixelMode::minmax = enabled; break;
case GL_MULTISAMPLE: State::Enable::multisample = enabled; break;
case GL_NORMALIZE: State::Enable::normalize = enabled;
State::Transform::normalize = enabled; break;
case GL_POINT_SMOOTH: State::Enable::pointSmooth = State::Point::smooth = enabled; break;
case GL_POINT_SPRITE: State::Enable::pointSprite = State::Point::sprite = enabled; break;
case GL_POLYGON_OFFSET_FILL: State::Enable::polygonOffsetFill = enabled;
State::Polygon::offsetFill = enabled; break;
case GL_POLYGON_OFFSET_LINE: State::Enable::polygonOffsetLine = enabled;
State::Polygon::offsetLine = enabled; break;
case GL_POLYGON_OFFSET_POINT: State::Enable::polygonOffsetPoint = enabled;
State::Polygon::offsetPoint = enabled; break;
case GL_POLYGON_SMOOTH: State::Enable::polygonSmooth = enabled;
State::Polygon::smoothEnable = enabled; break;
case GL_POLYGON_STIPPLE: State::Polygon::stippleEnable = enabled;
State::Enable::polygonStipple = enabled; break;
case GL_POST_COLOR_MATRIX_COLOR_TABLE: State::Enable::postColorMatrixColorTable = State::PixelMode::postColorMatrixColorTable = enabled; break;
case GL_POST_CONVOLUTION_COLOR_TABLE: State::Enable::postConvolutionColorTable = State::PixelMode::postConvolutionColorTable = enabled; break;
case GL_PROGRAM_POINT_SIZE: State::Enable::programPointSize = enabled; break;
case GL_RESCALE_NORMAL: State::Enable::rescaleNormal = enabled;
State::Transform::rescaleNormal = enabled; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: State::Enable::sampleAlphaToCoverage = enabled; break;
case GL_SAMPLE_ALPHA_TO_ONE: State::Enable::sampleAlphaToOne = enabled; break;
case GL_SAMPLE_COVERAGE: State::Enable::sampleCoverage = enabled; break;
case GL_SAMPLE_SHADING: State::Enable::sampleShading = enabled; break;
case GL_SCISSOR_TEST:
{
for (GLuint ii=0; ii<REGAL_MAX_VIEWPORTS; ii++)
State::Enable::scissorTest[ii] = State::Scissor::scissorTest[ii] = enabled;
}
break;
case GL_SEPARABLE_2D: State::Enable::separable2d = State::PixelMode::separable2d = enabled; break;
case GL_STENCIL_TEST: State::Enable::stencilTest = enabled;
State::Stencil::enable = enabled; break;
case GL_TEXTURE_1D: State::Enable::texture1d[activeTextureUnit] = enabled; break;
case GL_TEXTURE_2D: State::Enable::texture2d[activeTextureUnit] = enabled; break;
case GL_TEXTURE_3D: State::Enable::texture3d[activeTextureUnit] = enabled; break;
case GL_TEXTURE_CUBE_MAP: State::Enable::textureCubeMap[activeTextureUnit] = enabled; break;
case GL_TEXTURE_GEN_S: State::Enable::textureGenS[activeTextureUnit] = enabled; break;
case GL_TEXTURE_GEN_T: State::Enable::textureGenT[activeTextureUnit] = enabled; break;
case GL_TEXTURE_GEN_R: State::Enable::textureGenR[activeTextureUnit] = enabled; break;
case GL_TEXTURE_GEN_Q: State::Enable::textureGenQ[activeTextureUnit] = enabled; break;
case GL_VERTEX_PROGRAM_TWO_SIDE: State::Enable::vertexProgramTwoSide = enabled; break;
default: break;
}
if (ctx->info->core || ctx->info->es1 || ctx->info->es2)
{
switch( cap )
{
case GL_POINT_SMOOTH:
case GL_LINE_STIPPLE:
return true;
default:
break;
}
}
return false;
}
bool SetEnablei(RegalContext *ctx, GLenum cap, GLuint index, GLboolean enabled)
{
UNUSED_PARAMETER(ctx);
switch (cap)
{
case GL_BLEND:
if (index < REGAL_MAX_DRAW_BUFFERS)
State::Enable::blend[index] = State::ColorBuffer::blend[index] = enabled;
break;
case GL_SCISSOR_TEST:
if (index < REGAL_MAX_VIEWPORTS)
{
State::Enable::scissorTest[index] = State::Scissor::scissorTest[index] = enabled;
}
break;
default: break;
}
return false;
}
bool Enable(RegalContext *ctx, GLenum cap)
{
Internal("Regal::Ppa::Enable ",Token::toString(cap));
return SetEnable(ctx, cap, GL_TRUE);
}
bool Disable(RegalContext * ctx, GLenum cap)
{
Internal("Regal::Ppa::Disable ",Token::toString(cap));
return SetEnable(ctx, cap, GL_FALSE);
}
bool Enablei(RegalContext *ctx, GLenum cap, GLuint index)
{
Internal("Regal::Ppa::Enablei ",Token::toString(cap),index);
return SetEnablei(ctx, cap, index, GL_TRUE);
}
bool Disablei(RegalContext * ctx, GLenum cap, GLuint index)
{
Internal("Regal::Ppa::Disablei ",Token::toString(cap),index);
return SetEnablei(ctx, cap, index, GL_FALSE);
}
void glActiveTexture( GLenum tex )
{
GLuint unit = tex - GL_TEXTURE0;
if (unit < REGAL_EMU_MAX_TEXTURE_UNITS)
activeTextureUnit = unit;
else
{
Warning( "Active texture out of range: ", Token::GLtextureToString(tex), " > ", Token::GLtextureToString(GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS - 1));
return;
}
}
inline void glClampColor( GLenum target, GLenum clamp )
{
switch (target)
{
case GL_CLAMP_FRAGMENT_COLOR: State::Enable::clampFragmentColor = State::ColorBuffer::clampFragmentColor = clamp; break;
case GL_CLAMP_READ_COLOR: State::Enable::clampReadColor = State::ColorBuffer::clampReadColor = clamp; break;
case GL_CLAMP_VERTEX_COLOR: State::Enable::clampVertexColor = clamp; break;
default: break;
}
}
template <typename T> void glTexEnv(GLenum target, GLenum pname, T param)
{
if ((target == GL_POINT_SPRITE) && (pname == GL_COORD_REPLACE))
glMultiTexEnv(static_cast<GLenum>(GL_TEXTURE0+activeTextureUnit),target,pname,param);
}
template <typename T> void glTexEnvv(GLenum target, GLenum pname, const T *params)
{
if ((target == GL_POINT_SPRITE) && (pname == GL_COORD_REPLACE))
glMultiTexEnvv(static_cast<GLenum>(GL_TEXTURE0+activeTextureUnit),target,pname,params);
}
std::vector<GLbitfield> maskStack;
std::vector<State::Depth> depthStack;
std::vector<State::Stencil> stencilStack;
std::vector<State::Polygon> polygonStack;
std::vector<State::Transform> transformStack;
std::vector<State::Hint> hintStack;
std::vector<State::Enable> enableStack;
std::vector<State::List> listStack;
std::vector<State::AccumBuffer> accumBufferStack;
std::vector<State::Scissor> scissorStack;
std::vector<State::Viewport> viewportStack;
std::vector<State::Line> lineStack;
std::vector<State::Multisample> multisampleStack;
std::vector<State::Eval> evalStack;
std::vector<State::Fog> fogStack;
std::vector<State::Point> pointStack;
std::vector<State::PolygonStipple> polygonStippleStack;
std::vector<State::ColorBuffer> colorBufferStack;
std::vector<State::PixelMode> pixelModeStack;
GLuint activeTextureUnit;
};
}
REGAL_NAMESPACE_END
#endif // REGAL_EMULATION
#endif // ! __REGAL_PPA_H__