Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_batch.c')
-rw-r--r--source/blender/gpu/intern/gpu_batch.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
new file mode 100644
index 00000000000..5d347fc80e8
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -0,0 +1,171 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "GPU_batch.h"
+#include "gpu_shader_private.h"
+
+void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id)
+{
+ GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
+ GWN_batch_program_set(batch, shader->program, shader->interface);
+}
+
+static Gwn_Batch *sphere_high = NULL;
+static Gwn_Batch *sphere_med = NULL;
+static Gwn_Batch *sphere_low = NULL;
+static Gwn_Batch *sphere_wire_low = NULL;
+static Gwn_Batch *sphere_wire_med = NULL;
+
+static Gwn_VertBuf *vbo;
+static Gwn_VertFormat 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);
+
+ GWN_vertbuf_attr_set(vbo, nor_id, vert, pos);
+ GWN_vertbuf_attr_set(vbo, pos_id, vert++, pos);
+}
+
+/* Replacement for gluSphere */
+static Gwn_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 = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(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 + lat_inc, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon);
+ batch_sphere_lat_lon_vert(lat, lon);
+ }
+
+ if (j != 0) { /* Pole */
+ batch_sphere_lat_lon_vert(lat, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat, lon);
+ }
+ }
+ }
+
+ return GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
+}
+
+static Gwn_Batch *batch_sphere_wire(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 = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, (lat_res * lon_res * 2) + ((lat_res - 1) * lon_res * 2));
+ 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) {
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon);
+ batch_sphere_lat_lon_vert(lat, lon);
+
+ if (j != lat_res - 1) { /* Pole */
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon + lon_inc);
+ batch_sphere_lat_lon_vert(lat + lat_inc, lon);
+ }
+ }
+ }
+
+ return GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
+}
+
+Gwn_Batch *GPU_batch_preset_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;
+}
+
+Gwn_Batch *GPU_batch_preset_sphere_wire(int lod)
+{
+ BLI_assert(lod >= 0 && lod <= 1);
+
+ if (lod == 0)
+ return sphere_wire_low;
+ else
+ return sphere_wire_med;
+}
+
+void gpu_batch_init(void)
+{
+ /* Hard coded resolution */
+ sphere_low = batch_sphere(8, 16);
+ sphere_med = batch_sphere(16, 10);
+ sphere_high = batch_sphere(32, 24);
+
+ sphere_wire_low = batch_sphere_wire(6, 8);
+ sphere_wire_med = batch_sphere_wire(8, 16);
+}
+
+void gpu_batch_exit(void)
+{
+ GWN_batch_discard(sphere_low);
+ GWN_batch_discard(sphere_med);
+ GWN_batch_discard(sphere_high);
+ GWN_batch_discard(sphere_wire_low);
+ GWN_batch_discard(sphere_wire_med);
+}