[Bf-blender-cvs] [628ef78] blender2.8: overhaul gpuMatrix API

Mike Erwin noreply at git.blender.org
Sun Sep 25 19:29:54 CEST 2016


Commit: 628ef78e8a9db7ba37cfc1bbb6b2d4ac0dbecab3
Author: Mike Erwin
Date:   Sun Sep 25 19:29:45 2016 +0200
Branches: blender2.8
https://developer.blender.org/rB628ef78e8a9db7ba37cfc1bbb6b2d4ac0dbecab3

overhaul gpuMatrix API

Complete (for our needs) 2D & 3D transformation API. Should be easy to port legacy OpenGL matrix stack-based code to this. Still needs testing.

Ported ortho, frustum, lookAt functions from Viewport FX (rB194998766c65). Kept plenty of Viewport FX code from previous commit.

Stack API and 2D routines ported from Gawain. This version uses BLI_math library so everything is licensed under GPL instead of the usual MPL.

Part of T49450

===================================================================

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_matrix.h
M	source/blender/gpu/intern/gpu_matrix.c

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index e8e0a7b..0b3e41c 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -58,6 +58,7 @@ set(SRC
 	intern/gpu_immediate.c
 	intern/gpu_init_exit.c
 	intern/gpu_material.c
+	intern/gpu_matrix.c
 	intern/gpu_select.c
 	intern/gpu_shader.c
 	intern/gpu_texture.c
@@ -110,6 +111,7 @@ set(SRC
 	GPU_immediate.h
 	GPU_init_exit.h
 	GPU_material.h
+	GPU_matrix.h
 	GPU_select.h
 	GPU_shader.h
 	GPU_texture.h
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 4588e70..13648fd 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -23,7 +23,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): Alexandr Kuznetsov, Jason Wilkins
+ * Contributor(s): Alexandr Kuznetsov, Jason Wilkins, Mike Erwin
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -33,67 +33,87 @@
  */
 
 #include "GPU_glew.h"
+#include <stdbool.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef enum eGPUMatrixMode {
-	GPU_MODELVIEW_MATRIX = 0,
-	GPU_PROJECTION_MATRIX = 1,
-	GPU_TEXTURE_MATRIX = 2
-} eGPUMatrixMode;
+void gpuMatrixInit(void); /* called by system -- make private? */
 
-void gpuPushMatrix(eGPUMatrixMode stack);
-void gpuPopMatrix(eGPUMatrixMode stack);
 
-void gpuLoadMatrix(eGPUMatrixMode stack, const float m[16]);
-const float *gpuGetMatrix(eGPUMatrixMode stack, float m[16]);
+/* MatrixMode is conceptually different from GL_MATRIX_MODE */
 
-void gpuLoadIdentity(eGPUMatrixMode stack);
+typedef enum {
+	MATRIX_MODE_INACTIVE,
+	MATRIX_MODE_2D,
+	MATRIX_MODE_3D
+} MatrixMode;
 
-void gpuMultMatrix(eGPUMatrixMode stack, const float m[16]);
+MatrixMode gpuMatrixMode(void);
 
-void gpuTranslate(eGPUMatrixMode stack, float x, float y, float z);
-void gpuScale(eGPUMatrixMode stack, GLfloat x, GLfloat y, GLfloat z);
-void gpuRotateVector(eGPUMatrixMode stack, GLfloat deg, GLfloat vector[3]);
-void gpuRotateAxis(eGPUMatrixMode stack, GLfloat deg, char axis);
-void gpuRotateRight(eGPUMatrixMode stack, char type);
+void gpuMatrixBegin2D(void);
+void gpuMatrixBegin3D(void);
+void gpuMatrixEnd(void);
+/* TODO: gpuMatrixResume2D & gpuMatrixResume3D to switch modes but not reset stack */
 
