Browse Source

Nothing really important

Panagiotis Christopoulos Charitos 13 năm trước cách đây
mục cha
commit
3aa7d9a293

+ 53 - 57
include/anki/gl/GlState.h

@@ -5,105 +5,101 @@
 #include "anki/gl/Ogl.h"
 #include "anki/util/Assert.h"
 #include "anki/util/StdTypes.h"
-#include <unordered_map>
-#include <mutex>
-#include <algorithm>
+#include "anki/util/Array.h"
+#include "anki/math/Math.h"
 
 namespace anki {
 
 class Vao;
 class Fbo;
 class ShaderProgram;
-class GlState;
 
 /// @addtogroup gl
 /// @{
 
+/// Common stuff for all states
+class GlStateCommon
+{
+public:
+	U32 getMajorVersion() const
+	{
+		ANKI_ASSERT(major != -1);
+		return (U32)major;
+	}
+	U32 getMinorVersion() const
+	{
+		ANKI_ASSERT(minor != -1);
+		return (U32)minor;
+	}
+
+	void init(const U32 major_, const U32 minor_)
+	{
+		major = (I32)major_;
+		minor = (I32)minor_;
+	}
+
+private:
+	/// Minor major GL version
+	I32 major = -1, minor = -1;
+};
+
+typedef Singleton<GlStateCommon> GlStateCommonSingleton;
+
 /// Access the GL state machine.
 /// This class saves us from calling the GL functions
 class GlState
 {
 public:
 	GlState()
-	{}
-
-	~GlState()
-	{}
-
-	void init(const U32 major_, const U32 minor_)
 	{
 		sync();
-		major = major_;
-		minor = minor_;
-#if ANKI_DEBUG
-		ANKI_ASSERT(initialized == false);
-		initialized = true;
-#endif
 	}
 
-	U32 getMajorVersion() const
-	{
-		return major;
-	}
-	U32 getMinorVersion() const
-	{
-		return minor;
-	}
+	~GlState()
+	{}
 
-	/// @name Set the Fixed Function Pipeline, Call the OpenGL functions
-	/// only when needed
+	/// @name Alter the GL state when needed
 	/// @{
-	void enable(GLenum flag, bool enable = true);
-	void disable(GLenum flag)
+	void enable(GLenum cap, Bool enable = true);
+	void disable(GLenum cap)
 	{
-		enable(flag, false);
+		enable(cap, false);
 	}
-	bool isEnabled(GLenum flag);
+	bool isEnabled(GLenum cap);
 
 	void setViewport(U32 x, U32 y, U32 w, U32 h);
-	/// @}
-
-	/// Set the current program
-	void setProgram(ShaderProgram* prog);
 
-	/// Set the current vao
-	void setVao(Vao* vao);
+	void setClearColor(const Vec4& color);
 
-	/// Set the current FBO
-	/// @param fbo If nullptr then bind the default FBO
-	void setFbo(Fbo* fbo);
+	void setClearDepthValue(const GLfloat depth);
 
-	/// @name Draw functions
-	/// @{
-	void drawElements(U32 count);
+	void setClearStencilValue(const GLint s);
 	/// @}
 
 private:
-	/// Minor major GL version
-	U32 major, minor;
-
 	/// @name The GL state
 	/// @{
-	std::unordered_map<GLenum, bool> flags;
-	static GLenum flagEnums[];
-
-	GLint viewportX;
-	GLint viewportY;
-	GLsizei viewportW;
-	GLsizei viewportH;
+	Array<Bool, 7> flags;
+	Array<GLint, 4> viewport;
+	Vec4 clearColor;
+	GLfloat clearDepthValue;
+	GLint clearStencilValue;
+
+	// XXX
+	GLenum depthFunc; 
+	Array<GLint, 4> colorMask;
+	GLint depthMask;
 	/// @}
 
-#if ANKI_DEBUG
-	Bool initialized = false;
-#endif
-
 	/// Sync the local members with the opengl ones
 	void sync();
+
+	static U getIndexFromGlEnum(const GLenum cap);
 };
 
 typedef SingletonThreadSafe<GlState> GlStateSingleton;
 /// @}
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 1 - 1
include/anki/util/Array.h

@@ -53,7 +53,7 @@ struct Array
 		return &data[0] + N;
 	}
 
