// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Context.h: Defines the Context class, managing all GL state and performing
// rendering operations.
#ifndef LIBGL_CONTEXT_H_
#define LIBGL_CONTEXT_H_
#include "ResourceManager.h"
#include "common/NameSpace.hpp"
#include "common/Object.hpp"
#include "Image.hpp"
#include "Renderer/Sampler.hpp"
#include "Renderer/Vertex.hpp"
#include "common/MatrixStack.hpp"
#define _GDI32_
#include <windows.h>
#include <GL/GL.h>
#include <GL/glext.h>
#include <map>
#include <list>
#include <vector>
namespace gl
{
class Display;
class Surface;
class Config;
void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
class Command
{
public:
Command() {};
virtual ~Command() {};
virtual void call() = 0;
};
class Command0 : public Command
{
public:
Command0(void (APIENTRY *function)())
: function(function)
{
}
virtual void call()
{
function();
}
void (APIENTRY *function)();
};
template<typename A1>
class Command1 : public Command
{
public:
Command1(void (APIENTRY *function)(A1), A1 arg1)
: function(function)
, argument1(arg1)
{
}
virtual void call()
{
function(argument1);
}
void (APIENTRY *function)(A1);
A1 argument1;
};
template<typename A1, typename A2>
class Command2 : public Command
{
public:
Command2(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)
: function(function)
, argument1(arg1)
, argument2(arg2)
{
}
virtual void call()
{
function(argument1, argument2);
}
void (APIENTRY *function)(A1, A2);
A1 argument1;
A2 argument2;
};
template<typename A1, typename A2, typename A3>
class Command3 : public Command
{
public:
Command3(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)
: function(function)
, argument1(arg1)
, argument2(arg2)
, argument3(arg3)
{
}
virtual void call()
{
function(argument1, argument2, argument3);
}
void (APIENTRY *function)(A1, A2, A3);
A1 argument1;
A2 argument2;
A3 argument3;
};
template<typename A1, typename A2, typename A3, typename A4>
class Command4 : public Command
{
public:
Command4(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)
: function(function)
, argument1(arg1)
, argument2(arg2)
, argument3(arg3)
, argument4(arg4)
{
}
virtual void call()
{
function(argument1, argument2, argument3, argument4);
}
void (APIENTRY *function)(A1, A2, A3, A4);
A1 argument1;
A2 argument2;
A3 argument3;
A4 argument4;
};
template<typename A1, typename A2, typename A3, typename A4, typename A5>
class Command5 : public Command
{
public:
Command5(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
: function(function)
, argument1(arg1)
, argument2(arg2)
, argument3(arg3)
, argument4(arg4)
, argument5(arg5)
{
}
virtual void call()
{
function(argument1, argument2, argument3, argument4, argument5);
}
void (APIENTRY *function)(A1, A2, A3, A4, A5);
A1 argument1;
A2 argument2;
A3 argument3;
A4 argument4;
A5 argument5;
};
template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
class Command6 : public Command
{
public:
Command6(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)
: function(function)
, argument1(arg1)
, argument2(arg2)
, argument3(arg3)
, argument4(arg4)
, argument5(arg5)
, argument6(arg6)
{
}
~Command6()
{
if(function == glVertexAttribArray)
{
delete[] argument6;
}
}
virtual void call()
{
function(argument1, argument2, argument3, argument4, argument5, argument6);
}
void (APIENTRY *function)(A1, A2, A3, A4, A5, A6);
A1 argument1;
A2 argument2;
A3 argument3;
A4 argument4;
A5 argument5;
A6 argument6;
};
inline Command0 *newCommand(void (APIENTRY *function)())
{
return new Command0(function);
}
template<typename A1>
Command1<A1> *newCommand(void (APIENTRY *function)(A1), A1 arg1)
{
return new Command1<A1>(function, arg1);
}
template<typename A1, typename A2>
Command2<A1, A2> *newCommand(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)
{
return new Command2<A1, A2>(function, arg1, arg2);
}
template<typename A1, typename A2, typename A3>
Command3<A1, A2, A3> *newCommand(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)
{
return new Command3<A1, A2, A3>(function, arg1, arg2, arg3);
}
template<typename A1, typename A2, typename A3, typename A4>
Command4<A1, A2, A3, A4> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)
{
return new Command4<A1, A2, A3, A4>(function, arg1, arg2, arg3, arg4);
}
template<typename A1, typename A2, typename A3, typename A4, typename A5>
Command5<A1, A2, A3, A4, A5> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
{
return new Command5<A1, A2, A3, A4, A5>(function, arg1, arg2, arg3, arg4, arg5);
}
template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
Command6<A1, A2, A3, A4, A5, A6> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)
{
return new Command6<A1, A2, A3, A4, A5, A6>(function, arg1, arg2, arg3, arg4, arg5, arg6);
}
class DisplayList
{
public:
DisplayList()
{
}
~DisplayList()
{
while(!list.empty())
{
delete list.back();
list.pop_back();
}
}
void call()
{
for(CommandList::iterator command = list.begin(); command != list.end(); command++)
{
(*command)->call();
}
}
typedef std::list<Command*> CommandList;
CommandList list;
};
struct TranslatedAttribute;
struct TranslatedIndexData;
class Device;
class Buffer;
class Shader;
class Program;
class Texture;
class Texture2D;
class TextureCubeMap;
class Framebuffer;
class Renderbuffer;
class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
class StreamingIndexBuffer;
class Stencilbuffer;
class DepthStencilbuffer;
class VertexDataManager;
class IndexDataManager;
class Fence;
class Query;
enum
{
MAX_VERTEX_ATTRIBS = 9,
MAX_UNIFORM_VECTORS = 256, // Device limit
MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3, // Reserve space for gl_DepthRange
MAX_VARYING_VECTORS = 10,
MAX_TEXTURE_IMAGE_UNITS = 2,
MAX_VERTEX_TEXTURE_IMAGE_UNITS = 1,
MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,
MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3, // Reserve space for gl_DepthRange
MAX_DRAW_BUFFERS = 1,
IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
};
const GLenum compressedTextureFormats[] =
{
GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
};
const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
const GLint multisampleCount[] = {4, 2, 1};
const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);
const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];
const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
const float ALIASED_LINE_WIDTH_RANGE_MAX = 128.0f;
const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;
const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;
const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;
enum QueryType
{
QUERY_ANY_SAMPLES_PASSED,
QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,
QUERY_TYPE_COUNT
};
struct Color
{
float red;
float green;
float blue;
float alpha;
};
// Helper structure describing a single vertex attribute
class VertexAttribute
{
public:
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(nullptr), mArrayEnabled(false)
{
mCurrentValue[0] = 0.0f;
mCurrentValue[1] = 0.0f;
mCurrentValue[2] = 0.0f;
mCurrentValue[3] = 1.0f;
}
int typeSize() const
{
switch(mType)
{
case GL_BYTE: return mSize * sizeof(GLbyte);
case GL_UNSIGNED_BYTE: return mSize * sizeof(GLubyte);
case GL_SHORT: return mSize * sizeof(GLshort);
case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
case GL_FIXED: return mSize * sizeof(GLfixed);
case GL_FLOAT: return mSize * sizeof(GLfloat);
default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);
}
}
GLsizei stride() const
{
return mStride ? mStride : typeSize();
}
// From glVertexAttribPointer
GLenum mType;
GLint mSize;
bool mNormalized;
GLsizei mStride; // 0 means natural stride
union
{
const void *mPointer;
intptr_t mOffset;
};
BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
float mCurrentValue[4]; // From glVertexAttrib
};
typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
// Helper structure to store all raw state
struct State
{
Color colorClearValue;
GLclampf depthClearValue;
int stencilClearValue;
bool cullFaceEnabled;
GLenum cullMode;
GLenum frontFace;
bool depthTestEnabled;
GLenum depthFunc;
bool blendEnabled;
GLenum sourceBlendRGB;
GLenum destBlendRGB;
GLenum sourceBlendAlpha;
GLenum destBlendAlpha;
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
Color blendColor;
bool stencilTestEnabled;
GLenum stencilFunc;
GLint stencilRef;
GLuint stencilMask;
GLenum stencilFail;
GLenum stencilPassDepthFail;
GLenum stencilPassDepthPass;
GLuint stencilWritemask;
GLenum stencilBackFunc;
GLint stencilBackRef;
GLuint stencilBackMask;
GLenum stencilBackFail;
GLenum stencilBackPassDepthFail;
GLenum stencilBackPassDepthPass;
GLuint stencilBackWritemask;
bool polygonOffsetFillEnabled;
GLfloat polygonOffsetFactor;
GLfloat polygonOffsetUnits;
bool sampleAlphaToCoverageEnabled;
bool sampleCoverageEnabled;
GLclampf sampleCoverageValue;
bool sampleCoverageInvert;
bool scissorTestEnabled;
bool ditherEnabled;
bool colorLogicOpEnabled;
GLenum logicalOperation;
GLfloat lineWidth;
GLenum generateMipmapHint;
GLenum fragmentShaderDerivativeHint;
GLint viewportX;
GLint viewportY;
GLsizei viewportWidth;
GLsizei viewportHeight;
float zNear;
float zFar;
GLint scissorX;
GLint scissorY;
GLsizei scissorWidth;
GLsizei scissorHeight;
bool colorMaskRed;
bool colorMaskGreen;
bool colorMaskBlue;
bool colorMaskAlpha;
bool depthMask;
unsigned int activeSampler; // Active texture unit selector - GL_TEXTURE0
BindingPointer<Buffer> arrayBuffer;
BindingPointer<Buffer> elementArrayBuffer;
GLuint readFramebuffer;
GLuint drawFramebuffer;
BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];
BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
GLint unpackAlignment;
GLint packAlignment;
};
class Context
{
public:
Context(const Context *shareContext);
~Context();
void makeCurrent(Surface *surface);
void markAllStateDirty();
// State manipulation
void setClearColor(float red, float green, float blue, float alpha);
void setClearDepth(float depth);
void setClearStencil(int stencil);
void setCullFaceEnabled(bool enabled);
bool isCullFaceEnabled() const;
void setCullMode(GLenum mode);
void setFrontFace(GLenum front);
void setDepthTestEnabled(bool enabled);
bool isDepthTestEnabled() const;
void setDepthFunc(GLenum depthFunc);
void setDepthRange(float zNear, float zFar);
void setBlendEnabled(bool enabled);
bool isBlendEnabled() const;
void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
void setBlendColor(float red, float green, float blue, float alpha);
void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
void setStencilTestEnabled(bool enabled);
bool isStencilTestEnabled() const;
void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
void setStencilWritemask(GLuint stencilWritemask);
void setStencilBackWritemask(GLuint stencilBackWritemask);
void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);
void setPolygonOffsetFillEnabled(bool enabled);
bool isPolygonOffsetFillEnabled() const;
void setPolygonOffsetParams(GLfloat factor, GLfloat units);
void setSampleAlphaToCoverageEnabled(bool enabled);
bool isSampleAlphaToCoverageEnabled() const;
void setSampleCoverageEnabled(bool enabled);
bool isSampleCoverageEnabled() const;
void setSampleCoverageParams(GLclampf value, bool invert);
void setDitherEnabled(bool enabled);
bool isDitherEnabled() const;
void setLineWidth(GLfloat width);
void setGenerateMipmapHint(GLenum hint);
void setFragmentShaderDerivativeHint(GLenum hint);
void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
void setScissorTestEnabled(bool enabled);
bool isScissorTestEnabled() const;
void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
void setColorMask(bool red, bool green, bool blue, bool alpha);
void setDepthMask(bool mask);
void setActiveSampler(unsigned int active);
GLuint getReadFramebufferName() const;
GLuint getDrawFramebufferName() const;
GLuint getRenderbufferName() const;
GLuint getActiveQuery(GLenum target) const;
GLuint getArrayBufferName() const;
void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);
const VertexAttribute &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
const VertexAttributeArray &getVertexAttributes();
void setUnpackAlignment(GLint alignment);
GLint getUnpackAlignment() const;
void setPackAlignment(GLint alignment);
GLint getPackAlignment() const;
// These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types
GLuint createBuffer();
GLuint createShader(GLenum type);
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
// Framebuffers are owned by the Context, so these methods do not pass through
GLuint createFramebuffer();
void deleteFramebuffer(GLuint framebuffer);
// Fences are owned by the Context
GLuint createFence();
void deleteFence(GLuint fence);
// Queries are owned by the Context
GLuint createQuery();
void deleteQuery(GLuint query);
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
void useProgram(GLuint program);
void beginQuery(GLenum target, GLuint query);
void endQuery(GLenum target);
void setFramebufferZero(Framebuffer *framebuffer);
void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, float x, float y, float z, float w);
Buffer *getBuffer(GLuint handle);
Fence *getFence(GLuint handle);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Query *getQuery(GLuint handle, bool create, GLenum type);
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
Program *getCurrentProgram();
Texture2D *getTexture2D(GLenum target);
TextureCubeMap *getTextureCubeMap();
Texture *getSamplerTexture(unsigned int sampler, TextureType type);
Framebuffer *getReadFramebuffer();
Framebuffer *getDrawFramebuffer();
bool getFloatv(GLenum pname, GLfloat *params);
bool getIntegerv(GLenum pname, GLint *params);
bool getBooleanv(GLenum pname, GLboolean *params);
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void finish();
void flush();
void recordInvalidEnum();
void recordInvalidValue();
void recordInvalidOperation();
void recordOutOfMemory();
void recordInvalidFramebufferOperation();
GLenum getError();
static int getSupportedMultisampleCount(int requested);
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask);
void setMatrixMode(GLenum mode);
void loadIdentity();
void pushMatrix();
void popMatrix();
void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void translate(GLfloat x, GLfloat y, GLfloat z);
void scale(GLfloat x, GLfloat y, GLfloat z);
void multiply(const GLdouble *m);
void multiply(const GLfloat *m);
void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
void ortho(double left, double right, double bottom, double top, double zNear, double zFar); // FIXME: GLdouble
void setLightingEnabled(bool enabled);
void setFogEnabled(bool enabled);
void setAlphaTestEnabled(bool enabled);
void alphaFunc(GLenum func, GLclampf ref);
void setTexture2DEnabled(bool enabled);
void setShadeModel(GLenum mode);
void setLightEnabled(int index, bool enable);
void setNormalizeNormalsEnabled(bool enable);
GLuint genLists(GLsizei range);
void newList(GLuint list, GLenum mode);
void endList();
void callList(GLuint list);
void deleteList(GLuint list);
GLuint getListIndex() {return listIndex;}
GLenum getListMode() {return listMode;}
void listCommand(Command *command);
void captureAttribs();
void captureDrawArrays(GLenum mode, GLint first, GLsizei count);
void restoreAttribs();
void clientActiveTexture(GLenum texture);
GLenum getClientActiveTexture() const;
unsigned int getActiveTexture() const;
void begin(GLenum mode);
void position(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void end();
void setColorMaterialEnabled(bool enable);
void setColorMaterialMode(GLenum mode);
void setColorLogicOpEnabled(bool colorLogicOpEnabled);
bool isColorLogicOpEnabled();
void setLogicalOperation(GLenum logicalOperation);
Device *getDevice();
private:
bool applyRenderTarget();
void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void applyTextures(sw::SamplerType type);
void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer);
bool cullSkipsDraw(GLenum drawMode);
bool isTriangleMode(GLenum drawMode);
State mState;
BindingPointer<Texture2D> mTexture2DZero;
BindingPointer<Texture2D> mProxyTexture2DZero;
BindingPointer<TextureCubeMap> mTextureCubeMapZero;
gl::NameSpace<Framebuffer> mFramebufferNameSpace;
gl::NameSpace<Fence, 0> mFenceNameSpace;
gl::NameSpace<Query> mQueryNameSpace;
VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager;
// Recorded errors
bool mInvalidEnum;
bool mInvalidValue;
bool mInvalidOperation;
bool mOutOfMemory;
bool mInvalidFramebufferOperation;
bool mHasBeenCurrent;
unsigned int mAppliedProgramSerial;
// state caching flags
bool mDepthStateDirty;
bool mMaskStateDirty;
bool mPixelPackingStateDirty;
bool mBlendStateDirty;
bool mStencilStateDirty;
bool mPolygonOffsetStateDirty;
bool mSampleStateDirty;
bool mFrontFaceDirty;
bool mDitherStateDirty;
bool mColorLogicOperatorDirty;
Device *device;
ResourceManager *mResourceManager;
sw::MatrixStack ¤tMatrixStack();
GLenum matrixMode;
sw::MatrixStack modelView;
sw::MatrixStack projection;
sw::MatrixStack texture[8];
GLenum listMode;
//std::map<GLuint, GLuint> listMap;
std::map<GLuint, DisplayList*> displayList;
DisplayList *list;
GLuint listIndex;
GLuint firstFreeIndex;
GLenum clientTexture;
bool drawing;
GLenum drawMode;
struct InVertex
{
sw::float4 P; // Position
sw::float4 N; // Normal
sw::float4 C; // Color
sw::float4 T0; // Texture coordinate
sw::float4 T1;
};
std::vector<InVertex> vertex;
VertexAttribute clientAttribute[MAX_VERTEX_ATTRIBS];
bool envEnable[8];
};
}
#endif // INCLUDE_CONTEXT_H_