-void gpuOrtho(eGPUMatrixMode stack, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
-void gpuFrustum(eGPUMatrixMode stack, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
 
-void gpuLoadOrtho(eGPUMatrixMode stack, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
-void gpuLoadFrustum(eGPUMatrixMode stack, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
+/* ModelView Matrix (2D or 3D) */
 
-void gpuLookAt(eGPUMatrixMode stack, GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat centerX, GLfloat centerY, GLfloat centerZ, GLfloat upX, GLfloat upY, GLfloat upZ);
+void gpuPushMatrix(void); /* TODO: PushCopy vs PushIdentity? */
+void gpuPopMatrix(void);
 
-void gpuProject(const GLfloat obj[3], const GLfloat model[16], const GLfloat proj[16], const GLint view[4], GLfloat win[3]);
-GLboolean gpuUnProject(const GLfloat win[3], const GLfloat model[16], const GLfloat proj[16], const GLint view[4], GLfloat obj[3]);
+void gpuLoadIdentity(void);
 
-void gpu_commit_matrix(void);
+void gpuScaleUniform(float factor);
 
-void GPU_feedback_vertex_3fv(GLenum type, GLfloat x, GLfloat y, GLfloat z,            GLfloat out[3]);
-void GPU_feedback_vertex_4fv(GLenum type, GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat out[4]);
 
-#if defined(GLEW_ES_ONLY)
+/* 3D ModelView Matrix */
 
-/* ES 2.0 doesn't define these symbolic constants, but the matrix stack replacement library emulates them
- * (GL core has deprecated matrix stacks, but it should still be in the header) */
+void gpuLoadMatrix3D(const float m[4][4]);
+void gpuMultMatrix3D(const float m[4][4]);
+//const float *gpuGetMatrix3D(float m[4][4]);
 
-#ifndef GL_MODELVIEW_MATRIX
-#define GL_MODELVIEW_MATRIX 0x0BA6
-#endif
+void gpuTranslate3f(float x, float y, float z);
+void gpuTranslate3fv(const float vec[3]);
+void gpuScale3f(float x, float y, float z);
+void gpuScale3fv(const float vec[3]);
+void gpuRotate3fv(float deg, const float axis[3]); /* axis of rotation should be a unit vector */
+void gpuRotateAxis(float deg, char axis); /* TODO: enum for axis? */
 
-#ifndef GL_PROJECTION_MATRIX
-#define GL_PROJECTION_MATRIX 0x0BA7
-#endif
+void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
+/* TODO: variant that takes eye[3], center[3], up[3] */
 
-#ifndef GL_TEXTURE_MATRIX
-#define GL_TEXTURE_MATRIX 0x0BA8
-#endif
 
-#endif
+/* 2D ModelView Matrix */
+
+void gpuLoadMatrix2D(const float m[3][3]);
+void gpuMultMatrix2D(const float m[3][3]);
+
+void gpuTranslate2f(float x, float y);
+void gpuTranslate2fv(const float vec[2]);
+void gpuScale2f(float x, float y);
+void gpuScale2fv(const float vec[2]);
+void gpuRotate2D(float deg);
+
+
+/* 3D Projection Matrix */
+
+void gpuOrtho(float left, float right, float bottom, float top, float near, float far);
+void gpuFrustum(float left, float right, float bottom, float top, float near, float far);
+void gpuPerspective(float fovy, float aspect, float near, float far);
+
+/* pass vector through current transform (world --> screen) */
+void gpuProject(const float obj[3], const float model[4][4], const float proj[4][4], const GLint view[4], float win[3]);
+
+/* pass vector through inverse transform (world <-- screen) */
+bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const GLint view[4], float obj[3]);
+
+
+/* 2D Projection Matrix */
+
+void gpuOrtho2D(float left, float right, float bottom, float top);
+
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index 9a938cc..3cc93b9 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -20,7 +20,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): Alexandr Kuznetsov, Jason Wilkins
+ * Contributor(s): Alexandr Kuznetsov, Jason Wilkins, Mike Erwin
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -29,50 +29,77 @@
  *  \ingroup gpu
  */
 
-#if WITH_GL_PROFILE_COMPAT
-#define GPU_MANGLE_DEPRECATED 0 /* Allow use of deprecated OpenGL functions in this file */
-#endif
-
-#include "BLI_sys_types.h"
-
-#include "GPU_common.h"
-#include "GPU_debug.h"
-#include "GPU_extensions.h"
 #include "GPU_matrix.h"
 
-/* internal */
-#include "intern/gpu_private.h"
-
-/* external */
-
 #include "BLI_math_matrix.h"
 #include "BLI_math_rotation.h"
 #include "BLI_math_vector.h"
 
-#include "MEM_guardedalloc.h"
 
+#define MATRIX_STACK_DEPTH 32
+
+typedef float Mat4[4][4];
+typedef float Mat3[3][3];
 
+typedef struct {
+	Mat4 ModelViewStack3D[MATRIX_STACK_DEPTH];
+	Mat4 ProjectionMatrix3D;
 
-typedef GLfloat GPU_matrix[4][4];
+	Mat3 ModelViewStack2D[MATRIX_STACK_DEPTH];
+	Mat3 ProjectionMatrix2D;
 
-typedef struct GPU_matrix_stack
+	MatrixMode mode;
+	unsigned top; /* of current stack (would have to replicate if gpuResume2D/3D are implemented) */
+	
+	/* TODO: cache of derived matrices (Normal, MVP, inverse MVP, etc)
+	 * generate as needed for shaders, invalidate when original matrices change
+	 *
+	 * TODO: separate Model from View transform? Batches/objects have model,
+	 * camera/eye has view & projection
+	 */
+} MatrixState;
+
+static MatrixState state; /* TODO(merwin): make part of GPUContext, alongside immediate mode & state tracker */
+
+#define ModelView3D state.ModelViewStack3D[state.top]
+#define ModelView2D state.ModelViewStack2D[state.top]
+#define Projection3D state.ProjectionMatrix3D
+#define Projection2D state.ProjectionMatrix2D
+
+void gpuMatrixInit()
 {
-	GLsizei size;
-	GLsizei pos;
-	GPU_matrix *dynstack;
-} GPU_matrix_stack;
+	memset(&state, 0, sizeof(MatrixState));
+}
 
+void gpuMatrixBegin2D()
+{
+	state.mode = MATRIX_MODE_2D;
+	state.top = 0;
+	unit_m3(ModelView2D);
+	gpuOrtho2D(-1.0f, +1.0f, -1.0f, +1.0f); // or identity?
+}
+
+void gpuMatrixBegin3D()
+{
+	state.mode = MATRIX_MODE_3D;
+	state.top = 0;
+	unit_m4(ModelView3D);
+	gpuOrtho(-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f); // or identity?
+}
+
+void gpuMatrixEnd()
+{
+	state.mode = MATRIX_MODE_INACTIVE;
+}
 
-static GPU_matrix_stack mstacks[3];
 
-/* Check if we have a good matrix */
 #ifdef WITH_GPU_SAFETY
 
-static void checkmat(GLfloat *m)
+/* Check if matrix is numerically good */
+static void checkmat(cosnt float *m)
 {
-	GLint i;
-
-	for (i = 0; i < 16; i++) {
+	const int n = state.mode == MATRIX_MODE_3D ? 16 : 9;
+	for (int i = 0; i < n; i++) {
 #if _MSC_VER
 		BLI_assert(_finite(m[i]));
 #else
@@ -81,7 +108,7 @@ static void checkmat(GLfloat *m)
 	}
 }
 
-#define CHECKMAT(m) checkmat((GLfloat*)m)
+#define CHECKMAT(m) checkmat((const float*)m)
 
 #else
 
@@ -89,254 +116,331 @@ static void checkmat(GLfloat *m)
 
 #endif
 
-static void ms_init(GPU_matrix_stack* ms, GLint initsize)
-{
-	BLI_assert(initsize > 0);
 
-	ms->size = initsize;
-	ms->pos = 0;
-	ms->dynstack = (GPU_matrix*)MEM_mallocN(ms->size * sizeof(*(ms->dynstack)), "MatrixStack");
+void gpuPushMatrix()
+{
+	BLI_assert(state.mode != MATRIX_MODE_INACTIVE);
+	BLI_assert(state.top < MATRIX_STACK_DEPTH);
+	state.top++;
+	if (state.mode == MATRIX_MODE_3D)
+		copy_m4_m4(ModelView3D, state.ModelViewStack3D[state.top - 1]);
+	else
+		copy_m3_m3(ModelView2D, state.ModelViewStack2D[state.top - 1]);
 }
 
-static void ms_free(GPU_matrix_stack *ms)
+void gpuPopMatrix()
 {
-	ms->size = 0;
-	ms->pos = 0;
-	MEM_freeN(ms->dynstack);
-	ms->dynstack = NULL;
+	BLI_assert(state.mode != MATRIX_MODE_INACTIVE);
+	BLI_assert(state.top > 0);
+	state.top--;
 }
 
-void gpu_matrix_init(void)
+void gpuLoadMatrix3D(const float m[4][4])
 {
-	ms_init(&mstacks[GPU_TEXTURE_MATRIX], 16);
-	ms_init(&mstacks[GPU_PROJECTION_MATRIX], 16);
-	ms_init(&mstacks[GPU_MODELVIEW_MATRIX], 32);
+	BLI_assert(state.mode == MATRIX_MODE_3D);
+	copy_m4_m4(ModelView3D, m);
+	CHECKMAT(ModelView3D);
 }
 


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list