-	constexpr U getSize() const
+	static constexpr U getSize()
 	{
 		return N;
 	}

+ 102 - 57
src/gl/GlState.cpp

@@ -5,55 +5,80 @@
 #include "anki/util/Assert.h"
 #include <limits>
 
-#if ANKI_DEBUG
-#	define CHECK_GL() ANKI_ASSERT(initialized == true)
-#else
-#	define CHECK_GL() ((void)0)
-#endif
-
 namespace anki {
 
 //==============================================================================
-
-GLenum GlState::flagEnums[] = {
+static Array<GLenum, 7> glCaps = {{
 	GL_DEPTH_TEST,
 	GL_BLEND,
 	GL_STENCIL_TEST,
 	GL_CULL_FACE,
 	GL_RASTERIZER_DISCARD,
 	GL_POLYGON_OFFSET_FILL,
-	0
-};
+	GL_SCISSOR_TEST
+}};
+
+//==============================================================================
+U GlState::getIndexFromGlEnum(const GLenum cap)
+{
+	static_assert(decltype(GlState::flags)::getSize() == 7, "See file");
+	U out = false;
+	switch(cap)
+	{
+	case GL_DEPTH_TEST:
+		out = 0;
+		break;
+	case GL_BLEND:
+		out = 1;
+		break;
+	case GL_STENCIL_TEST:
+		out = 2;
+		break;
+	case GL_CULL_FACE:
+		out = 3;
+		break;
+	case GL_RASTERIZER_DISCARD:
+		out = 4;
+		break;
+	case GL_POLYGON_OFFSET_FILL:
+		out = 5;
+		break;
+	case GL_SCISSOR_TEST:
+		out = 6;
+	default:
+		ANKI_ASSERT(0);
+		break;
+	}
+	return out;
+}
 
 //==============================================================================
-void GlState::enable(GLenum glFlag, bool enable)
+void GlState::enable(GLenum cap, bool enable)
 {
-	CHECK_GL();
-	ANKI_ASSERT(flags.find(glFlag) != flags.end());
-	bool state = flags[glFlag];
-	ANKI_ASSERT(glIsEnabled(glFlag) == state);
+	U index = getIndexFromGlEnum(cap);
+	Bool state = flags[index];
+	ANKI_ASSERT(glIsEnabled(cap) == state);
 
 	if(enable != state)
 	{
 		if(enable)
 		{
-			glEnable(glFlag);
+			glEnable(cap);
 		}
 		else
 		{
-			glDisable(glFlag);
+			glDisable(cap);
 		}
-		flags[glFlag] = enable;
+		flags[index] = enable;
 	}
 }
 
 //==============================================================================
-bool GlState::isEnabled(GLenum glFlag)
+Bool GlState::isEnabled(GLenum cap)
 {
-	CHECK_GL();
-	ANKI_ASSERT(flags.find(glFlag) != flags.end());
-	bool state = flags[glFlag];
-	ANKI_ASSERT(glIsEnabled(glFlag) == state);
+	U index = getIndexFromGlEnum(cap);
+	Bool state = flags[index];
+	ANKI_ASSERT(glIsEnabled(cap) == state);
 	return state;
 }
 
@@ -61,66 +86,86 @@ bool GlState::isEnabled(GLenum glFlag)
 void GlState::sync()
 {
 	// Set flags
-	GLenum* flagEnum = &flagEnums[0];
-	while(*flagEnum != 0)
+	for(U i = 0; i < glCaps.getSize(); i++)
 	{
-		flags[*flagEnum] = glIsEnabled(*flagEnum);
-		++flagEnum;
+		flags[i] = glIsEnabled(glCaps[i]);
 	}
 
 	// viewport
-	GLint viewport[4];
 	glGetIntegerv(GL_VIEWPORT, &viewport[0]);
-	viewportX = viewport[0];
-	viewportY = viewport[1];
-	viewportW = viewport[2];
-	viewportH = viewport[3];
+
+	// clear color
+	glGetFloatv(GL_COLOR_CLEAR_VALUE, &clearColor[0]);
+
+	// clear depth value
+	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepthValue);
+
+	// clear stencil value
+	glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencilValue);
 }
 
 //==============================================================================
 void GlState::setViewport(U32 x, U32 y, U32 w, U32 h)
 {
-	CHECK_GL();
-	if(x != (U32)viewportX || y != (U32)viewportY 
-		|| w != (U32)viewportW || h != (U32)viewportH)
+	if(x != (U32)viewport[0] 
+		|| y != (U32)viewport[1]
+		|| w != (U32)viewport[2] 
+		|| h != (U32)viewport[3])
 	{
 		glViewport(x, y, w, h);
-		viewportX = x;
-		viewportY = y;
-		viewportW = w;
-		viewportH = h;
+		viewport[0] = x;
+		viewport[1] = y;
+		viewport[2] = w;
+		viewport[3] = h;
 	}
 }
 
 //==============================================================================
