[Bf-blender-cvs] [dfadb45254] blender2.8: OpenGL immediate mode: gluSphere replacement

Clément Foucault noreply at git.blender.org
Sat Feb 11 00:47:21 CET 2017


Commit: dfadb452549398bee5292ba6677aafe071f010b1
Author: Clément Foucault
Date:   Wed Feb 8 00:38:07 2017 +0100
Branches: blender2.8
https://developer.blender.org/rBdfadb452549398bee5292ba6677aafe071f010b1

OpenGL immediate mode: gluSphere replacement

Updated interface_draw.c to use the new sphere batch.

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

M	source/blender/editors/interface/interface_draw.c
M	source/blender/gpu/GPU_batch.h
M	source/blender/gpu/intern/gpu_batch.c
M	source/blender/gpu/intern/gpu_init_exit.c

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

diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 1cd1921d12..47497947dc 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1282,63 +1282,6 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
 	immUnbindProgram();
 }
 
-#define SPHERE_LAT_RES 24
-#define SPHERE_LON_RES 32
-
-static float sphere_coords[SPHERE_LON_RES][SPHERE_LAT_RES][3] = {{{2.0f}}};
-
-static void ui_draw_lat_lon_vert(unsigned int pos, unsigned int nor, float radius, int lat, int lon)
-{
-	const float x = sphere_coords[lon][lat][0];
-	const float y = sphere_coords[lon][lat][1];
-	const float z = sphere_coords[lon][lat][2];
-
-	immAttrib3f(nor, x, y, z);
-	immVertex3f(pos, x * radius, y * radius, z * radius);
-}
-
-static void ui_draw_unitvec_sphere(unsigned int pos, unsigned int nor, float radius)
-{
-	const float lon_inc = 2 * M_PI / SPHERE_LON_RES;
-	const float lat_inc = M_PI / SPHERE_LAT_RES;
-	float lon, lat;
-
-	/* TODO put that in a batch */
-
-	/* Init coords only once */
-	if (sphere_coords[0][0][0] == 2.0f) {
-		lon = 0.0f;
-		for(int i = 0; i < SPHERE_LON_RES; i++, lon += lon_inc) {
-			lat = 0.0f;
-			for(int j = 0; j < SPHERE_LAT_RES; j++, lat += lat_inc) {
-				sphere_coords[i][j][0] = sinf(lat) * cosf(lon);
-				sphere_coords[i][j][1] = cosf(lat);
-				sphere_coords[i][j][2] = sinf(lat) * sinf(lon);
-			}
-		}
-	}
-
-	immBegin(GL_TRIANGLES, (SPHERE_LAT_RES-1) * SPHERE_LON_RES * 6);
-	for(int i = 0; i < SPHERE_LON_RES; i++) {
-		for(int j = 0; j < SPHERE_LAT_RES; j++) {
-			if (j != SPHERE_LAT_RES - 1) { /* Pole */
-				ui_draw_lat_lon_vert(pos, nor, radius, j,   i);
-				ui_draw_lat_lon_vert(pos, nor, radius, j+1, i);
-				ui_draw_lat_lon_vert(pos, nor, radius, j+1, i+1);
-			}
-
-			if (j != 0) { /* Pole */
-				ui_draw_lat_lon_vert(pos, nor, radius, j,   i);
-				ui_draw_lat_lon_vert(pos, nor, radius, j+1, i+1);
-				ui_draw_lat_lon_vert(pos, nor, radius, j,   i+1);
-			}
-		}
-	}
-	immEnd();
-}
-#undef SPHERE_LAT_RES
-#undef SPHERE_LON_RES
-
 void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
 {
 	/* sphere color */
@@ -1357,40 +1300,36 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
 	ui_but_v3_get(but, light);
 	light[2] = -light[2];
 
-	VertexFormat *format = immVertexFormat();
-	unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
-	unsigned int nor = add_attrib(format, "nor", GL_FLOAT, 3, KEEP_FLOAT);
-	immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING);
-	immUniformColor3fv(diffuse);
-	immUniform3fv("light", light);
-
 	/* transform to button */
 	gpuMatrixBegin3D_legacy();
 	gpuPushMatrix();
 	
 	if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect))
-		size = BLI_rcti_size_x(rect) / 200.f;
+		size = BLI_rcti_size_x(rect) / 2.f;
 	else
-		size = BLI_rcti_size_y(rect) / 200.f;
+		size = BLI_rcti_size_y(rect) / 2.f;
 
 	gpuTranslate3f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect), 0.0f);
-	gpuScale3f(size, size, MIN2(size, 1.0f));
+	gpuScale3f(size, size, size);
 
-	ui_draw_unitvec_sphere(pos, nor, 100.0);
-	immUnbindProgram();
+	Batch *sphere = Batch_get_sphere(2);
+	Batch_set_builtin_program(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+	Batch_Uniform4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.f);
+	Batch_Uniform3fv(sphere, "light", light);
+	Batch_draw(sphere);
 
 	/* restore */
 	glDisable(GL_CULL_FACE);
 	
 	/* AA circle */