-void GlState::setProgram(ShaderProgram* prog_)
+void GlState::setClearColor(const Vec4& color)
 {
-	CHECK_GL();
-	ANKI_ASSERT(prog_);
-	prog_->bind();
+#if ANKI_DEBUG
+	Vec4 real;
+	glGetFloatv(GL_COLOR_CLEAR_VALUE, &real[0]);
+	ANKI_ASSERT(real == clearColor);
+#endif
+
+	if(clearColor != color)
+	{
+		glClearColor(color.x(), color.y(), color.z(), color.w());
+		clearColor == color;
+	}
 }
 
 //==============================================================================
-void GlState::setFbo(Fbo* fbo_)
+void GlState::setClearDepthValue(const GLfloat depth)
 {
-	CHECK_GL();
-	if(fbo_ == nullptr)
-	{
-		Fbo::unbindAll();
-	}
-	else
+#if ANKI_DEBUG
+	GLfloat real;
+	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &real);
+	ANKI_ASSERT(real == clearDepthValue);
+#endif
+
+	if(clearDepthValue != depth)
 	{
-		ANKI_ASSERT(fbo_->isComplete());
-		fbo_->bind();
+		glClearDepthf(depth);
+		clearDepthValue = depth;
 	}
 }
 
 //==============================================================================
-void GlState::setVao(Vao* vao_)
+void GlState::setClearStencilValue(const GLint s)
 {
-	CHECK_GL();
-	ANKI_ASSERT(vao_);
-	vao_->bind();
+#if ANKI_DEBUG
+	GLint real;
+	glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &real);
+	ANKI_ASSERT(real == clearStencilValue);
+#endif
+
+	if(clearStencilValue != s)
+	{
+		glClearStencil(s);
+		clearStencilValue = s;
+	}
 }
 
-} // end namespace
+} // end namespace anki

+ 2 - 2
src/gl/ShaderProgram.cpp

@@ -306,8 +306,8 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 	const char* transformFeedbackVaryings[])
 {
 	ANKI_ASSERT(!isCreated());
-	U32 minor = GlStateSingleton::get().getMinorVersion();
-	U32 major = GlStateSingleton::get().getMajorVersion();
+	U32 minor = GlStateCommonSingleton::get().getMinorVersion();
+	U32 major = GlStateCommonSingleton::get().getMajorVersion();
 
 	// 1) create and compile the shaders
 	//

+ 3 - 3
src/renderer/MainRenderer.cpp

@@ -56,9 +56,9 @@ void MainRenderer::initGl()
 		glGetString(GL_SHADING_LANGUAGE_VERSION)));
 
 	// get max texture units
-	glClearColor(1.0, 0.0, 1.0, 1.0);
-	glClearDepthf(1.0);
-	glClearStencil(0);
+	GlStateSingleton::get().setClearColor(Vec4(1.0, 0.0, 1.0, 1.0));
+	GlStateSingleton::get().setClearDepthValue(1.0);
+	GlStateSingleton::get().setClearStencilValue(0);
 	glDepthFunc(GL_LEQUAL);
 	// CullFace is always on
 	glCullFace(GL_BACK);

+ 2 - 2
testapp/Main.cpp

@@ -339,8 +339,8 @@ void initSubsystems(int argc, char* argv[])
 	win = new NativeWindow;	
 	win->create(nwinit);
 
-	// GL
-	GlStateSingleton::get().init(glmajor, glminor);
+	// GL stuff
+	GlStateCommonSingleton::get().init(glmajor, glminor);
 
 	// Input
 	InputSingleton::get().init(win);