-	format = immVertexFormat();
-	pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
+	VertexFormat *format = immVertexFormat();
+	unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
 	immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 	immUniformColor3ubv((unsigned char *)wcol->inner);
 
 	glEnable(GL_BLEND);
 	glEnable(GL_LINE_SMOOTH);
-	imm_draw_lined_circle(pos, 0.0f, 0.0f, 100.0f, 32);
+	imm_draw_lined_circle(pos, 0.0f, 0.0f, 1.0f, 32);
 	glDisable(GL_BLEND);
 	glDisable(GL_LINE_SMOOTH);
 
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index bc3017e278..066bc9eeba 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -35,3 +35,9 @@
 
 /* Extend Batch_set_program to use Blender’s library of built-in shader programs. */
 void Batch_set_builtin_program(Batch*, GPUBuiltinShader);
+
+/* Replacement for gluSphere */
+Batch *Batch_get_sphere(int lod);
+
+void gpu_batch_init(void);
+void gpu_batch_exit(void);
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 23f9f68f1a..716c5e55b3 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -25,6 +25,9 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
 #include "GPU_batch.h"
 #include "gpu_shader_private.h"
 
@@ -33,3 +36,87 @@ void Batch_set_builtin_program(Batch* batch, GPUBuiltinShader shader_id)
 	GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
 	Batch_set_program(batch, shader->program);
 }
+
+static Batch *sphere_high = NULL;
+static Batch *sphere_med = NULL;
+static Batch *sphere_low = NULL;
+
+static VertexBuffer *vbo;
+static VertexFormat format = {0};
+static unsigned int pos_id, nor_id;
+static unsigned int vert;
+
+static void batch_sphere_lat_lon_vert(float lat, float lon)
+{
+	float pos[3];
+	pos[0] = sinf(lat) * cosf(lon);
+	pos[1] = cosf(lat);
+	pos[2] = sinf(lat) * sinf(lon);
+
+	setAttrib(vbo, nor_id, vert, pos);
+	setAttrib(vbo, pos_id, vert++, pos);
+}
+
+/* Replacement for gluSphere */
+static Batch *batch_sphere(int lat_res, int lon_res)
+{
+	const float lon_inc = 2 * M_PI / lon_res;
+	const float lat_inc = M_PI / lat_res;
+	float lon, lat;
+
+	if (format.attrib_ct == 0) {
+		pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+		nor_id = add_attrib(&format, "nor", GL_FLOAT, 3, KEEP_FLOAT);
+	}
+
+	vbo = VertexBuffer_create_with_format(&format);
+	VertexBuffer_allocate_data(vbo, (lat_res-1) * lon_res * 6);
+	vert = 0;
+
+	lon = 0.0f;
+	for(int i = 0; i < lon_res; i++, lon += lon_inc) {
+		lat = 0.0f;
+		for(int j = 0; j < lat_res; j++, lat += lat_inc) {
+			if (j != lat_res - 1) { /* Pole */
+				batch_sphere_lat_lon_vert(lat,         lon);
+				batch_sphere_lat_lon_vert(lat+lat_inc, lon);
+				batch_sphere_lat_lon_vert(lat+lat_inc, lon+lon_inc);
+			}
+
+			if (j != 0) { /* Pole */
+				batch_sphere_lat_lon_vert(lat,         lon);
+				batch_sphere_lat_lon_vert(lat+lat_inc, lon+lon_inc);
+				batch_sphere_lat_lon_vert(lat,         lon+lon_inc);
+			}
+		}
+	}
+
+	return Batch_create(GL_TRIANGLES, vbo, NULL);
+}
+
+Batch *Batch_get_sphere(int lod)
+{
+	BLI_assert(lod >= 0 && lod <= 2);
+
+	if (lod == 0)
+		return sphere_low;
+	else if (lod == 1)
+		return sphere_med;
+	else
+		return sphere_high;
+}
+
+void gpu_batch_init(void)
+{
+	/* Hard coded resolution */
+	sphere_low = batch_sphere(8, 8);
+	sphere_med = batch_sphere(16, 10);
+	sphere_high = batch_sphere(32, 24);
+}
+
+void gpu_batch_exit(void)
+{
+	Batch_discard_all(sphere_low);
+	Batch_discard_all(sphere_med);
+	Batch_discard_all(sphere_high);
+}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 817756a308..7a6b1ff6c7 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -32,6 +32,7 @@
 #include "BLI_sys_types.h"
 #include "GPU_init_exit.h"  /* interface */
 #include "GPU_immediate.h"
+#include "GPU_batch.h"
 #include "BKE_global.h"
 
 #include "intern/gpu_codegen.h"
@@ -59,6 +60,8 @@ void GPU_init(void)
 	if (G.debug & G_DEBUG_GPU)
 		gpu_debug_init();
 
+	gpu_batch_init();
+
 	immInit();
 }
 
@@ -68,6 +71,8 @@ void GPU_exit(void)
 {
 	immDestroy();
 
+	gpu_batch_exit();
+
 	if (G.debug & G_DEBUG_GPU)
 		gpu_debug_exit();




More information about the Bf-blender-cvs mailing list