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')
-rw-r--r--source/blender/gpu/CMakeLists.txt56
-rw-r--r--source/blender/gpu/GPU_basic_shader.h3
-rw-r--r--source/blender/gpu/GPU_batch.h7
-rw-r--r--source/blender/gpu/GPU_buffers.h6
-rw-r--r--source/blender/gpu/GPU_debug.h3
-rw-r--r--source/blender/gpu/GPU_draw.h4
-rw-r--r--source/blender/gpu/GPU_framebuffer.h4
-rw-r--r--source/blender/gpu/GPU_immediate.h9
-rw-r--r--source/blender/gpu/GPU_lamp.h75
-rw-r--r--source/blender/gpu/GPU_material.h24
-rw-r--r--source/blender/gpu/GPU_matrix.h71
-rw-r--r--source/blender/gpu/GPU_select.h15
-rw-r--r--source/blender/gpu/GPU_shader.h31
-rw-r--r--source/blender/gpu/GPU_texture.h8
-rw-r--r--source/blender/gpu/GPU_viewport.h38
-rw-r--r--source/blender/gpu/gawain/attrib_binding.c69
-rw-r--r--source/blender/gpu/gawain/attrib_binding.h24
-rw-r--r--source/blender/gpu/gawain/batch.c340
-rw-r--r--source/blender/gpu/gawain/batch.h104
-rw-r--r--source/blender/gpu/gawain/buffer_id.cpp115
-rw-r--r--source/blender/gpu/gawain/buffer_id.h34
-rw-r--r--source/blender/gpu/gawain/common.h58
-rw-r--r--source/blender/gpu/gawain/element.c283
-rw-r--r--source/blender/gpu/gawain/element.h64
-rw-r--r--source/blender/gpu/gawain/imm_util.c46
-rw-r--r--source/blender/gpu/gawain/imm_util.h18
-rw-r--r--source/blender/gpu/gawain/immediate.c868
-rw-r--r--source/blender/gpu/gawain/immediate.h110
-rw-r--r--source/blender/gpu/gawain/vertex_buffer.c170
-rw-r--r--source/blender/gpu/gawain/vertex_buffer.h64
-rw-r--r--source/blender/gpu/gawain/vertex_format.c246
-rw-r--r--source/blender/gpu/gawain/vertex_format.h87
-rw-r--r--source/blender/gpu/intern/gpu_basic_shader.c160
-rw-r--r--source/blender/gpu/intern/gpu_batch.c71
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c97
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c6
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c176
-rw-r--r--source/blender/gpu/intern/gpu_debug.c440
-rw-r--r--source/blender/gpu/intern/gpu_draw.c68
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c151
-rw-r--r--source/blender/gpu/intern/gpu_lamp.c475
-rw-r--r--source/blender/gpu/intern/gpu_lamp_private.h86
-rw-r--r--source/blender/gpu/intern/gpu_material.c443
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c301
-rw-r--r--source/blender/gpu/intern/gpu_select.c277
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c740
-rw-r--r--source/blender/gpu/intern/gpu_select_private.h53
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c209
-rw-r--r--source/blender/gpu/intern/gpu_shader.c115
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.h7
-rw-r--r--source/blender/gpu/intern/gpu_texture.c61
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c210
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl1
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl25
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl22
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_smooth_vert.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_smooth_vert.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_smooth_vert.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_smooth_vert.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_smooth_vert.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_basic_frag.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_basic_vert.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl24
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fire_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl50
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl68
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl56
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl65
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_lib.glsl7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl20
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_vert.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_geometry.glsl7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl22
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl50
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl25
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl57
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl64
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl29
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl29
-rw-r--r--source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl51
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_point_uniform_color_smooth_frag.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_smooth_frag.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_smooth_frag.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl25
-rw-r--r--source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl17
-rw-r--r--source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl20
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex_world.glsl10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl11
99 files changed, 3542 insertions, 4553 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 7573985baa8..f0ef87c5f28 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -42,6 +42,7 @@ set(INC
../../../intern/glew-mx
../../../intern/guardedalloc
../../../intern/smoke/extern
+ ../../../intern/gawain
)
set(INC_SYS
@@ -60,32 +61,17 @@ set(SRC
intern/gpu_framebuffer.c
intern/gpu_immediate.c
intern/gpu_init_exit.c
+ intern/gpu_lamp.c
intern/gpu_material.c
intern/gpu_matrix.c
intern/gpu_select.c
+ intern/gpu_select_pick.c
+ intern/gpu_select_sample_query.c
intern/gpu_shader.c
intern/gpu_texture.c
intern/gpu_uniformbuffer.c
intern/gpu_viewport.c
- gawain/attrib_binding.c
- gawain/attrib_binding.h
- gawain/batch.c
- gawain/batch.h
- gawain/buffer_id.h
- gawain/buffer_id.cpp
- gawain/common.h
- gawain/element.c
- gawain/element.h
- gawain/immediate.c
- gawain/immediate.h
- gawain/imm_util.c
- gawain/imm_util.h
- gawain/vertex_buffer.c
- gawain/vertex_buffer.h
- gawain/vertex_format.c
- gawain/vertex_format.h
-
shaders/gpu_shader_fx_lib.glsl
shaders/gpu_shader_fx_ssao_frag.glsl
shaders/gpu_shader_fx_dof_frag.glsl
@@ -93,7 +79,7 @@ set(SRC
shaders/gpu_shader_fx_dof_hq_frag.glsl
shaders/gpu_shader_fx_dof_hq_vert.glsl
shaders/gpu_shader_fx_dof_hq_geo.glsl
- shaders/gpu_shader_fx_vert.glsl
+ shaders/gpu_shader_fullscreen_vert.glsl
shaders/gpu_shader_material.glsl
shaders/gpu_shader_sep_gaussian_blur_frag.glsl
shaders/gpu_shader_sep_gaussian_blur_vert.glsl
@@ -129,19 +115,27 @@ set(SRC
intern/gpu_codegen.h
intern/gpu_private.h
+ intern/gpu_lamp_private.h
+ intern/gpu_select_private.h
+ intern/gpu_shader_private.h
)
data_to_c_simple(shaders/gpu_shader_depth_only_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_uniform_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_checker_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_diag_stripes_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_lighting_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_flat_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_line_dashed_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_line_dashed_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC)
@@ -158,25 +152,31 @@ data_to_c_simple(shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_camera_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_distance_line_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_point_uniform_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_point_uniform_color_smooth_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_point_uniform_color_outline_smooth_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_point_varying_color_outline_smooth_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_uniform_color_aa_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_point_varying_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_point_varying_size_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_3D_point_uniform_size_smooth_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_3D_point_uniform_size_outline_smooth_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_smooth_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_outline_smooth_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_smooth_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_geom.glsl SRC)
@@ -205,7 +205,7 @@ data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_fx_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fullscreen_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_ssao_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_basic_shader.h b/source/blender/gpu/GPU_basic_shader.h
index bfdf4ab6bbd..dc378927e79 100644
--- a/source/blender/gpu/GPU_basic_shader.h
+++ b/source/blender/gpu/GPU_basic_shader.h
@@ -126,9 +126,6 @@ void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id);
void GPU_basic_shader_line_stipple(GLint stipple_factor, GLushort stipple_pattern);
void GPU_basic_shader_line_width(float line_width);
-bool GPU_basic_shader_use_glsl_get(void);
-void GPU_basic_shader_use_glsl_set(bool enabled);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 066bc9eeba7..2232e333bb6 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -30,7 +30,11 @@
#pragma once
-#include "gawain/batch.h"
+#include "../../../intern/gawain/gawain/batch.h"
+
+// TODO: CMake magic to do this:
+// #include "gawain/batch.h"
+
#include "GPU_shader.h"
/* Extend Batch_set_program to use Blender’s library of built-in shader programs. */
@@ -38,6 +42,7 @@ void Batch_set_builtin_program(Batch*, GPUBuiltinShader);
/* Replacement for gluSphere */
Batch *Batch_get_sphere(int lod);
+Batch *Batch_get_sphere_wire(int lod);
void gpu_batch_init(void);
void gpu_batch_exit(void);
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index b693d473bd8..958d5aed4a4 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -258,10 +258,8 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, struct CCGElem **gr
void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
bool wireframe, bool fast);
-/* debug PBVH draw*/
-void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf);
-void GPU_end_draw_pbvh_BB(void);
-void GPU_init_draw_pbvh_BB(void);
+/* debug PBVH draw */
+void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf, unsigned int pos);
bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, struct GSet *bm_faces, bool show_diffuse_color);
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
index 921deaaa6d6..c7a99d33654 100644
--- a/source/blender/gpu/GPU_debug.h
+++ b/source/blender/gpu/GPU_debug.h
@@ -41,9 +41,6 @@ extern "C" {
/* prints something if debug mode is active only */
void GPU_print_error_debug(const char *str);
-/* prints current OpenGL state */
-void GPU_state_print(void);
-
/* inserts a debug marker message for the debug context messaging system */
void GPU_string_marker(const char *str);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 91d436557f0..47ddabbed19 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -42,6 +42,7 @@ struct ImageUser;
struct MTexPoly;
struct Object;
struct Scene;
+struct SceneLayer;
struct View3D;
struct RegionView3D;
struct SmokeModifierData;
@@ -74,7 +75,8 @@ void GPU_disable_program_point_size(void);
* - after drawing, the material must be disabled again */
void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
- struct Scene *scene, struct Object *ob, bool glsl, bool *do_alpha_after);
+ struct Scene *scene, struct SceneLayer *sl,
+ struct Object *ob, bool glsl, bool *do_alpha_after);
void GPU_end_object_materials(void);
bool GPU_object_materials_check(void);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 9611a6f0577..15617832c9b 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -67,6 +67,10 @@ void GPU_framebuffer_blur(
GPUFrameBuffer *fb, struct GPUTexture *tex,
GPUFrameBuffer *blurfb, struct GPUTexture *blurtex);
+void GPU_framebuffer_blit(
+ GPUFrameBuffer *fb_read, int read_slot,
+ GPUFrameBuffer *fb_write, int write_slot, bool use_depth);
+
/* GPU OffScreen
* - wrapper around framebuffer and texture for simple offscreen drawing
* - changes size if graphics card can't support it */
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index 4a0840e22c0..35964a81030 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -30,8 +30,13 @@
#pragma once
-#include "gawain/immediate.h"
-#include "gawain/imm_util.h"
+#include "../../../intern/gawain/gawain/immediate.h"
+#include "../../../intern/gawain/gawain/imm_util.h"
+
+// TODO: CMake magic to do this:
+// #include "gawain/immediate.h"
+// #include "gawain/imm_util.h"
+
#include "GPU_shader.h"
/* Extend immBindProgram to use Blender’s library of built-in shader programs.
diff --git a/source/blender/gpu/GPU_lamp.h b/source/blender/gpu/GPU_lamp.h
new file mode 100644
index 00000000000..32793830479
--- /dev/null
+++ b/source/blender/gpu/GPU_lamp.h
@@ -0,0 +1,75 @@
+/*
+ * ***** 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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_lamp.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_LAMP_H__
+#define __GPU_LAMP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Scene;
+struct Object;
+struct RenderEngineType;
+
+typedef struct GPULamp GPULamp;
+
+typedef struct LampEngineData {
+ struct GPUFrameBuffer *framebuffers[4];
+ struct GPUTexture *textures[4];
+ void *storage[4];
+} LampEngineData;
+
+GPULamp *GPU_lamp_from_engine(struct Scene *scene, struct Object *ob, Object *par, struct RenderEngineType *re);
+GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
+void GPU_lamp_free(struct Object *ob);
+
+bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
+bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
+void GPU_lamp_update_buffer_mats(GPULamp *lamp);
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
+void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
+int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
+int GPU_lamp_shadow_bind_code(GPULamp *lamp);
+float *GPU_lamp_dynpersmat(GPULamp *lamp);
+
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
+void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
+void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
+ float coeff_const, float coeff_lin, float coeff_quad);
+void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
+int GPU_lamp_shadow_layer(GPULamp *lamp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GPU_LAMP_H__ */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 0d92d22a173..cbcd6383a72 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -45,7 +45,6 @@ struct Image;
struct ImageUser;
struct Material;
struct Object;
-struct Image;
struct Scene;
struct SceneRenderLayer;
struct GPUVertexAttribs;
@@ -61,7 +60,7 @@ struct World;
typedef struct GPUNode GPUNode;
typedef struct GPUNodeLink GPUNodeLink;
typedef struct GPUMaterial GPUMaterial;
-typedef struct GPULamp GPULamp;
+
typedef struct GPUParticleInfo GPUParticleInfo;
/* Functions to create GPU Materials nodes */
@@ -224,7 +223,6 @@ void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
-bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
void GPU_material_bind(
GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
@@ -310,26 +308,8 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma);
void GPU_free_shader_export(GPUShaderExport *shader);
/* Lamps */
-
-GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
-void GPU_lamp_free(struct Object *ob);
-
-bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
-void GPU_lamp_update_buffer_mats(GPULamp *lamp);
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
-void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
-int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
-int GPU_lamp_shadow_bind_code(GPULamp *lamp);
-float *GPU_lamp_dynpersmat(GPULamp *lamp);
-
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
-void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
-void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
- float coeff_const, float coeff_lin, float coeff_quad);
-void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
-int GPU_lamp_shadow_layer(GPULamp *lamp);
GPUNodeLink *GPU_lamp_get_data(
- GPUMaterial *mat, GPULamp *lamp,
+ GPUMaterial *mat, struct GPULamp *lamp,
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy);
/* World */
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 43a03f8e4b6..85b1b5c7acf 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -1,6 +1,3 @@
-#ifndef _GPU_MATRIX_H_
-#define _GPU_MATRIX_H_
-
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -32,8 +29,11 @@
* \ingroup gpu
*/
+#ifndef _GPU_MATRIX_H_
+#define _GPU_MATRIX_H_
+
+#include "BLI_sys_types.h"
#include "GPU_glew.h"
-#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@@ -84,6 +84,7 @@ 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 gpuRotate3f(float deg, float x, float y, float z); /* axis of rotation should be a unit vector */
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? */
@@ -105,16 +106,16 @@ void gpuRotate2D(float deg);
/* 3D Projection Matrix */
+void gpuLoadProjectionMatrix3D(const float m[4][4]);
+
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]);
+/* 3D Projection between Window and World Space */
+void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]);
+bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]);
/* 2D Projection Matrix */
@@ -130,15 +131,6 @@ const float *gpuGetNormalMatrix(float m[3][3]);
const float *gpuGetNormalMatrixInverse(float m[3][3]);
-#if SUPPORT_LEGACY_MATRIX
-/* copy top matrix from each legacy stack into new fresh stack */
-void gpuMatrixBegin3D_legacy(void);
-
-/* call after using glScale, glTranslate, etc. between draw calls */
-void gpuMatrixUpdate_legacy(void);
-#endif
-
-
/* set uniform values for currently bound shader */
void gpuBindMatrices(GLuint program);
bool gpuMatricesDirty(void); /* since last bind */
@@ -147,4 +139,47 @@ bool gpuMatricesDirty(void); /* since last bind */
}
#endif
+
+#ifndef SUPPRESS_GENERIC_MATRIX_API
+/* make matrix inputs generic, to avoid warnings */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+# define gpuMultMatrix3D(x) \
+ gpuMultMatrix3D(_Generic((x), \
+ float *: (const float (*)[4])(x), \
+ float [16]: (const float (*)[4])(x), \
+ float (*)[4]: (const float (*)[4])(x), \
+ float [4][4]: (const float (*)[4])(x), \
+ const float *: (const float (*)[4])(x), \
+ const float [16]: (const float (*)[4])(x), \
+ const float (*)[4]: (const float (*)[4])(x), \
+ const float [4][4]: (const float (*)[4])(x)) \
+)
+# define gpuLoadMatrix3D(x) \
+ gpuLoadMatrix3D(_Generic((x), \
+ float *: (const float (*)[4])(x), \
+ float [16]: (const float (*)[4])(x), \
+ float (*)[4]: (const float (*)[4])(x), \
+ float [4][4]: (const float (*)[4])(x), \
+ const float *: (const float (*)[4])(x), \
+ const float [16]: (const float (*)[4])(x), \
+ const float (*)[4]: (const float (*)[4])(x), \
+ const float [4][4]: (const float (*)[4])(x)) \
+)
+/* TODO: finish this in a simpler way --^ */
+#else
+# define gpuMultMatrix3D(x) gpuMultMatrix3D((const float (*)[4])(x))
+# define gpuLoadMatrix3D(x) gpuLoadMatrix3D((const float (*)[4])(x))
+
+# define gpuLoadProjectionMatrix3D(x) gpuLoadProjectionMatrix3D((const float (*)[4])(x))
+
+# define gpuMultMatrix2D(x) gpuMultMatrix2D((const float (*)[3])(x))
+# define gpuLoadMatrix2D(x) gpuLoadMatrix2D((const float (*)[3])(x))
+
+# define gpuGetModelViewMatrix3D(x) gpuGetModelViewMatrix3D((float (*)[4])(x))
+# define gpuGetProjectionMatrix3D(x) gpuGetProjectionMatrix3D((float (*)[4])(x))
+# define gpuGetModelViewProjectionMatrix3D(x) gpuGetModelViewProjectionMatrix3D((float (*)[4])(x))
+# define gpuGetNormalMatrix(x) gpuGetNormalMatrix((float (*)[3])(x))
+# define gpuGetNormalMatrixInverse(x) gpuGetNormalMatrixInverse((float (*)[3])(x))
+#endif /* C11 */
+#endif /* SUPPRESS_GENERIC_MATRIX_API */
#endif /* GPU_MATRIX_H */
diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h
index 6a16b5b7456..cf5b8bf7d8f 100644
--- a/source/blender/gpu/GPU_select.h
+++ b/source/blender/gpu/GPU_select.h
@@ -30,19 +30,30 @@
#ifndef __GPU_SELECT_H__
#define __GPU_SELECT_H__
-#include "DNA_vec_types.h" /* rcft */
#include "BLI_sys_types.h"
+struct rcti;
+
/* flags for mode of operation */
enum {
GPU_SELECT_ALL = 1,
+ /* gpu_select_query */
GPU_SELECT_NEAREST_FIRST_PASS = 2,
GPU_SELECT_NEAREST_SECOND_PASS = 3,
+ /* gpu_select_pick */
+ GPU_SELECT_PICK_ALL = 4,
+ GPU_SELECT_PICK_NEAREST = 5,
};
-void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, char mode, int oldhits);
+void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const struct rcti *input, char mode, int oldhits);
bool GPU_select_load_id(unsigned int id);
unsigned int GPU_select_end(void);
bool GPU_select_query_check_active(void);
+/* cache selection region */
+bool GPU_select_is_cached(void);
+void GPU_select_cache_begin(void);
+void GPU_select_cache_load_id(void);
+void GPU_select_cache_end(void);
+
#endif
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index fcf070890ea..71a1e3a6591 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -71,8 +71,12 @@ void GPU_shader_bind(GPUShader *shader);
void GPU_shader_unbind(void);
int GPU_shader_get_program(GPUShader *shader);
+
void *GPU_shader_get_interface(GPUShader *shader);
-void GPU_shader_set_interface(GPUShader *shader, void *interface);
+
+void *GPU_fx_shader_get_interface(GPUShader *shader);
+void GPU_fx_shader_set_interface(GPUShader *shader, void *interface);
+
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name);
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length,
@@ -103,12 +107,14 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_EDGES_OVERLAY,
GPU_SHADER_KEYFRAME_DIAMOND,
GPU_SHADER_SIMPLE_LIGHTING,
+ GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR,
/* for simple 2D drawing */
GPU_SHADER_2D_UNIFORM_COLOR,
GPU_SHADER_2D_FLAT_COLOR,
GPU_SHADER_2D_SMOOTH_COLOR,
GPU_SHADER_2D_IMAGE_COLOR,
GPU_SHADER_2D_CHECKER,
+ GPU_SHADER_2D_DIAG_STRIPES,
/* for simple 3D drawing */
GPU_SHADER_3D_UNIFORM_COLOR,
GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE,
@@ -117,6 +123,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_3D_DEPTH_ONLY,
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
/* basic image drawing */
+ GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
GPU_SHADER_3D_IMAGE_MODULATE_ALPHA,
GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA,
@@ -125,23 +132,35 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_IMAGE_INTERLACE,
/* points */
GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR,
- GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH,
- GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH,
- GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_SMOOTH,
+ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
+ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
+ GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA,
GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR,
GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR,
GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR,
- GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH,
- GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH,
+ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
+ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
GPU_SHADER_3D_POINT_VARYING_SIZE_UNIFORM_COLOR,
GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR,
+ /* lines */
+ GPU_SHADER_2D_LINE_DASHED_COLOR,
/* lamp drawing */
GPU_SHADER_3D_GROUNDPOINT,
GPU_SHADER_3D_GROUNDLINE,
GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR,
+ /* bone drawing */
+ GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR,
+ GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR,
+ /* camera drawing */
+ GPU_SHADER_CAMERA,
+ /* distance in front of objects */
+ GPU_SHADER_DISTANCE_LINES,
+ /* axis name */
+ GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS,
/* instance */
GPU_SHADER_INSTANCE_UNIFORM_COLOR,
GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE,
+ GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR,
GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
} GPUBuiltinShader;
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index a8df80cd626..93cc8443643 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -66,6 +66,7 @@ typedef enum GPUTextureFormat {
GPU_RGBA8,
GPU_RG32F,
GPU_RG16F,
+ GPU_R16F,
GPU_R8,
#if 0
GPU_RGBA32F,
@@ -87,7 +88,6 @@ typedef enum GPUTextureFormat {
GPU_R32F,
GPU_R32I,
GPU_R32UI,
- GPU_R16F,
GPU_R16I,
GPU_R16UI,
GPU_R16,
@@ -101,8 +101,8 @@ typedef enum GPUTextureFormat {
GPU_RGB10_A2,
GPU_RGB10_A2UI,
GPU_DEPTH32F_STENCIL8,
- GPU_DEPTH24_STENCIL8,
#endif
+ GPU_DEPTH24_STENCIL8,
/* Texture only format */
#if 0
@@ -155,6 +155,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int d, const float *pixels, char
GPUTexture *GPU_texture_create_3D_custom(
int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
+GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256]);
GPUTexture *GPU_texture_from_blender(
@@ -183,7 +184,8 @@ void GPU_texture_framebuffer_set(GPUTexture *tex, struct GPUFrameBuffer *fb, int
int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
-int GPU_texture_depth(const GPUTexture *tex);
+bool GPU_texture_depth(const GPUTexture *tex);
+bool GPU_texture_stencil(const GPUTexture *tex);
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
#ifdef __cplusplus
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 9de16f64ca1..2411fe755af 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -44,7 +44,7 @@ typedef struct GPUViewport GPUViewport;
#define MAX_BUFFERS 8
#define MAX_TEXTURES 16
#define MAX_PASSES 16
-#define MAX_STORAGE 2 /* extend if needed */
+#define MAX_STORAGE 5 /* extend if needed */
/* All FramebufferLists are just the same pointers with different names */
typedef struct FramebufferList {
@@ -56,34 +56,40 @@ typedef struct TextureList {
} TextureList;
typedef struct PassList {
- struct DRWPass *passes[MAX_TEXTURES];
+ struct DRWPass *passes[MAX_PASSES];
} PassList;
typedef struct StorageList {
void *storage[MAX_STORAGE]; /* custom structs from the engine */
} StorageList;
-/* Buffer and textures used by the viewport by default */
-typedef struct DefaultFramebufferList {
- struct GPUFrameBuffer *default_fb;
-} DefaultFramebufferList;
+typedef struct ViewportEngineData {
+ void *engine_type;
-typedef struct DefaultTextureList {
- struct GPUTexture *color;
- struct GPUTexture *depth;
-} DefaultTextureList;
+ FramebufferList *fbl;
+ TextureList *txl;
+ PassList *psl;
+ StorageList *stl;
-typedef struct DefaultPassList {
- struct DRWPass *non_meshes_pass;
- struct DRWPass *ob_center_pass;
-} DefaultPassList;
+ /* Profiling data */
+ double init_time;
+ double cache_time;
+ double render_time;
+ double background_time;
+} ViewportEngineData;
GPUViewport *GPU_viewport_create(void);
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine);
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
void GPU_viewport_unbind(GPUViewport *viewport);
void GPU_viewport_free(GPUViewport *viewport);
-void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str);
+void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type);
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type);
+void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport);
+void *GPU_viewport_texture_list_get(GPUViewport *viewport);
+void GPU_viewport_size_get(GPUViewport *viewport, int *size);
+
+bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash);
/* debug */
bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]);
diff --git a/source/blender/gpu/gawain/attrib_binding.c b/source/blender/gpu/gawain/attrib_binding.c
deleted file mode 100644
index bb42aaf66eb..00000000000
--- a/source/blender/gpu/gawain/attrib_binding.c
+++ /dev/null
@@ -1,69 +0,0 @@
-
-// Gawain vertex attribute binding
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "attrib_binding.h"
-
-#if MAX_VERTEX_ATTRIBS != 16
- #error "attrib binding code assumes MAX_VERTEX_ATTRIBS = 16"
-#endif
-
-void clear_AttribBinding(AttribBinding* binding)
- {
- binding->loc_bits = 0;
- binding->enabled_bits = 0;
- }
-
-unsigned read_attrib_location(const AttribBinding* binding, unsigned a_idx)
- {
-#if TRUST_NO_ONE
- assert(a_idx < MAX_VERTEX_ATTRIBS);
- assert(binding->enabled_bits & (1 << a_idx));
-#endif
-
- return (binding->loc_bits >> (4 * a_idx)) & 0xF;
- }
-
-static void write_attrib_location(AttribBinding* binding, unsigned a_idx, unsigned location)
- {
-#if TRUST_NO_ONE
- assert(a_idx < MAX_VERTEX_ATTRIBS);
- assert(location < MAX_VERTEX_ATTRIBS);
-#endif
-
- const unsigned shift = 4 * a_idx;
- const uint64_t mask = ((uint64_t)0xF) << shift;
- // overwrite this attrib's previous location
- binding->loc_bits = (binding->loc_bits & ~mask) | (location << shift);
- // mark this attrib as enabled
- binding->enabled_bits |= 1 << a_idx;
- }
-
-void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, GLuint program)
- {
-#if TRUST_NO_ONE
- assert(glIsProgram(program));
-#endif
-
- clear_AttribBinding(binding);
-
- for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx)
- {
- const Attrib* a = format->attribs + a_idx;
- GLint loc = glGetAttribLocation(program, a->name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
- // TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
-#endif
-
- write_attrib_location(binding, a_idx, loc);
- }
- }
diff --git a/source/blender/gpu/gawain/attrib_binding.h b/source/blender/gpu/gawain/attrib_binding.h
deleted file mode 100644
index 9e2431ca379..00000000000
--- a/source/blender/gpu/gawain/attrib_binding.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-// Gawain vertex attribute binding
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-#include "vertex_format.h"
-
-typedef struct {
- uint64_t loc_bits; // store 4 bits for each of the 16 attribs
- uint16_t enabled_bits; // 1 bit for each attrib
-} AttribBinding;
-
-void clear_AttribBinding(AttribBinding*);
-
-void get_attrib_locations(const VertexFormat*, AttribBinding*, GLuint program);
-unsigned read_attrib_location(const AttribBinding*, unsigned a_idx);
diff --git a/source/blender/gpu/gawain/batch.c b/source/blender/gpu/gawain/batch.c
deleted file mode 100644
index 55ccd94a555..00000000000
--- a/source/blender/gpu/gawain/batch.c
+++ /dev/null
@@ -1,340 +0,0 @@
-
-// Gawain geometry batch
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "batch.h"
-#include "buffer_id.h"
-#include <stdlib.h>
-
-// necessary functions from matrix API
-extern void gpuBindMatrices(GLuint program);
-extern bool gpuMatricesDirty(void); // how best to use this here?
-
-Batch* Batch_create(PrimitiveType prim_type, VertexBuffer* verts, ElementList* elem)
- {
- Batch* batch = calloc(1, sizeof(Batch));
-
- Batch_init(batch, prim_type, verts, elem);
-
- return batch;
- }
-
-void Batch_init(Batch* batch, PrimitiveType prim_type, VertexBuffer* verts, ElementList* elem)
- {
-#if TRUST_NO_ONE
- assert(verts != NULL);
- assert(prim_type == PRIM_POINTS || prim_type == PRIM_LINES || prim_type == PRIM_TRIANGLES);
- // we will allow other primitive types in a future update
-#endif
-
- batch->verts = verts;
- batch->elem = elem;
- batch->prim_type = prim_type;
- batch->phase = READY_TO_DRAW;
- }
-
-void Batch_discard(Batch* batch)
- {
- if (batch->vao_id)
- vao_id_free(batch->vao_id);
-
- free(batch);
- }
-
-void Batch_discard_all(Batch* batch)
- {
- VertexBuffer_discard(batch->verts);
- if (batch->elem)
- ElementList_discard(batch->elem);
- Batch_discard(batch);
- }
-
-void Batch_set_program(Batch* batch, GLuint program)
- {
-#if TRUST_NO_ONE
- assert(glIsProgram(program));
-#endif
-
- batch->program = program;
- batch->program_dirty = true;
-
- Batch_use_program(batch); // hack! to make Batch_Uniform* simpler
- }
-
-static void Batch_update_program_bindings(Batch* batch)
- {
- const VertexFormat* format = &batch->verts->format;
-
- const unsigned attrib_ct = format->attrib_ct;
- const unsigned stride = format->stride;
-
- // disable all as a precaution
- // why are we not using prev_attrib_enabled_bits?? see immediate.c
- for (unsigned a_idx = 0; a_idx < MAX_VERTEX_ATTRIBS; ++a_idx)
- glDisableVertexAttribArray(a_idx);
-
- VertexBuffer_use(batch->verts);
-
- for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
- {
- const Attrib* a = format->attribs + a_idx;
-
- const GLvoid* pointer = (const GLubyte*)0 + a->offset;
-
- const GLint loc = glGetAttribLocation(batch->program, a->name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glEnableVertexAttribArray(loc);
-
- switch (a->fetch_mode)
- {
- case KEEP_FLOAT:
- case CONVERT_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_FALSE, stride, pointer);
- break;
- case NORMALIZE_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_TRUE, stride, pointer);
- break;
- case KEEP_INT:
- glVertexAttribIPointer(loc, a->comp_ct, a->comp_type, stride, pointer);
- }
- }
-
- batch->program_dirty = false;
- }
-
-void Batch_use_program(Batch* batch)
- {
- // NOTE: use_program & done_using_program are fragile, depend on staying in sync with
- // the GL context's active program. use_program doesn't mark other programs as "not used".
- // TODO: make not fragile (somehow)
-
- if (!batch->program_in_use)
- {
- glUseProgram(batch->program);
- batch->program_in_use = true;
- }
- }
-
-void Batch_done_using_program(Batch* batch)
- {
- if (batch->program_in_use)
- {
- glUseProgram(0);
- batch->program_in_use = false;
- }
- }
-
-void Batch_Uniform1b(Batch* batch, const char* name, bool value)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, value ? GL_TRUE : GL_FALSE);
- }
-
-void Batch_Uniform2f(Batch* batch, const char* name, float x, float y)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2f(loc, x, y);
- }
-
-void Batch_Uniform4f(Batch* batch, const char* name, float x, float y, float z, float w)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4f(loc, x, y, z, w);
- }
-
-void Batch_Uniform1f(Batch* batch, const char* name, float x)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1f(loc, x);
- }
-
-void Batch_Uniform3fv(Batch* batch, const char* name, const float data[3])
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3fv(loc, 1, data);
- }
-
-void Batch_Uniform4fv(Batch* batch, const char* name, const float data[4])
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4fv(loc, 1, data);
- }
-
-static void Batch_prime(Batch* batch)
- {
- batch->vao_id = vao_id_alloc();
- glBindVertexArray(batch->vao_id);
-
- VertexBuffer_use(batch->verts);
-
- if (batch->elem)
- ElementList_use(batch->elem);
-
- // vertex attribs and element list remain bound to this VAO
- }
-
-void Batch_draw(Batch* batch)
- {
-#if TRUST_NO_ONE
- assert(batch->phase == READY_TO_DRAW);
- assert(glIsProgram(batch->program));
-#endif
-
- if (batch->vao_id)
- glBindVertexArray(batch->vao_id);
- else
- Batch_prime(batch);
-
- if (batch->program_dirty)
- Batch_update_program_bindings(batch);
-
- Batch_use_program(batch);
-
- gpuBindMatrices(batch->program);
-
- if (batch->elem)
- {
- const ElementList* el = batch->elem;
-
-#if TRACK_INDEX_RANGE
- if (el->base_index)
- glDrawRangeElementsBaseVertex(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0, el->base_index);
- else
- glDrawRangeElements(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0);
-#else
- glDrawElements(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
-#endif
- }
- else
- glDrawArrays(batch->prim_type, 0, batch->verts->vertex_ct);
-
- Batch_done_using_program(batch);
- glBindVertexArray(0);
- }
-
-
-
-// clement : temp stuff
-void Batch_draw_stupid(Batch* batch)
-{
- if (batch->vao_id)
- glBindVertexArray(batch->vao_id);
- else
- Batch_prime(batch);
-
- if (batch->program_dirty)
- Batch_update_program_bindings(batch);
-
- // Batch_use_program(batch);
-
- //gpuBindMatrices(batch->program);
-
- if (batch->elem)
- {
- const ElementList* el = batch->elem;
-
-#if TRACK_INDEX_RANGE
- if (el->base_index)
- glDrawRangeElementsBaseVertex(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0, el->base_index);
- else
- glDrawRangeElements(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0);
-#else
- glDrawElements(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
-#endif
- }
- else
- glDrawArrays(batch->prim_type, 0, batch->verts->vertex_ct);
-
- // Batch_done_using_program(batch);
- glBindVertexArray(0);
-}
-
-// clement : temp stuff
-void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count,
- int attrib_nbr, int attrib_stride, int attrib_size[16], int attrib_loc[16])
-{
- if (batch->vao_id)
- glBindVertexArray(batch->vao_id);
- else
- Batch_prime(batch);
-
- if (batch->program_dirty)
- Batch_update_program_bindings(batch);
-
- glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
- int ptr_ofs = 0;
- for (int i = 0; i < attrib_nbr; ++i) {
- int size = attrib_size[i];
- int loc = attrib_loc[i];
- int atr_ofs = 0;
-
- while (size > 0) {
- glEnableVertexAttribArray(loc + atr_ofs);
- glVertexAttribPointer(loc + atr_ofs, (size > 4) ? 4 : size, GL_FLOAT, GL_FALSE,
- sizeof(float) * attrib_stride, (GLvoid*)(sizeof(float) * ptr_ofs));
- glVertexAttribDivisor(loc + atr_ofs, 1);
- atr_ofs++;
- ptr_ofs += (size > 4) ? 4 : size;
- size -= 4;
- }
- }
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- // Batch_use_program(batch);
-
- //gpuBindMatrices(batch->program);
-
- if (batch->elem)
- {
- const ElementList* el = batch->elem;
-
- glDrawElementsInstanced(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0, instance_count);
- }
- else
- glDrawArraysInstanced(batch->prim_type, 0, batch->verts->vertex_ct, instance_count);
-
- // Batch_done_using_program(batch);
- glBindVertexArray(0);
-}
-
diff --git a/source/blender/gpu/gawain/batch.h b/source/blender/gpu/gawain/batch.h
deleted file mode 100644
index 660ed9eb762..00000000000
--- a/source/blender/gpu/gawain/batch.h
+++ /dev/null
@@ -1,104 +0,0 @@
-
-// Gawain geometry batch
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-#include "vertex_buffer.h"
-#include "element.h"
-
-typedef enum {
- READY_TO_FORMAT,
- READY_TO_BUILD,
- BUILDING,
- READY_TO_DRAW
-} BatchPhase;
-
-typedef struct Batch{
- // geometry
- VertexBuffer* verts;
- ElementList* elem; // NULL if element list not needed
- PrimitiveType prim_type;
-
- // book-keeping
- GLuint vao_id; // remembers all geometry state (vertex attrib bindings & element buffer)
- BatchPhase phase;
- bool program_dirty;
- bool program_in_use;
-
- // state
- GLuint program;
-} Batch;
-
-Batch* Batch_create(PrimitiveType, VertexBuffer*, ElementList*);
-void Batch_init(Batch*, PrimitiveType, VertexBuffer*, ElementList*);
-
-void Batch_discard(Batch*); // verts & elem are not discarded
-void Batch_discard_all(Batch*); // including verts & elem
-
-void Batch_set_program(Batch*, GLuint program);
-// Entire batch draws with one shader program, but can be redrawn later with another program.
-// Vertex shader's inputs must be compatible with the batch's vertex format.
-
-void Batch_use_program(Batch*); // call before Batch_Uniform (temp hack?)
-void Batch_done_using_program(Batch*);
-
-void Batch_Uniform1b(Batch*, const char* name, bool value);
-void Batch_Uniform1f(Batch*, const char* name, float value);
-void Batch_Uniform2f(Batch*, const char* name, float x, float y);
-void Batch_Uniform4f(Batch*, const char* name, float x, float y, float z, float w);
-void Batch_Uniform3fv(Batch*, const char* name, const float data[3]);
-void Batch_Uniform4fv(Batch*, const char* name, const float data[4]);
-
-void Batch_draw(Batch*);
-
-
-// clement : temp stuff
-void Batch_draw_stupid(Batch*);
-void Batch_draw_stupid_instanced(Batch*, unsigned int instance_vbo, int instance_count,
- int attrib_nbr, int attrib_stride, int attrib_loc[16], int attrib_size[16]);
-
-
-
-
-
-
-#if 0 // future plans
-
-// Can multiple batches share a VertexBuffer? Use ref count?
-
-
-// We often need a batch with its own data, to be created and discarded together.
-// WithOwn variants reduce number of system allocations.
-
-typedef struct {
- Batch batch;
- VertexBuffer verts; // link batch.verts to this
-} BatchWithOwnVertexBuffer;
-
-typedef struct {
- Batch batch;
- ElementList elem; // link batch.elem to this
-} BatchWithOwnElementList;
-
-typedef struct {
- Batch batch;
- ElementList elem; // link batch.elem to this
- VertexBuffer verts; // link batch.verts to this
-} BatchWithOwnVertexBufferAndElementList;
-
-Batch* create_BatchWithOwnVertexBuffer(PrimitiveType, VertexFormat*, unsigned v_ct, ElementList*);
-Batch* create_BatchWithOwnElementList(PrimitiveType, VertexBuffer*, unsigned prim_ct);
-Batch* create_BatchWithOwnVertexBufferAndElementList(PrimitiveType, VertexFormat*, unsigned v_ct, unsigned prim_ct);
-// verts: shared, own
-// elem: none, shared, own
-Batch* create_BatchInGeneral(PrimitiveType, VertexBufferStuff, ElementListStuff);
-
-#endif // future plans
diff --git a/source/blender/gpu/gawain/buffer_id.cpp b/source/blender/gpu/gawain/buffer_id.cpp
deleted file mode 100644
index 450656c4ebf..00000000000
--- a/source/blender/gpu/gawain/buffer_id.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-
-// Gawain buffer IDs
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.#include "buffer_id.h"
-
-#include "buffer_id.h"
-#include <mutex>
-#include <vector>
-
-#define ORPHAN_DEBUG 0
-
-#if ORPHAN_DEBUG
- #include <cstdio>
-#endif
-
-static std::vector<GLuint> orphaned_buffer_ids;
-static std::vector<GLuint> orphaned_vao_ids;
-
-static std::mutex orphan_mutex;
-
-extern "C" {
-extern int BLI_thread_is_main(void); // Blender-specific function
-}
-
-static bool thread_is_main()
- {
- // "main" here means the GL context's thread
- return BLI_thread_is_main();
- }
-
-GLuint buffer_id_alloc()
- {
-#if TRUST_NO_ONE
- assert(thread_is_main());
-#endif
-
- // delete orphaned IDs
- orphan_mutex.lock();
- if (!orphaned_buffer_ids.empty())
- {
- const auto orphaned_buffer_ct = (unsigned)orphaned_buffer_ids.size();
-#if ORPHAN_DEBUG
- printf("deleting %u orphaned VBO%s\n", orphaned_buffer_ct, orphaned_buffer_ct == 1 ? "" : "s");
-#endif
- glDeleteBuffers(orphaned_buffer_ct, orphaned_buffer_ids.data());
- orphaned_buffer_ids.clear();
- }
- orphan_mutex.unlock();
-
- GLuint new_buffer_id = 0;
- glGenBuffers(1, &new_buffer_id);
- return new_buffer_id;
- }
-
-void buffer_id_free(GLuint buffer_id)
- {
- if (thread_is_main())
- glDeleteBuffers(1, &buffer_id);
- else
- {
- // add this ID to the orphaned list
- orphan_mutex.lock();
-#if ORPHAN_DEBUG
- printf("orphaning VBO %u\n", buffer_id);
-#endif
- orphaned_buffer_ids.emplace_back(buffer_id);
- orphan_mutex.unlock();
- }
- }
-
-GLuint vao_id_alloc()
- {
-#if TRUST_NO_ONE
- assert(thread_is_main());
-#endif
-
- // delete orphaned IDs
- orphan_mutex.lock();
- if (!orphaned_vao_ids.empty())
- {
- const auto orphaned_vao_ct = (unsigned)orphaned_vao_ids.size();
-#if ORPHAN_DEBUG
- printf("deleting %u orphaned VAO%s\n", orphaned_vao_ct, orphaned_vao_ct == 1 ? "" : "s");
-#endif
- glDeleteVertexArrays(orphaned_vao_ct, orphaned_vao_ids.data());
- orphaned_vao_ids.clear();
- }
- orphan_mutex.unlock();
-
- GLuint new_vao_id = 0;
- glGenVertexArrays(1, &new_vao_id);
- return new_vao_id;
- }
-
-void vao_id_free(GLuint vao_id)
- {
- if (thread_is_main())
- glDeleteVertexArrays(1, &vao_id);
- else
- {
- // add this ID to the orphaned list
- orphan_mutex.lock();
-#if ORPHAN_DEBUG
- printf("orphaning VAO %u\n", vao_id);
-#endif
- orphaned_vao_ids.emplace_back(vao_id);
- orphan_mutex.unlock();
- }
- }
diff --git a/source/blender/gpu/gawain/buffer_id.h b/source/blender/gpu/gawain/buffer_id.h
deleted file mode 100644
index 3f67458d060..00000000000
--- a/source/blender/gpu/gawain/buffer_id.h
+++ /dev/null
@@ -1,34 +0,0 @@
-
-// Gawain buffer IDs
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-// Manage GL buffer IDs in a thread-safe way
-// Use these instead of glGenBuffers & its friends
-// - alloc must be called from main thread
-// - free can be called from any thread
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "common.h"
-
-GLuint buffer_id_alloc(void);
-void buffer_id_free(GLuint buffer_id);
-
-GLuint vao_id_alloc(void);
-void vao_id_free(GLuint vao_id);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/gpu/gawain/common.h b/source/blender/gpu/gawain/common.h
deleted file mode 100644
index 90340b94e4d..00000000000
--- a/source/blender/gpu/gawain/common.h
+++ /dev/null
@@ -1,58 +0,0 @@
-
-// Gawain common #defines and #includes
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-// #define TRUST_NO_ONE !defined(NDEBUG)
-#define TRUST_NO_ONE 1
-// strict error checking, always enabled during early development
-
-#include <GL/glew.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#if TRUST_NO_ONE
- #include <assert.h>
-#endif
-
-#define PER_THREAD
-// #define PER_THREAD __thread
-// MSVC uses __declspec(thread) for C code
-
-#define APPLE_LEGACY (defined(__APPLE__) && defined(WITH_GL_PROFILE_COMPAT))
-
-#if APPLE_LEGACY
- #undef glGenVertexArrays
- #define glGenVertexArrays glGenVertexArraysAPPLE
-
- #undef glDeleteVertexArrays
- #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
-
- #undef glBindVertexArray
- #define glBindVertexArray glBindVertexArrayAPPLE
-#endif
-
-typedef enum {
- PRIM_POINTS = GL_POINTS,
- PRIM_LINES = GL_LINES,
- PRIM_TRIANGLES = GL_TRIANGLES,
-
-#ifdef WITH_GL_PROFILE_COMPAT
- PRIM_QUADS = GL_QUADS, // legacy GL has this, modern GL & Vulkan do not
-#endif
-
- PRIM_LINE_STRIP = GL_LINE_STRIP,
- PRIM_LINE_LOOP = GL_LINE_LOOP, // GL has this, Vulkan does not
- PRIM_TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
- PRIM_TRIANGLE_FAN = GL_TRIANGLE_FAN,
-
- PRIM_NONE = 0xF
-} PrimitiveType;
diff --git a/source/blender/gpu/gawain/element.c b/source/blender/gpu/gawain/element.c
deleted file mode 100644
index 3c3ca1c7626..00000000000
--- a/source/blender/gpu/gawain/element.c
+++ /dev/null
@@ -1,283 +0,0 @@
-
-// Gawain element list (AKA index buffer)
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "element.h"
-#include "buffer_id.h"
-#include <stdlib.h>
-
-#define KEEP_SINGLE_COPY 1
-
-unsigned ElementList_size(const ElementList* elem)
- {
-#if TRACK_INDEX_RANGE
- switch (elem->index_type)
- {
- case INDEX_U8: return elem->index_ct * sizeof(GLubyte);
- case INDEX_U16: return elem->index_ct * sizeof(GLushort);
- case INDEX_U32: return elem->index_ct * sizeof(GLuint);
- default:
- #if TRUST_NO_ONE
- assert(false);
- #endif
- return 0;
- }
-
-#else
- return elem->index_ct * sizeof(GLuint);
-#endif
- }
-
-static void ElementList_prime(ElementList* elem)
- {
- elem->vbo_id = buffer_id_alloc();
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
- // fill with delicious data & send to GPU the first time only
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, ElementList_size(elem), elem->data, GL_STATIC_DRAW);
-
-#if KEEP_SINGLE_COPY
- // now that GL has a copy, discard original
- free(elem->data);
- elem->data = NULL;
-#endif
- }
-
-void ElementList_use(ElementList* elem)
- {
- if (elem->vbo_id)
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
- else
- ElementList_prime(elem);
- }
-
-void ElementListBuilder_init(ElementListBuilder* builder, PrimitiveType prim_type, unsigned prim_ct, unsigned vertex_ct)
- {
- unsigned verts_per_prim = 0;
- switch (prim_type)
- {
- case PRIM_POINTS:
- verts_per_prim = 1;
- break;
- case PRIM_LINES:
- verts_per_prim = 2;
- break;
- case PRIM_TRIANGLES:
- verts_per_prim = 3;
- break;
- default:
-#if TRUST_NO_ONE
- assert(false);
-#endif
- return;
- }
-
- builder->max_allowed_index = vertex_ct - 1;
- builder->max_index_ct = prim_ct * verts_per_prim;
- builder->index_ct = 0; // start empty
- builder->prim_type = prim_type;
- builder->data = calloc(builder->max_index_ct, sizeof(unsigned));
- }
-
-void add_generic_vertex(ElementListBuilder* builder, unsigned v)
- {
-#if TRUST_NO_ONE
- assert(builder->data != NULL);
- assert(builder->index_ct < builder->max_index_ct);
- assert(v <= builder->max_allowed_index);
-#endif
-
- builder->data[builder->index_ct++] = v;
- }
-
-void add_point_vertex(ElementListBuilder* builder, unsigned v)
- {
-#if TRUST_NO_ONE
- assert(builder->prim_type == PRIM_POINTS);
-#endif
-
- add_generic_vertex(builder, v);
- }
-
-void add_line_vertices(ElementListBuilder* builder, unsigned v1, unsigned v2)
- {
-#if TRUST_NO_ONE
- assert(builder->prim_type == PRIM_LINES);
- assert(v1 != v2);
-#endif
-
- add_generic_vertex(builder, v1);
- add_generic_vertex(builder, v2);
- }
-
-void add_triangle_vertices(ElementListBuilder* builder, unsigned v1, unsigned v2, unsigned v3)
- {
-#if TRUST_NO_ONE
- assert(builder->prim_type == PRIM_TRIANGLES);
- assert(v1 != v2 && v2 != v3 && v3 != v1);
-#endif
-
- add_generic_vertex(builder, v1);
- add_generic_vertex(builder, v2);
- add_generic_vertex(builder, v3);
- }
-
-#if TRACK_INDEX_RANGE
-// Everything remains 32 bit while building to keep things simple.
-// Find min/max after, then convert to smallest index type possible.
-
-static unsigned index_range(const unsigned values[], unsigned value_ct, unsigned* min_out, unsigned* max_out)
- {
- unsigned min_value = values[0];
- unsigned max_value = values[0];
- for (unsigned i = 1; i < value_ct; ++i)
- {
- const unsigned value = values[i];
- if (value < min_value)
- min_value = value;
- else if (value > max_value)
- max_value = value;
- }
- *min_out = min_value;
- *max_out = max_value;
- return max_value - min_value;
- }
-
-static void squeeze_indices_byte(const unsigned values[], ElementList* elem)
- {
- const unsigned index_ct = elem->index_ct;
- GLubyte* data = malloc(index_ct * sizeof(GLubyte));
-
- if (elem->max_index > 0xFF)
- {
- const unsigned base = elem->min_index;
-
- elem->base_index = base;
- elem->min_index = 0;
- elem->max_index -= base;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLubyte)(values[i] - base);
- }
- else
- {
- elem->base_index = 0;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLubyte)(values[i]);
- }
-
- elem->data = data;
- }
-
-static void squeeze_indices_short(const unsigned values[], ElementList* elem)
- {
- const unsigned index_ct = elem->index_ct;
- GLushort* data = malloc(index_ct * sizeof(GLushort));
-
- if (elem->max_index > 0xFFFF)
- {
- const unsigned base = elem->min_index;
-
- elem->base_index = base;
- elem->min_index = 0;
- elem->max_index -= base;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLushort)(values[i] - base);
- }
- else
- {
- elem->base_index = 0;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLushort)(values[i]);
- }
-
- elem->data = data;
- }
-
-#endif // TRACK_INDEX_RANGE
-
-ElementList* ElementList_build(ElementListBuilder* builder)
- {
- ElementList* elem = calloc(1, sizeof(ElementList));
- ElementList_build_in_place(builder, elem);
- return elem;
- }
-
-void ElementList_build_in_place(ElementListBuilder* builder, ElementList* elem)
- {
-#if TRUST_NO_ONE
- assert(builder->data != NULL);
-#endif
-
- elem->index_ct = builder->index_ct;
-
-#if TRACK_INDEX_RANGE
- const unsigned range = index_range(builder->data, builder->index_ct, &elem->min_index, &elem->max_index);
-
- if (range <= 0xFF)
- {
- elem->index_type = INDEX_U8;
- squeeze_indices_byte(builder->data, elem);
- }
- else if (range <= 0xFFFF)
- {
- elem->index_type = INDEX_U16;
- squeeze_indices_short(builder->data, elem);
- }
- else
- {
- elem->index_type = INDEX_U32;
- elem->base_index = 0;
-
- if (builder->index_ct < builder->max_index_ct)
- {
- builder->data = realloc(builder->data, builder->index_ct * sizeof(unsigned));
- // TODO: realloc only if index_ct is much smaller than max_index_ct
- }
-
- elem->data = builder->data;
- }
-#else
- if (builder->index_ct < builder->max_index_ct)
- {
- builder->data = realloc(builder->data, builder->index_ct * sizeof(unsigned));
- // TODO: realloc only if index_ct is much smaller than max_index_ct
- }
-
- elem->data = builder->data;
-#endif
-
- // elem->data will never be *larger* than builder->data... how about converting
- // in place to avoid extra allocation?
-
- elem->vbo_id = 0;
- // TODO: create GL buffer object directly, based on an input flag
-
- // discard builder (one-time use)
- if (builder->data != elem->data)
- free(builder->data);
- builder->data = NULL;
- // other fields are safe to leave
- }
-
-void ElementList_discard(ElementList* elem)
- {
- if (elem->vbo_id)
- buffer_id_free(elem->vbo_id);
-#if KEEP_SINGLE_COPY
- else
-#endif
- if (elem->data)
- free(elem->data);
-
- free(elem);
- }
diff --git a/source/blender/gpu/gawain/element.h b/source/blender/gpu/gawain/element.h
deleted file mode 100644
index 4e0d5fb0649..00000000000
--- a/source/blender/gpu/gawain/element.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-// Gawain element list (AKA index buffer)
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-#include "common.h"
-
-#define TRACK_INDEX_RANGE 1
-
-typedef enum {
- INDEX_U8 = GL_UNSIGNED_BYTE, // GL has this, Vulkan does not
- INDEX_U16 = GL_UNSIGNED_SHORT,
- INDEX_U32 = GL_UNSIGNED_INT
-} IndexType;
-
-typedef struct {
- unsigned index_ct;
-#if TRACK_INDEX_RANGE
- IndexType index_type;
- unsigned min_index;
- unsigned max_index;
- unsigned base_index;
-#endif
- void* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
- GLuint vbo_id; // 0 indicates not yet sent to VRAM
-} ElementList;
-
-void ElementList_use(ElementList*);
-unsigned ElementList_size(const ElementList*);
-
-typedef struct {
- unsigned max_allowed_index;
- unsigned max_index_ct;
- unsigned index_ct;
- PrimitiveType prim_type;
- unsigned* data;
-} ElementListBuilder;
-
-// supported primitives:
-// PRIM_POINTS
-// PRIM_LINES
-// PRIM_TRIANGLES
-
-void ElementListBuilder_init(ElementListBuilder*, PrimitiveType, unsigned prim_ct, unsigned vertex_ct);
-//void ElementListBuilder_init_custom(ElementListBuilder*, PrimitiveType, unsigned index_ct, unsigned vertex_ct);
-
-void add_generic_vertex(ElementListBuilder*, unsigned v);
-
-void add_point_vertex(ElementListBuilder*, unsigned v);
-void add_line_vertices(ElementListBuilder*, unsigned v1, unsigned v2);
-void add_triangle_vertices(ElementListBuilder*, unsigned v1, unsigned v2, unsigned v3);
-
-ElementList* ElementList_build(ElementListBuilder*);
-void ElementList_build_in_place(ElementListBuilder*, ElementList*);
-
-void ElementList_discard(ElementList*);
diff --git a/source/blender/gpu/gawain/imm_util.c b/source/blender/gpu/gawain/imm_util.c
deleted file mode 100644
index 74caeb6fd3a..00000000000
--- a/source/blender/gpu/gawain/imm_util.c
+++ /dev/null
@@ -1,46 +0,0 @@
-
-// Gawain immediate mode drawing utilities
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "imm_util.h"
-#include "immediate.h"
-
-
-void immRectf(unsigned pos, float x1, float y1, float x2, float y2)
-{
- immBegin(PRIM_TRIANGLE_FAN, 4);
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y1);
- immVertex2f(pos, x2, y2);
- immVertex2f(pos, x1, y2);
- immEnd();
-}
-
-void immRecti(unsigned pos, int x1, int y1, int x2, int y2)
-{
- immBegin(PRIM_TRIANGLE_FAN, 4);
- immVertex2i(pos, x1, y1);
- immVertex2i(pos, x2, y1);
- immVertex2i(pos, x2, y2);
- immVertex2i(pos, x1, y2);
- immEnd();
-}
-
-#if 0 // more complete version in case we want that
-void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4])
-{
- VertexFormat *format = immVertexFormat();
- unsigned pos = add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(color);
- immRecti(pos, x1, y1, x2, y2);
- immUnbindProgram();
-}
-#endif
diff --git a/source/blender/gpu/gawain/imm_util.h b/source/blender/gpu/gawain/imm_util.h
deleted file mode 100644
index 730bd7c1a3c..00000000000
--- a/source/blender/gpu/gawain/imm_util.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-// Gawain immediate mode drawing utilities
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-
-// Draw 2D rectangles (replaces glRect functions)
-// caller is reponsible for vertex format & shader
-void immRectf(unsigned pos, float x1, float y1, float x2, float y2);
-void immRecti(unsigned pos, int x1, int y1, int x2, int y2);
diff --git a/source/blender/gpu/gawain/immediate.c b/source/blender/gpu/gawain/immediate.c
deleted file mode 100644
index b7aad530620..00000000000
--- a/source/blender/gpu/gawain/immediate.c
+++ /dev/null
@@ -1,868 +0,0 @@
-
-// Gawain immediate mode work-alike
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "immediate.h"
-#include "attrib_binding.h"
-#include "buffer_id.h"
-#include <string.h>
-
-// necessary functions from matrix API
-extern void gpuBindMatrices(GLuint program);
-extern bool gpuMatricesDirty(void);
-
-typedef struct {
- // TODO: organize this struct by frequency of change (run-time)
-
-#if IMM_BATCH_COMBO
- Batch* batch;
-#endif
-
- // current draw call
- GLubyte* buffer_data;
- unsigned buffer_offset;
- unsigned buffer_bytes_mapped;
- unsigned vertex_ct;
- bool strict_vertex_ct;
- PrimitiveType prim_type;
-
- VertexFormat vertex_format;
-
- // current vertex
- unsigned vertex_idx;
- GLubyte* vertex_data;
- uint16_t unassigned_attrib_bits; // which attributes of current vertex have not been given values?
-
- GLuint vbo_id;
- GLuint vao_id;
-
- GLuint bound_program;
- AttribBinding attrib_binding;
- uint16_t prev_enabled_attrib_bits; // <-- only affects this VAO, so we're ok
-} Immediate;
-
-// size of internal buffer -- make this adjustable?
-#define IMM_BUFFER_SIZE (4 * 1024 * 1024)
-
-static PER_THREAD bool initialized = false;
-static PER_THREAD Immediate imm;
-
-void immInit(void)
- {
-#if TRUST_NO_ONE
- assert(!initialized);
-#endif
-
- memset(&imm, 0, sizeof(Immediate));
-
- imm.vbo_id = buffer_id_alloc();
- glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id);
- glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
-
-#if APPLE_LEGACY
- glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
- glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
-#endif
-
- imm.prim_type = PRIM_NONE;
- imm.strict_vertex_ct = true;
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- initialized = true;
-
- immActivate();
- }
-
-void immActivate(void)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we're not between a Begin/End pair
- assert(imm.vao_id == 0);
-#endif
-
- imm.vao_id = vao_id_alloc();
- }
-
-void immDeactivate(void)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we're not between a Begin/End pair
- assert(imm.vao_id != 0);
-#endif
-
- vao_id_free(imm.vao_id);
- imm.vao_id = 0;
- imm.prev_enabled_attrib_bits = 0;
- }
-
-void immDestroy(void)
- {
- immDeactivate();
- buffer_id_free(imm.vbo_id);
- initialized = false;
- }
-
-VertexFormat* immVertexFormat(void)
- {
- VertexFormat_clear(&imm.vertex_format);
- return &imm.vertex_format;
- }
-
-void immBindProgram(GLuint program)
- {
-#if TRUST_NO_ONE
- assert(imm.bound_program == 0);
- assert(glIsProgram(program));
-#endif
-
- if (!imm.vertex_format.packed)
- VertexFormat_pack(&imm.vertex_format);
-
- glUseProgram(program);
- get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program);
- imm.bound_program = program;
-
- gpuBindMatrices(program);
- }
-
-void immUnbindProgram(void)
- {
-#if TRUST_NO_ONE
- assert(imm.bound_program != 0);
-#endif
-
- glUseProgram(0);
- imm.bound_program = 0;
- }
-
-static bool vertex_count_makes_sense_for_primitive(unsigned vertex_ct, PrimitiveType prim_type)
- {
- // does vertex_ct make sense for this primitive type?
- if (vertex_ct == 0)
- return false;
-
- switch (prim_type)
- {
- case PRIM_POINTS:
- return true;
- case PRIM_LINES:
- return vertex_ct % 2 == 0;
- case PRIM_LINE_STRIP:
- case PRIM_LINE_LOOP:
- return vertex_ct >= 2;
- case PRIM_TRIANGLES:
- return vertex_ct % 3 == 0;
- case PRIM_TRIANGLE_STRIP:
- case PRIM_TRIANGLE_FAN:
- return vertex_ct >= 3;
- #ifdef WITH_GL_PROFILE_COMPAT
- case PRIM_QUADS:
- return vertex_ct % 4 == 0;
- #endif
- default:
- return false;
- }
- }
-
-void immBegin(PrimitiveType prim_type, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we haven't already begun
- assert(vertex_count_makes_sense_for_primitive(vertex_ct, prim_type));
-#endif
-
- imm.prim_type = prim_type;
- imm.vertex_ct = vertex_ct;
- imm.vertex_idx = 0;
- imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
-
- // how many bytes do we need for this draw call?
- const unsigned bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_ct);
-
-#if TRUST_NO_ONE
- assert(bytes_needed <= IMM_BUFFER_SIZE);
-#endif
-
- glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id);
-
- // does the current buffer have enough room?
- const unsigned available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset;
- // ensure vertex data is aligned
- const unsigned pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); // might waste a little space, but it's safe
- if ((bytes_needed + pre_padding) <= available_bytes)
- imm.buffer_offset += pre_padding;
- else
- {
- // orphan this buffer & start with a fresh one
-#if APPLE_LEGACY
- glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
-#else
- if (GLEW_VERSION_4_3 || GLEW_ARB_invalidate_subdata)
- glInvalidateBufferData(imm.vbo_id);
- else
- glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE, GL_MAP_INVALIDATE_BUFFER_BIT);
-#endif
-
- imm.buffer_offset = 0;
- }
-
-// printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1);
-
-#if APPLE_LEGACY
- imm.buffer_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY) + imm.buffer_offset;
-#else
- imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, imm.buffer_offset, bytes_needed,
- GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | (imm.strict_vertex_ct ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT));
-#endif
-
-#if TRUST_NO_ONE
- assert(imm.buffer_data != NULL);
-#endif
-
- imm.buffer_bytes_mapped = bytes_needed;
- imm.vertex_data = imm.buffer_data;
- }
-
-void immBeginAtMost(PrimitiveType prim_type, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(vertex_ct > 0);
-#endif
-
- imm.strict_vertex_ct = false;
- immBegin(prim_type, vertex_ct);
- }
-
-#if IMM_BATCH_COMBO
-
-Batch* immBeginBatch(PrimitiveType prim_type, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we haven't already begun
- assert(vertex_count_makes_sense_for_primitive(vertex_ct, prim_type));
-#endif
-
- imm.prim_type = prim_type;
- imm.vertex_ct = vertex_ct;
- imm.vertex_idx = 0;
- imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
-
- VertexBuffer* verts = VertexBuffer_create_with_format(&imm.vertex_format);
- VertexBuffer_allocate_data(verts, vertex_ct);
-
- imm.buffer_bytes_mapped = VertexBuffer_size(verts);
- imm.vertex_data = verts->data;
-
- imm.batch = Batch_create(prim_type, verts, NULL);
- imm.batch->phase = BUILDING;
-
- Batch_set_program(imm.batch, imm.bound_program);
-
- return imm.batch;
- }
-
-Batch* immBeginBatchAtMost(PrimitiveType prim_type, unsigned vertex_ct)
- {
- imm.strict_vertex_ct = false;
- return immBeginBatch(prim_type, vertex_ct);
- }
-
-#endif // IMM_BATCH_COMBO
-
-static void immDrawSetup(void)
- {
- // set up VAO -- can be done during Begin or End really
- glBindVertexArray(imm.vao_id);
-
- // enable/disable vertex attribs as needed
- if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits)
- {
- for (unsigned loc = 0; loc < MAX_VERTEX_ATTRIBS; ++loc)
- {
- bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc);
- bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc);
-
- if (is_enabled && !was_enabled)
- {
-// printf("enabling attrib %u\n", loc);
- glEnableVertexAttribArray(loc);
- }
- else if (was_enabled && !is_enabled)
- {
-// printf("disabling attrib %u\n", loc);
- glDisableVertexAttribArray(loc);
- }
- }
-
- imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits;
- }
-
- const unsigned stride = imm.vertex_format.stride;
-
- for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx)
- {
- const Attrib* a = imm.vertex_format.attribs + a_idx;
-
- const unsigned offset = imm.buffer_offset + a->offset;
- const GLvoid* pointer = (const GLubyte*)0 + offset;
-
- const unsigned loc = read_attrib_location(&imm.attrib_binding, a_idx);
-
-// printf("specifying attrib %u '%s' with offset %u, stride %u\n", loc, a->name, offset, stride);
-
- switch (a->fetch_mode)
- {
- case KEEP_FLOAT:
- case CONVERT_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_FALSE, stride, pointer);
- break;
- case NORMALIZE_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_TRUE, stride, pointer);
- break;
- case KEEP_INT:
- glVertexAttribIPointer(loc, a->comp_ct, a->comp_type, stride, pointer);
- }
- }
-
- if (gpuMatricesDirty())
- gpuBindMatrices(imm.bound_program);
- }
-
-void immEnd(void)
- {
-#if TRUST_NO_ONE
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- unsigned buffer_bytes_used;
- if (imm.strict_vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx == imm.vertex_ct); // with all vertices defined
-#endif
- buffer_bytes_used = imm.buffer_bytes_mapped;
- }
- else
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx <= imm.vertex_ct);
-#endif
- // printf("used %u of %u verts,", imm.vertex_idx, imm.vertex_ct);
- if (imm.vertex_idx == imm.vertex_ct)
- {
- buffer_bytes_used = imm.buffer_bytes_mapped;
- }
- else
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx == 0 || vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type));
-#endif
- imm.vertex_ct = imm.vertex_idx;
- buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_ct);
- // unused buffer bytes are available to the next immBegin
- // printf(" %u of %u bytes\n", buffer_bytes_used, imm.buffer_bytes_mapped);
- }
-#if !APPLE_LEGACY
- // tell OpenGL what range was modified so it doesn't copy the whole mapped range
- // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
- glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used);
-#endif
- }
-
-#if IMM_BATCH_COMBO
- if (imm.batch)
- {
- if (buffer_bytes_used != imm.buffer_bytes_mapped)
- {
- VertexBuffer_resize_data(imm.batch->verts, imm.vertex_ct);
- // TODO: resize only if vertex count is much smaller
- }
-
- imm.batch->phase = READY_TO_DRAW;
- imm.batch = NULL; // don't free, batch belongs to caller
- }
- else
-#endif
- {
-#if APPLE_LEGACY
- // tell OpenGL what range was modified so it doesn't copy the whole buffer
- // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
- glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, imm.buffer_offset, buffer_bytes_used);
-#endif
- glUnmapBuffer(GL_ARRAY_BUFFER);
-
- if (imm.vertex_ct > 0)
- {
- immDrawSetup();
- glDrawArrays(imm.prim_type, 0, imm.vertex_ct);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
-
- // prep for next immBegin
- imm.buffer_offset += buffer_bytes_used;
- }
-
- // prep for next immBegin
- imm.prim_type = PRIM_NONE;
- imm.strict_vertex_ct = true;
- }
-
-static void setAttribValueBit(unsigned attrib_id)
- {
- uint16_t mask = 1 << attrib_id;
-
-#if TRUST_NO_ONE
- assert(imm.unassigned_attrib_bits & mask); // not already set
-#endif
-
- imm.unassigned_attrib_bits &= ~mask;
- }
-
-
-// --- generic attribute functions ---
-
-void immAttrib1f(unsigned attrib_id, float x)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 1);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- }
-
-void immAttrib2f(unsigned attrib_id, float x, float y)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 2);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- data[1] = y;
- }
-
-void immAttrib3f(unsigned attrib_id, float x, float y, float z)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 3);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- data[1] = y;
- data[2] = z;
- }
-
-void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 4);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- data[1] = y;
- data[2] = z;
- data[3] = w;
- }
-
-void immAttrib2i(unsigned attrib_id, int x, int y)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_I32);
- assert(attrib->comp_ct == 2);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- int* data = (int*)(imm.vertex_data + attrib->offset);
-
- data[0] = x;
- data[1] = y;
- }
-
-void immAttrib2s(unsigned attrib_id, short x, short y)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_I16);
- assert(attrib->comp_ct == 2);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- short* data = (short*)(imm.vertex_data + attrib->offset);
-
- data[0] = x;
- data[1] = y;
- }
-
-void immAttrib3fv(unsigned attrib_id, const float data[3])
- {
- immAttrib3f(attrib_id, data[0], data[1], data[2]);
- }
-
-void immAttrib4fv(unsigned attrib_id, const float data[4])
- {
- immAttrib4f(attrib_id, data[0], data[1], data[2], data[3]);
- }
-
-void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_U8);
- assert(attrib->comp_ct == 3);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- GLubyte* data = imm.vertex_data + attrib->offset;
-// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data);
-
- data[0] = r;
- data[1] = g;
- data[2] = b;
- }
-
-void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_U8);
- assert(attrib->comp_ct == 4);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- GLubyte* data = imm.vertex_data + attrib->offset;
-// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data);
-
- data[0] = r;
- data[1] = g;
- data[2] = b;
- data[3] = a;
- }
-
-void immAttrib3ubv(unsigned attrib_id, const unsigned char data[3])
- {
- immAttrib3ub(attrib_id, data[0], data[1], data[2]);
- }
-
-void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4])
- {
- immAttrib4ub(attrib_id, data[0], data[1], data[2], data[3]);
- }
-
-void immSkipAttrib(unsigned attrib_id)
- {
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
- }
-
-static void immEndVertex(void) // and move on to the next vertex
- {
-#if TRUST_NO_ONE
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
- assert(imm.vertex_idx < imm.vertex_ct);
-#endif
-
- // have all attribs been assigned values?
- // if not, copy value from previous vertex
- if (imm.unassigned_attrib_bits)
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx > 0); // first vertex must have all attribs specified
-#endif
-
- for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx)
- {
- if ((imm.unassigned_attrib_bits >> a_idx) & 1)
- {
- const Attrib* a = imm.vertex_format.attribs + a_idx;
-
-// printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx);
-
- GLubyte* data = imm.vertex_data + a->offset;
- memcpy(data, data - imm.vertex_format.stride, a->sz);
- // TODO: consolidate copy of adjacent attributes
- }
- }
- }
-
- imm.vertex_idx++;
- imm.vertex_data += imm.vertex_format.stride;
- imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
- }
-
-void immVertex2f(unsigned attrib_id, float x, float y)
- {
- immAttrib2f(attrib_id, x, y);
- immEndVertex();
- }
-
-void immVertex3f(unsigned attrib_id, float x, float y, float z)
- {
- immAttrib3f(attrib_id, x, y, z);
- immEndVertex();
- }
-
-void immVertex2i(unsigned attrib_id, int x, int y)
- {
- immAttrib2i(attrib_id, x, y);
- immEndVertex();
- }
-
-void immVertex2s(unsigned attrib_id, short x, short y)
- {
- immAttrib2s(attrib_id, x, y);
- immEndVertex();
- }
-
-void immVertex2fv(unsigned attrib_id, const float data[2])
- {
- immAttrib2f(attrib_id, data[0], data[1]);
- immEndVertex();
- }
-
-void immVertex3fv(unsigned attrib_id, const float data[3])
- {
- immAttrib3f(attrib_id, data[0], data[1], data[2]);
- immEndVertex();
- }
-
-void immVertex2iv(unsigned attrib_id, const int data[2])
- {
- immAttrib2i(attrib_id, data[0], data[1]);
- immEndVertex();
- }
-
-
-// --- generic uniform functions ---
-
-void immUniform1f(const char* name, float x)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1f(loc, x);
- }
-
-void immUniform2f(const char* name, float x, float y)
-{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2f(loc, x, y);
-}
-
-void immUniform2fv(const char* name, const float data[2])
-{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2fv(loc, 1, data);
-}
-
-void immUniform3f(const char* name, float x, float y, float z)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3f(loc, x, y, z);
- }
-
-void immUniform3fv(const char* name, const float data[3])
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3fv(loc, 1, data);
- }
-
-void immUniform4f(const char* name, float x, float y, float z, float w)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4f(loc, x, y, z, w);
- }
-
-void immUniform4fv(const char* name, const float data[4])
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4fv(loc, 1, data);
- }
-
-void immUniformMat4(const char* name, const float data[4][4])
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniformMatrix4fv(loc, 1, GL_FALSE, (float *)data);
- }
-
-void immUniform1i(const char* name, int x)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, x);
- }
-
-
-// --- convenience functions for setting "uniform vec4 color" ---
-
-void immUniformColor4f(float r, float g, float b, float a)
- {
- immUniform4f("color", r, g, b, a);
- }
-
-void immUniformColor4fv(const float rgba[4])
- {
- immUniform4fv("color", rgba);
- }
-
-void immUniformColor3f(float r, float g, float b)
- {
- immUniform4f("color", r, g, b, 1.0f);
- }
-
-void immUniformColor3fv(const float rgb[3])
- {
- immUniform4f("color", rgb[0], rgb[1], rgb[2], 1.0f);
- }
-
-void immUniformColor3fvAlpha(const float rgb[3], float a)
- {
- immUniform4f("color", rgb[0], rgb[1], rgb[2], a);
- }
-
-// TODO: v-- treat as sRGB? --v
-
-void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b)
- {
- const float scale = 1.0f / 255.0f;
- immUniform4f("color", scale * r, scale * g, scale * b, 1.0f);
- }
-
-void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
- {
- const float scale = 1.0f / 255.0f;
- immUniform4f("color", scale * r, scale * g, scale * b, scale * a);
- }
-
-void immUniformColor3ubv(const unsigned char rgb[3])
- {
- immUniformColor3ub(rgb[0], rgb[1], rgb[2]);
- }
-
-void immUniformColor4ubv(const unsigned char rgba[4])
- {
- immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]);
- }
diff --git a/source/blender/gpu/gawain/immediate.h b/source/blender/gpu/gawain/immediate.h
deleted file mode 100644
index 53f9e6c46e1..00000000000
--- a/source/blender/gpu/gawain/immediate.h
+++ /dev/null
@@ -1,110 +0,0 @@
-
-// Gawain immediate mode work-alike
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-#include "vertex_format.h"
-
-#define IMM_BATCH_COMBO 1
-
-
-VertexFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib
-
-void immBindProgram(GLuint program); // every immBegin must have a program bound first
-void immUnbindProgram(void); // call after your last immEnd, or before binding another program
-
-void immBegin(PrimitiveType, unsigned vertex_ct); // must supply exactly vertex_ct vertices
-void immBeginAtMost(PrimitiveType, unsigned max_vertex_ct); // can supply fewer vertices
-void immEnd(void); // finishes and draws
-
-#if IMM_BATCH_COMBO
-#include "batch.h"
-// immBegin a batch, then use standard immFunctions as usual.
-// immEnd will finalize the batch instead of drawing.
-// Then you can draw it as many times as you like! Partially replaces the need for display lists.
-Batch* immBeginBatch(PrimitiveType, unsigned vertex_ct);
-Batch* immBeginBatchAtMost(PrimitiveType, unsigned vertex_ct);
-#endif
-
-
-// provide attribute values that can change per vertex
-// first vertex after immBegin must have all its attributes specified
-// skipped attributes will continue using the previous value for that attrib_id
-void immAttrib1f(unsigned attrib_id, float x);
-void immAttrib2f(unsigned attrib_id, float x, float y);
-void immAttrib3f(unsigned attrib_id, float x, float y, float z);
-void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w);
-
-void immAttrib2i(unsigned attrib_id, int x, int y);
-
-void immAttrib2s(unsigned attrib_id, short x, short y);
-
-void immAttrib3fv(unsigned attrib_id, const float data[3]);
-void immAttrib4fv(unsigned attrib_id, const float data[4]);
-
-void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b);
-void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
-
-void immAttrib3ubv(unsigned attrib_id, const unsigned char data[4]);
-void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4]);
-
-// explicitly skip an attribute
-// this advanced option kills automatic value copying for this attrib_id
-void immSkipAttrib(unsigned attrib_id);
-
-
-// provide one last attribute value & end the current vertex
-// this is most often used for 2D or 3D position (similar to glVertex)
-void immVertex2f(unsigned attrib_id, float x, float y);
-void immVertex3f(unsigned attrib_id, float x, float y, float z);
-
-void immVertex2i(unsigned attrib_id, int x, int y);
-
-void immVertex2s(unsigned attrib_id, short x, short y);
-
-void immVertex2fv(unsigned attrib_id, const float data[2]);
-void immVertex3fv(unsigned attrib_id, const float data[3]);
-
-void immVertex2iv(unsigned attrib_id, const int data[2]);
-
-
-// provide uniform values that don't change for the entire draw call
-void immUniform1i(const char* name, int x);
-void immUniform1f(const char* name, float x);
-void immUniform2f(const char* name, float x, float y);
-void immUniform2fv(const char* name, const float data[2]);
-void immUniform3f(const char* name, float x, float y, float z);
-void immUniform3fv(const char* name, const float data[3]);
-void immUniform4f(const char* name, float x, float y, float z, float w);
-void immUniform4fv(const char* name, const float data[4]);
-void immUniformMat4(const char* name, const float data[4][4]);
-
-
-// convenience functions for setting "uniform vec4 color"
-// the rgb functions have implicit alpha = 1.0
-void immUniformColor4f(float r, float g, float b, float a);
-void immUniformColor4fv(const float rgba[4]);
-void immUniformColor3f(float r, float g, float b);
-void immUniformColor3fv(const float rgb[3]);
-void immUniformColor3fvAlpha(const float rgb[3], float a);
-
-void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b);
-void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
-void immUniformColor3ubv(const unsigned char rgb[3]);
-void immUniformColor4ubv(const unsigned char rgba[4]);
-
-
-// these are called by the system -- not part of drawing API
-
-void immInit(void);
-void immActivate(void);
-void immDeactivate(void);
-void immDestroy(void);
diff --git a/source/blender/gpu/gawain/vertex_buffer.c b/source/blender/gpu/gawain/vertex_buffer.c
deleted file mode 100644
index 827703403e3..00000000000
--- a/source/blender/gpu/gawain/vertex_buffer.c
+++ /dev/null
@@ -1,170 +0,0 @@
-
-// Gawain geometry batch
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "vertex_buffer.h"
-#include "buffer_id.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define KEEP_SINGLE_COPY 1
-
-VertexBuffer* VertexBuffer_create(void)
- {
- VertexBuffer* verts = malloc(sizeof(VertexBuffer));
- VertexBuffer_init(verts);
- return verts;
- }
-
-VertexBuffer* VertexBuffer_create_with_format(const VertexFormat* format)
- {
- VertexBuffer* verts = VertexBuffer_create();
- VertexFormat_copy(&verts->format, format);
- if (!format->packed)
- VertexFormat_pack(&verts->format);
- return verts;
-
- // this function might seem redundant, but there is potential for memory savings here...
- // TODO: implement those memory savings
- }
-
-void VertexBuffer_init(VertexBuffer* verts)
- {
- memset(verts, 0, sizeof(VertexBuffer));
- }
-
-void VertexBuffer_init_with_format(VertexBuffer* verts, const VertexFormat* format)
- {
- VertexBuffer_init(verts);
- VertexFormat_copy(&verts->format, format);
- if (!format->packed)
- VertexFormat_pack(&verts->format);
- }
-
-void VertexBuffer_discard(VertexBuffer* verts)
- {
- if (verts->vbo_id)
- buffer_id_free(verts->vbo_id);
-#if KEEP_SINGLE_COPY
- else
-#endif
- if (verts->data)
- free(verts->data);
-
- free(verts);
- }
-
-unsigned VertexBuffer_size(const VertexBuffer* verts)
- {
- return vertex_buffer_size(&verts->format, verts->vertex_ct);
- }
-
-void VertexBuffer_allocate_data(VertexBuffer* verts, unsigned v_ct)
- {
- VertexFormat* format = &verts->format;
- if (!format->packed)
- VertexFormat_pack(format);
-
- verts->vertex_ct = v_ct;
-
- // Data initially lives in main memory. Will be transferred to VRAM when we "prime" it.
- verts->data = malloc(VertexBuffer_size(verts));
- }
-
-void VertexBuffer_resize_data(VertexBuffer* verts, unsigned v_ct)
- {
-#if TRUST_NO_ONE
- assert(verts->vertex_ct != v_ct); // allow this?
- assert(verts->data != NULL); // has already been allocated
- assert(verts->vbo_id == 0); // has not been sent to VRAM
-#endif
-
- verts->vertex_ct = v_ct;
- verts->data = realloc(verts->data, VertexBuffer_size(verts));
- // TODO: skip realloc if v_ct < existing vertex count
- // extra space will be reclaimed, and never sent to VRAM (see VertexBuffer_prime)
- }
-
-void setAttrib(VertexBuffer* verts, unsigned a_idx, unsigned v_idx, const void* data)
- {
- const VertexFormat* format = &verts->format;
- const Attrib* a = format->attribs + a_idx;
-
-#if TRUST_NO_ONE
- assert(a_idx < format->attrib_ct);
- assert(v_idx < verts->vertex_ct);
- assert(verts->data != NULL); // data must be in main mem
-#endif
-
- memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz);
- }
-
-void fillAttrib(VertexBuffer* verts, unsigned a_idx, const void* data)
- {
- const VertexFormat* format = &verts->format;
- const Attrib* a = format->attribs + a_idx;
-
-#if TRUST_NO_ONE
- assert(a_idx < format->attrib_ct);
-#endif
-
- const unsigned stride = a->sz; // tightly packed input data
-
- fillAttribStride(verts, a_idx, stride, data);
- }
-
-void fillAttribStride(VertexBuffer* verts, unsigned a_idx, unsigned stride, const void* data)
- {
- const VertexFormat* format = &verts->format;
- const Attrib* a = format->attribs + a_idx;
-
-#if TRUST_NO_ONE
- assert(a_idx < format->attrib_ct);
- assert(verts->data != NULL); // data must be in main mem
-#endif
-
- const unsigned vertex_ct = verts->vertex_ct;
-
- if (format->attrib_ct == 1 && stride == format->stride)
- {
- // we can copy it all at once
- memcpy(verts->data, data, vertex_ct * a->sz);
- }
- else
- {
- // we must copy it per vertex
- for (unsigned v = 0; v < vertex_ct; ++v)
- memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz);
- }
- }
-
-static void VertexBuffer_prime(VertexBuffer* verts)
- {
- const VertexFormat* format = &verts->format;
-
- verts->vbo_id = buffer_id_alloc();
- glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
- // fill with delicious data & send to GPU the first time only
- glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size(format, verts->vertex_ct), verts->data, GL_STATIC_DRAW);
-
-#if KEEP_SINGLE_COPY
- // now that GL has a copy, discard original
- free(verts->data);
- verts->data = NULL;
-#endif
- }
-
-void VertexBuffer_use(VertexBuffer* verts)
- {
- if (verts->vbo_id)
- glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
- else
- VertexBuffer_prime(verts);
- }
diff --git a/source/blender/gpu/gawain/vertex_buffer.h b/source/blender/gpu/gawain/vertex_buffer.h
deleted file mode 100644
index 6a72cfe6ff3..00000000000
--- a/source/blender/gpu/gawain/vertex_buffer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-// Gawain geometry batch
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-#include "vertex_format.h"
-
-// How to create a VertexBuffer:
-// 1) verts = create_VertexBuffer() or init_VertexBuffer(verts)
-// 2) add_attrib(verts->format, ...)
-// 3) allocate_vertex_data(verts, vertex_ct) <-- finalizes/packs vertex format
-// 4) fillAttrib(verts, pos, application_pos_buffer)
-// 5) prime_VertexBuffer(verts);
-
-// Is VertexBuffer always used as part of a Batch?
-
-typedef struct {
- VertexFormat format;
- unsigned vertex_ct;
- GLubyte* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
- GLuint vbo_id; // 0 indicates not yet sent to VRAM
-} VertexBuffer;
-
-VertexBuffer* VertexBuffer_create(void);
-VertexBuffer* VertexBuffer_create_with_format(const VertexFormat*);
-
-void VertexBuffer_discard(VertexBuffer*);
-
-void VertexBuffer_init(VertexBuffer*);
-void VertexBuffer_init_with_format(VertexBuffer*, const VertexFormat*);
-
-unsigned VertexBuffer_size(const VertexBuffer*);
-void VertexBuffer_allocate_data(VertexBuffer*, unsigned v_ct);
-void VertexBuffer_resize_data(VertexBuffer*, unsigned v_ct);
-
-// The most important setAttrib variant is the untyped one. Get it right first.
-// It takes a void* so the app developer is responsible for matching their app data types
-// to the vertex attribute's type and component count. They're in control of both, so this
-// should not be a problem.
-
-void setAttrib(VertexBuffer*, unsigned a_idx, unsigned v_idx, const void* data);
-void fillAttrib(VertexBuffer*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data
-void fillAttribStride(VertexBuffer*, unsigned a_idx, unsigned stride, const void* data);
-
-// TODO: decide whether to keep the functions below
-// doesn't immediate mode satisfy these needs?
-
-// void setAttrib1f(unsigned a_idx, unsigned v_idx, float x);
-// void setAttrib2f(unsigned a_idx, unsigned v_idx, float x, float y);
-// void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z);
-// void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w);
-//
-// void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b);
-// void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
-
-void VertexBuffer_use(VertexBuffer*);
diff --git a/source/blender/gpu/gawain/vertex_format.c b/source/blender/gpu/gawain/vertex_format.c
deleted file mode 100644
index 671b979a810..00000000000
--- a/source/blender/gpu/gawain/vertex_format.c
+++ /dev/null
@@ -1,246 +0,0 @@
-
-// Gawain vertex format
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#include "vertex_format.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define PACK_DEBUG 0
-
-#if PACK_DEBUG
- #include <stdio.h>
-#endif
-
-void VertexFormat_clear(VertexFormat* format)
- {
-#if TRUST_NO_ONE
- memset(format, 0, sizeof(VertexFormat));
-#else
- format->attrib_ct = 0;
- format->packed = false;
- format->name_offset = 0;
-#endif
- }
-
-void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src)
- {
- // copy regular struct fields
- memcpy(dest, src, sizeof(VertexFormat));
- }
-
-static unsigned comp_sz(VertexCompType type)
- {
-#if TRUST_NO_ONE
- assert(type >= GL_BYTE && type <= GL_FLOAT);
-#endif
-
- const GLubyte sizes[] = {1,1,2,2,4,4,4};
- return sizes[type - GL_BYTE];
- }
-
-static unsigned attrib_sz(const Attrib *a)
- {
-#if USE_10_10_10
- if (a->comp_type == COMP_I10)
- return 4; // always packed as 10_10_10_2
-#endif
-
- return a->comp_ct * comp_sz(a->comp_type);
- }
-
-static unsigned attrib_align(const Attrib *a)
- {
-#if USE_10_10_10
- if (a->comp_type == COMP_I10)
- return 4; // always packed as 10_10_10_2
-#endif
-
- unsigned c = comp_sz(a->comp_type);
- if (a->comp_ct == 3 && c <= 2)
- return 4 * c; // AMD HW can't fetch these well, so pad it out (other vendors too?)
- else
- return c; // most fetches are ok if components are naturally aligned
- }
-
-unsigned vertex_buffer_size(const VertexFormat* format, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(format->packed && format->stride > 0);
-#endif
-
- return format->stride * vertex_ct;
- }
-
-static const char* copy_attrib_name(VertexFormat* format, const char* name)
- {
- // strncpy does 110% of what we need; let's do exactly 100%
- char* name_copy = format->names + format->name_offset;
- unsigned available = VERTEX_ATTRIB_NAMES_BUFFER_LEN - format->name_offset;
- bool terminated = false;
-
- for (unsigned i = 0; i < available; ++i)
- {
- const char c = name[i];
- name_copy[i] = c;
- if (c == '\0')
- {
- terminated = true;
- format->name_offset += (i + 1);
- break;
- }
- }
-
-#if TRUST_NO_ONE
- assert(terminated);
- assert(format->name_offset <= VERTEX_ATTRIB_NAMES_BUFFER_LEN);
-#endif
-
- return name_copy;
- }
-
-unsigned add_attrib(VertexFormat* format, const char* name, VertexCompType comp_type, unsigned comp_ct, VertexFetchMode fetch_mode)
- {
-#if TRUST_NO_ONE
- assert(format->attrib_ct < MAX_VERTEX_ATTRIBS); // there's room for more
- assert(!format->packed); // packed means frozen/locked
- assert(comp_ct >= 1 && comp_ct <= 4);
- switch (comp_type)
- {
- case COMP_F32:
- // float type can only kept as float
- assert(fetch_mode == KEEP_FLOAT);
- break;
- #if USE_10_10_10
- case COMP_I10:
- assert(comp_ct == 3); // 10_10_10 format intended for normals (xyz) or colors (rgb)
- assert(fetch_mode == NORMALIZE_INT_TO_FLOAT);
- break;
- #endif
- default:
- // integer types can be kept as int or converted/normalized to float
- assert(fetch_mode != KEEP_FLOAT);
- }
-#endif
-
- const unsigned attrib_id = format->attrib_ct++;
- Attrib* attrib = format->attribs + attrib_id;
-
- attrib->name = copy_attrib_name(format, name);
- attrib->comp_type = comp_type;
-#if USE_10_10_10
- attrib->comp_ct = (comp_type == COMP_I10) ? 4 : comp_ct; // system needs 10_10_10_2 to be 4 or BGRA
-#else
- attrib->comp_ct = comp_ct;
-#endif
- attrib->sz = attrib_sz(attrib);
- attrib->offset = 0; // offsets & stride are calculated later (during pack)
- attrib->fetch_mode = fetch_mode;
-
- return attrib_id;
- }
-
-unsigned padding(unsigned offset, unsigned alignment)
- {
- const unsigned mod = offset % alignment;
- return (mod == 0) ? 0 : (alignment - mod);
- }
-
-#if PACK_DEBUG
-static void show_pack(unsigned a_idx, unsigned sz, unsigned pad)
- {
- const char c = 'A' + a_idx;
- for (unsigned i = 0; i < pad; ++i)
- putchar('-');
- for (unsigned i = 0; i < sz; ++i)
- putchar(c);
- }
-#endif
-
-void VertexFormat_pack(VertexFormat* format)
- {
- // for now, attributes are packed in the order they were added,
- // making sure each attrib is naturally aligned (add padding where necessary)
-
- // later we can implement more efficient packing w/ reordering
- // (keep attrib ID order, adjust their offsets to reorder in buffer)
-
- // TODO:
- // realloc just enough to hold the final combo string. And just enough to
- // hold used attribs, not all 16.
-
- Attrib* a0 = format->attribs + 0;
- a0->offset = 0;
- unsigned offset = a0->sz;
-
-#if PACK_DEBUG
- show_pack(0, a0->sz, 0);
-#endif
-
- for (unsigned a_idx = 1; a_idx < format->attrib_ct; ++a_idx)
- {
- Attrib* a = format->attribs + a_idx;
- unsigned mid_padding = padding(offset, attrib_align(a));
- offset += mid_padding;
- a->offset = offset;
- offset += a->sz;
-
-#if PACK_DEBUG
- show_pack(a_idx, a->sz, mid_padding);
-#endif
- }
-
- unsigned end_padding = padding(offset, attrib_align(a0));
-
-#if PACK_DEBUG
- show_pack(0, 0, end_padding);
- putchar('\n');
-#endif
-
- format->stride = offset + end_padding;
- format->packed = true;
- }
-
-
-#if USE_10_10_10
-
-// OpenGL ES packs in a different order as desktop GL but component conversion is the same.
-// Of the code here, only struct PackedNormal needs to change.
-
-#define SIGNED_INT_10_MAX 511
-#define SIGNED_INT_10_MIN -512
-
-static int clampi(int x, int min_allowed, int max_allowed)
- {
-#if TRUST_NO_ONE
- assert(min_allowed <= max_allowed);
-#endif
-
- if (x < min_allowed)
- return min_allowed;
- else if (x > max_allowed)
- return max_allowed;
- else
- return x;
- }
-
-static int quantize(float x)
- {
- int qx = x * 511.0f;
- return clampi(qx, SIGNED_INT_10_MIN, SIGNED_INT_10_MAX);
- }
-
-PackedNormal convert_i10_v3(const float data[3])
- {
- PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) };
- return n;
- }
-
-#endif // USE_10_10_10
diff --git a/source/blender/gpu/gawain/vertex_format.h b/source/blender/gpu/gawain/vertex_format.h
deleted file mode 100644
index 66477b0cfc7..00000000000
--- a/source/blender/gpu/gawain/vertex_format.h
+++ /dev/null
@@ -1,87 +0,0 @@
-
-// Gawain vertex format
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-#pragma once
-
-#include "common.h"
-
-#define MAX_VERTEX_ATTRIBS 16
-#define AVG_VERTEX_ATTRIB_NAME_LEN 5
-#define VERTEX_ATTRIB_NAMES_BUFFER_LEN ((AVG_VERTEX_ATTRIB_NAME_LEN + 1) * MAX_VERTEX_ATTRIBS)
-
-#define USE_10_10_10 defined(_WIN32)
-// (GLEW_VERSION_3_3 || GLEW_ARB_vertex_type_2_10_10_10_rev)
-// ^-- this is only guaranteed on Windows right now, will be true on all platforms soon
-
-typedef enum {
- COMP_I8 = GL_BYTE,
- COMP_U8 = GL_UNSIGNED_BYTE,
- COMP_I16 = GL_SHORT,
- COMP_U16 = GL_UNSIGNED_SHORT,
- COMP_I32 = GL_INT,
- COMP_U32 = GL_UNSIGNED_INT,
-
- COMP_F32 = GL_FLOAT, // TODO: drop the GL_ equivalence here, use a private lookup table
-
-#if USE_10_10_10
- COMP_I10 = GL_INT_2_10_10_10_REV
-#endif
-} VertexCompType;
-
-typedef enum {
- KEEP_FLOAT,
- KEEP_INT,
- NORMALIZE_INT_TO_FLOAT, // 127 (ubyte) -> 0.5 (and so on for other int types)
- CONVERT_INT_TO_FLOAT // 127 (any int type) -> 127.0
-} VertexFetchMode;
-
-typedef struct {
- VertexCompType comp_type;
- unsigned comp_ct; // 1 to 4
- unsigned sz; // size in bytes, 1 to 16
- unsigned offset; // from beginning of vertex, in bytes
- VertexFetchMode fetch_mode;
- const char* name;
-} Attrib;
-
-typedef struct {
- unsigned attrib_ct; // 0 to 16 (MAX_VERTEX_ATTRIBS)
- unsigned stride; // stride in bytes, 1 to 256
- bool packed;
- Attrib attribs[MAX_VERTEX_ATTRIBS]; // TODO: variable-size attribs array
- char names[VERTEX_ATTRIB_NAMES_BUFFER_LEN];
- unsigned name_offset;
-} VertexFormat;
-
-void VertexFormat_clear(VertexFormat*);
-void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src);
-
-unsigned add_attrib(VertexFormat*, const char* name, VertexCompType, unsigned comp_ct, VertexFetchMode);
-
-// format conversion
-
-#if USE_10_10_10
-
-typedef struct {
- int x : 10;
- int y : 10;
- int z : 10;
- int w : 2; // ignored for our purposes
-} PackedNormal;
-
-PackedNormal convert_i10_v3(const float data[3]);
-
-#endif // USE_10_10_10
-
-// for internal use
-void VertexFormat_pack(VertexFormat*);
-unsigned padding(unsigned offset, unsigned alignment);
-unsigned vertex_buffer_size(const VertexFormat*, unsigned vertex_ct);
diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c
index 757982d1b30..960181df545 100644
--- a/source/blender/gpu/intern/gpu_basic_shader.c
+++ b/source/blender/gpu/intern/gpu_basic_shader.c
@@ -159,24 +159,6 @@ const GLubyte stipple_hexagon[128] = {
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22};
/* ********************************************* */
-/* GLSL State */
-
-static bool USE_GLSL = true;
-
-/**
- * \note this isn't part of the basic shader API,
- * only set from the command line once on startup.
- */
-void GPU_basic_shader_use_glsl_set(bool enabled)
-{
- USE_GLSL = enabled;
-}
-
-bool GPU_basic_shader_use_glsl_get(void)
-{
- return USE_GLSL;
-}
-
/* Init / exit */
void GPU_basic_shaders_init(void)
@@ -312,85 +294,16 @@ static void GPU_basic_shader_uniform_autoset(GPUShader *shader, int options)
void GPU_basic_shader_bind(int options)
{
- if (USE_GLSL) {
- if (options) {
- GPUShader *shader = gpu_basic_shader(options);
+ if (options) {
+ GPUShader *shader = gpu_basic_shader(options);
- if (shader) {
- GPU_shader_bind(shader);
- GPU_basic_shader_uniform_autoset(shader, options);
- }
- }
- else {
- GPU_shader_unbind();
+ if (shader) {
+ GPU_shader_bind(shader);
+ GPU_basic_shader_uniform_autoset(shader, options);
}
}
else {
- const int bound_options = GPU_MATERIAL_STATE.bound_options;
-
- if (options & GPU_SHADER_LIGHTING) {
- glEnable(GL_LIGHTING);
-
- if (options & GPU_SHADER_USE_COLOR)
- glEnable(GL_COLOR_MATERIAL);
- else
- glDisable(GL_COLOR_MATERIAL);
-
- if (options & GPU_SHADER_TWO_SIDED)
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
- else
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
- }
- else if (bound_options & GPU_SHADER_LIGHTING) {
- glDisable(GL_LIGHTING);
- glDisable(GL_COLOR_MATERIAL);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
- }
-
- if (options & GPU_SHADER_TEXTURE_2D) {
- GLint env_mode = (options & (GPU_SHADER_USE_COLOR | GPU_SHADER_LIGHTING)) ? GL_MODULATE : GL_REPLACE;
- glEnable(GL_TEXTURE_2D);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env_mode);
- }
- else if (bound_options & GPU_SHADER_TEXTURE_2D) {
- if ((options & GPU_SHADER_TEXTURE_RECT) == 0) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- glDisable(GL_TEXTURE_2D);
- }
-
- if (options & GPU_SHADER_TEXTURE_RECT) {
- GLint env_mode = (options & (GPU_SHADER_USE_COLOR | GPU_SHADER_LIGHTING)) ? GL_MODULATE : GL_REPLACE;
- glEnable(GL_TEXTURE_RECTANGLE);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env_mode);
- }
- else if (bound_options & GPU_SHADER_TEXTURE_RECT) {
- if ((options & GPU_SHADER_TEXTURE_2D) == 0) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- glDisable(GL_TEXTURE_RECTANGLE);
- }
-
- if ((options & GPU_SHADER_LINE) && (options & GPU_SHADER_STIPPLE)) {
- glEnable(GL_LINE_STIPPLE);
- }
- else if ((bound_options & GPU_SHADER_LINE) && (bound_options & GPU_SHADER_STIPPLE)) {
- glDisable(GL_LINE_STIPPLE);
- }
-
- if (((options & GPU_SHADER_LINE) == 0) && (options & GPU_SHADER_STIPPLE)) {
- glEnable(GL_POLYGON_STIPPLE);
- }
- else if (((bound_options & GPU_SHADER_LINE) == 0) && (bound_options & GPU_SHADER_STIPPLE)) {
- glDisable(GL_POLYGON_STIPPLE);
- }
-
- if (options & GPU_SHADER_FLAT_NORMAL) {
- glShadeModel(GL_FLAT);
- }
- else if (bound_options & GPU_SHADER_FLAT_NORMAL) {
- glShadeModel(GL_SMOOTH);
- }
+ GPU_shader_unbind();
}
GPU_MATERIAL_STATE.bound_options = options;
@@ -500,14 +413,12 @@ void GPU_basic_shader_light_set(int light_num, GPULightData *light)
}
else {
/* TODO(sergey): Needs revisit. */
- if (USE_GLSL || true) {
- /* glsl shader needs these zero to skip them */
- const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ /* glsl shader needs these zero to skip them */
+ const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- glLightfv(GL_LIGHT0 + light_num, GL_POSITION, zero);
- glLightfv(GL_LIGHT0 + light_num, GL_DIFFUSE, zero);
- glLightfv(GL_LIGHT0 + light_num, GL_SPECULAR, zero);
- }
+ glLightfv(GL_LIGHT0 + light_num, GL_POSITION, zero);
+ glLightfv(GL_LIGHT0 + light_num, GL_DIFFUSE, zero);
+ glLightfv(GL_LIGHT0 + light_num, GL_SPECULAR, zero);
glDisable(GL_LIGHT0 + light_num);
}
@@ -520,56 +431,19 @@ void GPU_basic_shader_light_set_viewer(bool local)
void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id)
{
- if (USE_GLSL) {
- glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_id"), stipple_id);
- }
- else {
- switch (stipple_id) {
- case GPU_SHADER_STIPPLE_HALFTONE:
- glPolygonStipple(stipple_halftone);
- return;
- case GPU_SHADER_STIPPLE_QUARTTONE:
- glPolygonStipple(stipple_quarttone);
- return;
- case GPU_SHADER_STIPPLE_CHECKER_8PX:
- glPolygonStipple(stipple_checker_8px);
- return;
- case GPU_SHADER_STIPPLE_HEXAGON:
- glPolygonStipple(stipple_hexagon);
- return;
- case GPU_SHADER_STIPPLE_DIAG_STRIPES_SWAP:
- glPolygonStipple(stipple_diag_stripes_neg);
- return;
- case GPU_SHADER_STIPPLE_DIAG_STRIPES:
- glPolygonStipple(stipple_diag_stripes_pos);
- return;
- default:
- glPolygonStipple(stipple_hexagon);
- return;
- }
- }
+ glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_id"), stipple_id);
}
void GPU_basic_shader_line_width(float line_width)
{
- if (USE_GLSL) {
- GPU_MATERIAL_STATE.line_width = line_width;
- if (GPU_MATERIAL_STATE.bound_options & GPU_SHADER_LINE) {
- glUniform1f(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "line_width"), line_width);
- }
- }
- else {
- glLineWidth(line_width);
+ GPU_MATERIAL_STATE.line_width = line_width;
+ if (GPU_MATERIAL_STATE.bound_options & GPU_SHADER_LINE) {
+ glUniform1f(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "line_width"), line_width);
}
}
void GPU_basic_shader_line_stipple(GLint stipple_factor, GLushort stipple_pattern)
{
- if (USE_GLSL) {
- glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_factor"), stipple_factor);
- glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_pattern"), stipple_pattern);
- }
- else {
- glLineStipple(stipple_factor, stipple_pattern);
- }
+ glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_factor"), stipple_factor);
+ glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_pattern"), stipple_pattern);
}
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 716c5e55b3c..65a827febde 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -31,7 +31,7 @@
#include "GPU_batch.h"
#include "gpu_shader_private.h"
-void Batch_set_builtin_program(Batch* batch, GPUBuiltinShader shader_id)
+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);
@@ -40,6 +40,8 @@ void Batch_set_builtin_program(Batch* batch, GPUBuiltinShader shader_id)
static Batch *sphere_high = NULL;
static Batch *sphere_med = NULL;
static Batch *sphere_low = NULL;
+static Batch *sphere_wire_low = NULL;
+static Batch *sphere_wire_med = NULL;
static VertexBuffer *vbo;
static VertexFormat format = {0};
@@ -70,23 +72,23 @@ static Batch *batch_sphere(int lat_res, int lon_res)
}
vbo = VertexBuffer_create_with_format(&format);
- VertexBuffer_allocate_data(vbo, (lat_res-1) * lon_res * 6);
+ 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) {
+ 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) {
+ 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);
+ 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);
- batch_sphere_lat_lon_vert(lat+lat_inc, lon+lon_inc);
- batch_sphere_lat_lon_vert(lat, lon+lon_inc);
+ 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);
}
}
}
@@ -94,6 +96,38 @@ static Batch *batch_sphere(int lat_res, int lon_res)
return Batch_create(GL_TRIANGLES, vbo, NULL);
}
+static 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 = 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 * 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 Batch_create(GL_LINES, vbo, NULL);
+}
+
Batch *Batch_get_sphere(int lod)
{
BLI_assert(lod >= 0 && lod <= 2);
@@ -106,12 +140,25 @@ Batch *Batch_get_sphere(int lod)
return sphere_high;
}
+Batch *Batch_get_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, 8);
+ 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)
@@ -119,4 +166,6 @@ void gpu_batch_exit(void)
Batch_discard_all(sphere_low);
Batch_discard_all(sphere_med);
Batch_discard_all(sphere_high);
+ Batch_discard_all(sphere_wire_low);
+ Batch_discard_all(sphere_wire_med);
}
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 370841327aa..6492cf90929 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -56,6 +56,7 @@
#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_basic_shader.h"
+#include "GPU_immediate.h"
#include "bmesh.h"
@@ -2033,59 +2034,57 @@ void GPU_free_pbvh_buffer_multires(GridCommonGPUBuffer **grid_common_gpu_buffer)
}
/* debug function, draws the pbvh BB */
-void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
+void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf, unsigned int pos)
{
- const float quads[4][4][3] = {
- {
- {min[0], min[1], min[2]},
- {max[0], min[1], min[2]},
- {max[0], min[1], max[2]},
- {min[0], min[1], max[2]}
- },
-
- {
- {min[0], min[1], min[2]},
- {min[0], max[1], min[2]},
- {min[0], max[1], max[2]},
- {min[0], min[1], max[2]}
- },
-
- {
- {max[0], max[1], min[2]},
- {max[0], min[1], min[2]},
- {max[0], min[1], max[2]},
- {max[0], max[1], max[2]}
- },
-
- {
- {max[0], max[1], min[2]},
- {min[0], max[1], min[2]},
- {min[0], max[1], max[2]},
- {max[0], max[1], max[2]}
- },
- };
-
if (leaf)
- glColor4f(0.0, 1.0, 0.0, 0.5);
+ immUniformColor4f(0.0, 1.0, 0.0, 0.5);
else
- glColor4f(1.0, 0.0, 0.0, 0.5);
+ immUniformColor4f(1.0, 0.0, 0.0, 0.5);
- glVertexPointer(3, GL_FLOAT, 0, &quads[0][0][0]);
- glDrawArrays(GL_QUADS, 0, 16);
-}
+ /* TODO(merwin): revisit this after we have mutable VertexBuffers
+ * could keep a static batch & index buffer, change the VBO contents per draw
+ */
-void GPU_init_draw_pbvh_BB(void)
-{
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_CULL_FACE);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glEnable(GL_BLEND);
-}
+ immBegin(PRIM_LINES, 24);
-void GPU_end_draw_pbvh_BB(void)
-{
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glPopAttrib();
+ /* top */
+ immVertex3f(pos, min[0], min[1], max[2]);
+ immVertex3f(pos, min[0], max[1], max[2]);
+
+ immVertex3f(pos, min[0], max[1], max[2]);
+ immVertex3f(pos, max[0], max[1], max[2]);
+
+ immVertex3f(pos, max[0], max[1], max[2]);
+ immVertex3f(pos, max[0], min[1], max[2]);
+
+ immVertex3f(pos, max[0], min[1], max[2]);
+ immVertex3f(pos, min[0], min[1], max[2]);
+
+ /* bottom */
+ immVertex3f(pos, min[0], min[1], min[2]);
+ immVertex3f(pos, min[0], max[1], min[2]);
+
+ immVertex3f(pos, min[0], max[1], min[2]);
+ immVertex3f(pos, max[0], max[1], min[2]);
+
+ immVertex3f(pos, max[0], max[1], min[2]);
+ immVertex3f(pos, max[0], min[1], min[2]);
+
+ immVertex3f(pos, max[0], min[1], min[2]);
+ immVertex3f(pos, min[0], min[1], min[2]);
+
+ /* sides */
+ immVertex3f(pos, min[0], min[1], min[2]);
+ immVertex3f(pos, min[0], min[1], max[2]);
+
+ immVertex3f(pos, min[0], max[1], min[2]);
+ immVertex3f(pos, min[0], max[1], max[2]);
+
+ immVertex3f(pos, max[0], max[1], min[2]);
+ immVertex3f(pos, max[0], max[1], max[2]);
+
+ immVertex3f(pos, max[0], min[1], min[2]);
+ immVertex3f(pos, max[0], min[1], max[2]);
+
+ immEnd();
}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 4223ec54f74..df3b6f962e5 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -360,7 +360,7 @@ static void codegen_print_datatype(DynStr *ds, const GPUType type, float *data)
BLI_dynstr_appendf(ds, "%s(", GPU_DATATYPE_STR[type]);
for (i = 0; i < type; i++) {
- BLI_dynstr_appendf(ds, "%f", data[i]);
+ BLI_dynstr_appendf(ds, "%.12f", data[i]);
if (i == type - 1)
BLI_dynstr_append(ds, ")");
else
@@ -653,7 +653,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ");\n");
}
- BLI_dynstr_append(ds, "\n\tgl_FragColor = ");
+ BLI_dynstr_append(ds, "\n\tfragColor = ");
codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
BLI_dynstr_append(ds, ";\n");
}
@@ -788,7 +788,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
#endif
BLI_dynstr_appendf(
- ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n",
+ ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n",
input->attribid, input->attribid);
BLI_dynstr_appendf(
ds, "\tvar%d.w = att%d.w;\n",
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index 528bdefc209..5214b6b1ab7 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -47,6 +47,7 @@
#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "GPU_batch.h"
#include "MEM_guardedalloc.h"
@@ -193,7 +194,8 @@ struct GPUFX {
/* we have a stencil, restore the previous state */
bool restore_stencil;
- unsigned int vbuffer;
+ Batch *quad_batch;
+ Batch *point_batch;
};
#if 0
@@ -269,12 +271,32 @@ GPUFX *GPU_fx_compositor_create(void)
{
GPUFX *fx = MEM_callocN(sizeof(GPUFX), "GPUFX compositor");
- glGenBuffers(1, &fx->vbuffer);
- glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STATIC_DRAW);
- glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(float), fullscreencos);
- glBufferSubData(GL_ARRAY_BUFFER, 8 * sizeof(float), 8 * sizeof(float), fullscreenuvs);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ /* Quad buffer */
+ static VertexFormat format = {0};
+ static unsigned int pos, uvs;
+ if (format.attrib_ct == 0) {
+ pos = add_attrib(&format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
+ uvs = add_attrib(&format, "uvs", GL_FLOAT, 2, KEEP_FLOAT);
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, 4);
+ for (int i = 0; i < 4; ++i) {
+ setAttrib(vbo, pos, i, fullscreencos[i]);
+ setAttrib(vbo, uvs, i, fullscreenuvs[i]);
+ }
+ fx->quad_batch = Batch_create(GL_TRIANGLE_STRIP, vbo, NULL);
+
+ /* Point Buffer */
+ static VertexFormat format_point = {0};
+ static unsigned int dummy_attrib;
+ if (format_point.attrib_ct == 0) {
+ dummy_attrib = add_attrib(&format_point, "pos", GL_FLOAT, 2, KEEP_FLOAT);
+ }
+ float dummy[2] = {0.0f, 0.0f};
+ VertexBuffer *vbo_point = VertexBuffer_create_with_format(&format_point);
+ VertexBuffer_allocate_data(vbo_point, 1);
+ setAttrib(vbo_point, dummy_attrib, 0, &dummy);
+ fx->point_batch = Batch_create(GL_POINTS, vbo_point, NULL);
return fx;
}
@@ -364,7 +386,8 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
void GPU_fx_compositor_destroy(GPUFX *fx)
{
cleanup_fx_gl_data(fx, true);
- glDeleteBuffers(1, &fx->vbuffer);
+ Batch_discard_all(fx->quad_batch);
+ Batch_discard_all(fx->point_batch);
MEM_freeN(fx);
}
@@ -702,19 +725,13 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
/* disable writing to color buffer, it's depth only pass */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- /* set up quad buffer */
- glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
- glVertexPointer(2, GL_FLOAT, 0, NULL);
- glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float)));
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
depth_resolve_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false);
if (depth_resolve_shader) {
- GPUDepthResolveInterface *interface = GPU_shader_get_interface(depth_resolve_shader);
+ GPUDepthResolveInterface *interface = GPU_fx_shader_get_interface(depth_resolve_shader);
- GPU_shader_bind(depth_resolve_shader);
+ /* set up quad buffer */
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(depth_resolve_shader));
GPU_texture_bind(fx->depth_buffer_xray, 0);
GPU_texture_compare_mode(fx->depth_buffer_xray, false);
@@ -722,7 +739,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
GPU_shader_uniform_texture(depth_resolve_shader, interface->depth_uniform, fx->depth_buffer_xray);
/* draw */
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_compare_mode(fx->depth_buffer_xray, true);
@@ -734,10 +751,6 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
glPopAttrib();
}
@@ -774,13 +787,6 @@ bool GPU_fx_do_composite_pass(
src = fx->color_buffer;
target = fx->color_buffer_sec;
- /* set up quad buffer */
- glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
- glVertexPointer(2, GL_FLOAT, 0, NULL);
- glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float)));
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
/* full screen FX pass */
/* invert the view matrix */
@@ -808,8 +814,6 @@ bool GPU_fx_do_composite_pass(
viewvecs[1][2] = vec_far[2] - viewvecs[0][2];
}
- /* set invalid color in case shader fails */
- glColor3f(1.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
/* ssao pass */
@@ -828,9 +832,9 @@ bool GPU_fx_do_composite_pass(
ssao_params[3] = (passes_left == 1 && !ofs) ? dfdyfac[0] : dfdyfac[1];
- GPUSSAOShaderInterface *interface = GPU_shader_get_interface(ssao_shader);
+ GPUSSAOShaderInterface *interface = GPU_fx_shader_get_interface(ssao_shader);
- GPU_shader_bind(ssao_shader);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(ssao_shader));
GPU_shader_uniform_vector(ssao_shader, interface->ssao_uniform, 4, 1, ssao_params);
GPU_shader_uniform_vector(ssao_shader, interface->ssao_color_uniform, 4, 1, fx_ssao->color);
@@ -854,7 +858,7 @@ bool GPU_fx_do_composite_pass(
/* draw */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(src);
@@ -912,11 +916,8 @@ bool GPU_fx_do_composite_pass(
if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3)) {
GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
GPU_framebuffer_restore();
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GPU_shader_unbind();
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
}
@@ -924,9 +925,9 @@ bool GPU_fx_do_composite_pass(
{
float invrendertargetdim[2] = {1.0f / fx->dof_downsampled_w, 1.0f / fx->dof_downsampled_h};
- GPUDOFHQPassOneInterface *interface = GPU_shader_get_interface(dof_shader_pass1);
+ GPUDOFHQPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1);
- GPU_shader_bind(dof_shader_pass1);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1));
GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -953,7 +954,8 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_check_valid(fx->gbuffer, NULL);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
+
/* disable bindings */
GPU_texture_filter_mode(src, true);
GPU_texture_unbind(src);
@@ -975,19 +977,18 @@ bool GPU_fx_do_composite_pass(
int rendertargetdim[2] = {fx->dof_downsampled_w, fx->dof_downsampled_h};
float selection[2] = {0.0f, 1.0f};
- GPUDOFHQPassTwoInterface *interface = GPU_shader_get_interface(dof_shader_pass2);
+ GPUDOFHQPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2);
- GPU_shader_bind(dof_shader_pass2);
+ Batch_set_program(fx->point_batch, GPU_shader_get_program(dof_shader_pass2));
+
+ GPU_texture_bind(fx->dof_nearfar_coc, numslots++);
+ GPU_texture_bind(fx->dof_half_downsampled_far, numslots++);
+ GPU_texture_bind(fx->dof_half_downsampled_near, numslots++);
GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector_int(dof_shader_pass2, interface->rendertargetdim_uniform, 2, 1, rendertargetdim);
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
-
- GPU_texture_bind(fx->dof_nearfar_coc, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->coc_uniform, fx->dof_nearfar_coc);
-
- GPU_texture_bind(fx->dof_half_downsampled_far, numslots++);
- GPU_texture_bind(fx->dof_half_downsampled_near, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_far);
GPU_texture_filter_mode(fx->dof_half_downsampled_far, false);
@@ -1003,24 +1004,24 @@ bool GPU_fx_do_composite_pass(
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
- glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h);
+ Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL);
GPU_texture_unbind(fx->dof_half_downsampled_far);
GPU_framebuffer_texture_detach(fx->dof_far_blur);
- GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near);
- GPU_texture_filter_mode(fx->dof_half_downsampled_near, false);
-
selection[0] = 1.0f;
selection[1] = 0.0f;
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
+ GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near);
+ GPU_texture_filter_mode(fx->dof_half_downsampled_near, false);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0);
/* have to clear the buffer unfortunately */
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
- glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h);
+ Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL);
+ Batch_done_using_program(fx->point_batch);
/* disable bindings */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -1032,15 +1033,16 @@ bool GPU_fx_do_composite_pass(
GPU_texture_unbind(fx->dof_nearfar_coc);
GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_far_blur);
+ numslots = 0;
}
/* third pass, accumulate the near/far blur fields */
{
float invrendertargetdim[2] = {1.0f / fx->dof_downsampled_w, 1.0f / fx->dof_downsampled_h};
- GPUDOFHQPassThreeInterface *interface = GPU_shader_get_interface(dof_shader_pass3);
+ GPUDOFHQPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3);
- GPU_shader_bind(dof_shader_pass3);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3));
GPU_shader_uniform_vector(dof_shader_pass3, interface->dof_uniform, 4, 1, dof_params);
@@ -1066,7 +1068,7 @@ bool GPU_fx_do_composite_pass(
/* if this is the last pass, prepare for rendering on the frambuffer */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_blur);
@@ -1108,11 +1110,8 @@ bool GPU_fx_do_composite_pass(
if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3 && dof_shader_pass4 && dof_shader_pass5)) {
GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
GPU_framebuffer_restore();
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GPU_shader_unbind();
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
}
@@ -1120,9 +1119,9 @@ bool GPU_fx_do_composite_pass(
{
float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
- GPUDOFPassOneInterface *interface = GPU_shader_get_interface(dof_shader_pass1);
+ GPUDOFPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1);
- GPU_shader_bind(dof_shader_pass1);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1));
GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -1141,7 +1140,7 @@ bool GPU_fx_do_composite_pass(
/* binding takes care of setting the viewport to the downsampled size */
GPU_texture_bind_as_framebuffer(fx->dof_near_coc_buffer);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(src);
GPU_texture_compare_mode(fx->depth_buffer, true);
@@ -1159,12 +1158,12 @@ bool GPU_fx_do_composite_pass(
float tmp = invrendertargetdim[0];
invrendertargetdim[0] = 0.0f;
- GPUDOFPassTwoInterface *interface = GPU_shader_get_interface(dof_shader_pass2);
+ GPUDOFPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2);
dof_params[2] = GPU_texture_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor);
/* Blurring vertically */
- GPU_shader_bind(dof_shader_pass2);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2));
GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass2, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -1182,10 +1181,14 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0);
/* Drawing quad */
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
+
+ /* Rebind Shader */
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2));
/* *unbind/detach */
GPU_texture_unbind(fx->dof_near_coc_buffer);
+
GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer);
/* Blurring horizontally */
@@ -1197,7 +1200,8 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_final_buffer);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ Batch_draw(fx->quad_batch);
/* *unbind/detach */
GPU_texture_compare_mode(fx->depth_buffer, true);
@@ -1214,9 +1218,9 @@ bool GPU_fx_do_composite_pass(
/* third pass, calculate near coc */
{
- GPUDOFPassThreeInterface *interface = GPU_shader_get_interface(dof_shader_pass3);
+ GPUDOFPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3);
- GPU_shader_bind(dof_shader_pass3);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3));
GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_downsampled, fx->dof_near_coc_buffer);
@@ -1226,7 +1230,7 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
@@ -1242,9 +1246,9 @@ bool GPU_fx_do_composite_pass(
float invrendertargetdim[2] = {1.0f / GPU_texture_width(fx->dof_near_coc_blurred_buffer),
1.0f / GPU_texture_height(fx->dof_near_coc_blurred_buffer)};
- GPUDOFPassFourInterface *interface = GPU_shader_get_interface(dof_shader_pass4);
+ GPUDOFPassFourInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass4);
- GPU_shader_bind(dof_shader_pass4);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass4));
GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass4, interface->near_coc_downsampled, fx->dof_near_coc_final_buffer);
@@ -1252,7 +1256,7 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_final_buffer);
@@ -1267,9 +1271,9 @@ bool GPU_fx_do_composite_pass(
{
float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
- GPUDOFPassFiveInterface *interface = GPU_shader_get_interface(dof_shader_pass5);
+ GPUDOFPassFiveInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass5);
- GPU_shader_bind(dof_shader_pass5);
+ Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass5));
GPU_shader_uniform_vector(dof_shader_pass5, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass5, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@@ -1292,7 +1296,7 @@ bool GPU_fx_do_composite_pass(
/* if this is the last pass, prepare for rendering on the frambuffer */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
@@ -1318,10 +1322,6 @@ bool GPU_fx_do_composite_pass(
}
}
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
GPU_shader_unbind();
return true;
@@ -1363,7 +1363,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->ssao_concentric_tex = GPU_shader_get_uniform(shader, "ssao_concentric_tex");
interface->ssao_jitter_uniform = GPU_shader_get_uniform(shader, "jitter_tex");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1377,7 +1377,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1391,7 +1391,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->select_uniform = GPU_shader_get_uniform(shader, "layerselection");
interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1407,7 +1407,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1421,7 +1421,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
@@ -1434,7 +1434,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
@@ -1444,7 +1444,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->near_coc_downsampled = GPU_shader_get_uniform(shader, "colorbuffer");
interface->near_coc_blurred = GPU_shader_get_uniform(shader, "blurredcolorbuffer");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
@@ -1454,7 +1454,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->near_coc_downsampled = GPU_shader_get_uniform(shader, "colorbuffer");
interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
@@ -1469,7 +1469,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
@@ -1479,7 +1479,7 @@ void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect ef
interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer");
- GPU_shader_set_interface(shader, interface);
+ GPU_fx_shader_set_interface(shader, interface);
break;
}
diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.c
index e306394c4c3..eeeb6e0ab33 100644
--- a/source/blender/gpu/intern/gpu_debug.c
+++ b/source/blender/gpu/intern/gpu_debug.c
@@ -20,7 +20,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): Brecht Van Lommel, Jason Wilkins.
+ * Contributor(s): Brecht Van Lommel, Jason Wilkins, Mike Erwin.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -43,19 +43,21 @@
#include <stdlib.h>
#include <string.h>
-/* control whether we use older AMD_debug_output extension, or just the newer extensions
- * TODO(merwin): determine whether all supported GPU + OS combos have newer extensions */
-#define LEGACY_DEBUG 0
+#ifndef __APPLE__ /* only non-Apple systems implement OpenGL debug callbacks */
+
+/* control whether we use older AMD_debug_output extension
+ * some supported GPU + OS combos do not have the newer extensions */
+# define LEGACY_DEBUG 1
/* Debug callbacks need the same calling convention as OpenGL functions. */
-#if defined(_WIN32)
-# define APIENTRY __stdcall
-#else
-# define APIENTRY
-#endif
+# if defined(_WIN32)
+# define APIENTRY __stdcall
+# else
+# define APIENTRY
+# endif
-static const char* source_name(GLenum source)
+static const char *source_name(GLenum source)
{
switch (source) {
case GL_DEBUG_SOURCE_API: return "API";
@@ -68,7 +70,7 @@ static const char* source_name(GLenum source)
}
}
-static const char* message_type_name(GLenum message)
+static const char *message_type_name(GLenum message)
{
switch (message) {
case GL_DEBUG_TYPE_ERROR: return "error";
@@ -105,9 +107,9 @@ static void APIENTRY gpu_debug_proc(
}
}
-#if LEGACY_DEBUG
+# if LEGACY_DEBUG
-static const char* category_name_amd(GLenum category)
+static const char *category_name_amd(GLenum category)
{
switch (category) {
case GL_DEBUG_CATEGORY_API_ERROR_AMD: return "API error";
@@ -143,12 +145,16 @@ static void APIENTRY gpu_debug_proc_amd(
fflush(stderr);
}
}
-#endif /* LEGACY_DEBUG */
+# endif /* LEGACY_DEBUG */
-#undef APIENTRY
+# undef APIENTRY
+#endif /* not Apple */
void gpu_debug_init(void)
{
+#ifdef __APPLE__
+ fprintf(stderr, "OpenGL debug callback is not available on Apple.\n");
+#else /* not Apple */
const char success[] = "Successfully hooked OpenGL debug callback.";
if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
@@ -166,37 +172,43 @@ void gpu_debug_init(void)
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
GPU_string_marker(success);
}
-#if LEGACY_DEBUG
+# if LEGACY_DEBUG
else if (GLEW_AMD_debug_output) {
fprintf(stderr, "Using AMD_debug_output extension\n");
glDebugMessageCallbackAMD(gpu_debug_proc_amd, mxGetCurrentContext());
glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
GPU_string_marker(success);
}
-#endif
+# endif
else {
fprintf(stderr, "Failed to hook OpenGL debug callback.\n");
}
+#endif /* not Apple */
}
void gpu_debug_exit(void)
{
+#ifndef __APPLE__
if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
glDebugMessageCallback(NULL, NULL);
}
else if (GLEW_ARB_debug_output) {
glDebugMessageCallbackARB(NULL, NULL);
}
-#if LEGACY_DEBUG
+# if LEGACY_DEBUG
else if (GLEW_AMD_debug_output) {
glDebugMessageCallbackAMD(NULL, NULL);
}
+# endif
#endif
}
void GPU_string_marker(const char *buf)
{
+#ifdef __APPLE__
+ UNUSED_VARS(buf);
+#else /* not Apple */
if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
glDebugMessageInsert(
GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
@@ -207,13 +219,14 @@ void GPU_string_marker(const char *buf)
GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0,
GL_DEBUG_SEVERITY_LOW_ARB, -1, buf);
}
-#if LEGACY_DEBUG
+# if LEGACY_DEBUG
else if (GLEW_AMD_debug_output) {
glDebugMessageInsertAMD(
GL_DEBUG_CATEGORY_APPLICATION_AMD, GL_DEBUG_SEVERITY_LOW_AMD, 0,
0, buf);
}
-#endif
+# endif
+#endif /* not Apple */
}
void GPU_print_error_debug(const char *str)
@@ -221,390 +234,3 @@ void GPU_print_error_debug(const char *str)
if (G.debug & G_DEBUG)
fprintf(stderr, "GPU: %s\n", str);
}
-
-static void gpu_state_print_fl_ex(const char *name, GLenum type)
-{
- const unsigned char err_mark[4] = {0xff, 0xff, 0xff, 0xff};
-
- float value[32];
- int a;
-
- memset(value, 0xff, sizeof(value));
- glGetFloatv(type, value);
-
- if (glGetError() == GL_NO_ERROR) {
- printf("%s: ", name);
- for (a = 0; a < 32; a++) {
- if (memcmp(&value[a], err_mark, sizeof(value[a])) == 0) {
- break;
- }
- printf("%.2f ", value[a]);
- }
- printf("\n");
- }
-}
-
-#define gpu_state_print_fl(val) gpu_state_print_fl_ex(#val, val)
-
-void GPU_state_print(void)
-{
- /* clear any errors */
- while (glGetError() != GL_NO_ERROR) {}
-
- gpu_state_print_fl(GL_ACCUM_ALPHA_BITS);
- gpu_state_print_fl(GL_ACCUM_BLUE_BITS);
- gpu_state_print_fl(GL_ACCUM_CLEAR_VALUE);
- gpu_state_print_fl(GL_ACCUM_GREEN_BITS);
- gpu_state_print_fl(GL_ACCUM_RED_BITS);
- gpu_state_print_fl(GL_ACTIVE_TEXTURE);
- gpu_state_print_fl(GL_ALIASED_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_ALIASED_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_ALPHA_BIAS);
- gpu_state_print_fl(GL_ALPHA_BITS);
- gpu_state_print_fl(GL_ALPHA_SCALE);
- gpu_state_print_fl(GL_ALPHA_TEST);
- gpu_state_print_fl(GL_ALPHA_TEST_FUNC);
- gpu_state_print_fl(GL_ALPHA_TEST_REF);
- gpu_state_print_fl(GL_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_AUTO_NORMAL);
- gpu_state_print_fl(GL_AUX_BUFFERS);
- gpu_state_print_fl(GL_BLEND);
- gpu_state_print_fl(GL_BLEND_COLOR);
- gpu_state_print_fl(GL_BLEND_DST_ALPHA);
- gpu_state_print_fl(GL_BLEND_DST_RGB);
- gpu_state_print_fl(GL_BLEND_EQUATION_ALPHA);
- gpu_state_print_fl(GL_BLEND_EQUATION_RGB);
- gpu_state_print_fl(GL_BLEND_SRC_ALPHA);
- gpu_state_print_fl(GL_BLEND_SRC_RGB);
- gpu_state_print_fl(GL_BLUE_BIAS);
- gpu_state_print_fl(GL_BLUE_BITS);
- gpu_state_print_fl(GL_BLUE_SCALE);
- gpu_state_print_fl(GL_CLIENT_ACTIVE_TEXTURE);
- gpu_state_print_fl(GL_CLIENT_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_CLIP_PLANE0);
- gpu_state_print_fl(GL_COLOR_ARRAY);
- gpu_state_print_fl(GL_COLOR_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_COLOR_ARRAY_SIZE);
- gpu_state_print_fl(GL_COLOR_ARRAY_STRIDE);
- gpu_state_print_fl(GL_COLOR_ARRAY_TYPE);
- gpu_state_print_fl(GL_COLOR_CLEAR_VALUE);
- gpu_state_print_fl(GL_COLOR_LOGIC_OP);
- gpu_state_print_fl(GL_COLOR_MATERIAL);
- gpu_state_print_fl(GL_COLOR_MATERIAL_FACE);
- gpu_state_print_fl(GL_COLOR_MATERIAL_PARAMETER);
- gpu_state_print_fl(GL_COLOR_MATRIX);
- gpu_state_print_fl(GL_COLOR_MATRIX_STACK_DEPTH);
- gpu_state_print_fl(GL_COLOR_SUM);
- gpu_state_print_fl(GL_COLOR_TABLE);
- gpu_state_print_fl(GL_COLOR_WRITEMASK);
- gpu_state_print_fl(GL_COMPRESSED_TEXTURE_FORMATS);
- gpu_state_print_fl(GL_CONVOLUTION_1D);
- gpu_state_print_fl(GL_CONVOLUTION_2D);
- gpu_state_print_fl(GL_CULL_FACE);
- gpu_state_print_fl(GL_CULL_FACE_MODE);
- gpu_state_print_fl(GL_CURRENT_COLOR);
- gpu_state_print_fl(GL_CURRENT_FOG_COORD);
- gpu_state_print_fl(GL_CURRENT_INDEX);
- gpu_state_print_fl(GL_CURRENT_NORMAL);
- gpu_state_print_fl(GL_CURRENT_PROGRAM);
- gpu_state_print_fl(GL_CURRENT_RASTER_COLOR);
- gpu_state_print_fl(GL_CURRENT_RASTER_DISTANCE);
- gpu_state_print_fl(GL_CURRENT_RASTER_INDEX);
- gpu_state_print_fl(GL_CURRENT_RASTER_POSITION);
- gpu_state_print_fl(GL_CURRENT_RASTER_POSITION_VALID);
- gpu_state_print_fl(GL_CURRENT_RASTER_SECONDARY_COLOR);
- gpu_state_print_fl(GL_CURRENT_RASTER_TEXTURE_COORDS);
- gpu_state_print_fl(GL_CURRENT_SECONDARY_COLOR);
- gpu_state_print_fl(GL_CURRENT_TEXTURE_COORDS);
- gpu_state_print_fl(GL_DEPTH_BIAS);
- gpu_state_print_fl(GL_DEPTH_BITS);
- gpu_state_print_fl(GL_DEPTH_CLEAR_VALUE);
- gpu_state_print_fl(GL_DEPTH_FUNC);
- gpu_state_print_fl(GL_DEPTH_RANGE);
- gpu_state_print_fl(GL_DEPTH_SCALE);
- gpu_state_print_fl(GL_DEPTH_TEST);
- gpu_state_print_fl(GL_DEPTH_WRITEMASK);
- gpu_state_print_fl(GL_DITHER);
- gpu_state_print_fl(GL_DOUBLEBUFFER);
- gpu_state_print_fl(GL_DRAW_BUFFER);
- gpu_state_print_fl(GL_DRAW_BUFFER0);
- gpu_state_print_fl(GL_EDGE_FLAG);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_STRIDE);
- gpu_state_print_fl(GL_ELEMENT_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_FEEDBACK_BUFFER_SIZE);
- gpu_state_print_fl(GL_FEEDBACK_BUFFER_TYPE);
- gpu_state_print_fl(GL_FOG);
- gpu_state_print_fl(GL_FOG_COLOR);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_STRIDE);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_TYPE);
- gpu_state_print_fl(GL_FOG_COORD_SRC);
- gpu_state_print_fl(GL_FOG_DENSITY);
- gpu_state_print_fl(GL_FOG_END);
- gpu_state_print_fl(GL_FOG_HINT);
- gpu_state_print_fl(GL_FOG_INDEX);
- gpu_state_print_fl(GL_FOG_MODE);
- gpu_state_print_fl(GL_FOG_START);
- gpu_state_print_fl(GL_FRAGMENT_PROGRAM_ARB); /* TODO: remove ARB program support */
- gpu_state_print_fl(GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
- gpu_state_print_fl(GL_FRONT_FACE);
- gpu_state_print_fl(GL_GENERATE_MIPMAP_HINT);
- gpu_state_print_fl(GL_GREEN_BIAS);
- gpu_state_print_fl(GL_GREEN_BITS);
- gpu_state_print_fl(GL_GREEN_SCALE);
- gpu_state_print_fl(GL_HISTOGRAM);
- gpu_state_print_fl(GL_INDEX_ARRAY);
- gpu_state_print_fl(GL_INDEX_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_INDEX_ARRAY_STRIDE);
- gpu_state_print_fl(GL_INDEX_ARRAY_TYPE);
- gpu_state_print_fl(GL_INDEX_BITS);
- gpu_state_print_fl(GL_INDEX_CLEAR_VALUE);
- gpu_state_print_fl(GL_INDEX_LOGIC_OP);
- gpu_state_print_fl(GL_INDEX_MODE);
- gpu_state_print_fl(GL_INDEX_OFFSET);
- gpu_state_print_fl(GL_INDEX_SHIFT);
- gpu_state_print_fl(GL_INDEX_WRITEMASK);
- gpu_state_print_fl(GL_LIGHT0);
- gpu_state_print_fl(GL_LIGHT1);
- gpu_state_print_fl(GL_LIGHT2);
- gpu_state_print_fl(GL_LIGHT3);
- gpu_state_print_fl(GL_LIGHT4);
- gpu_state_print_fl(GL_LIGHT5);
- gpu_state_print_fl(GL_LIGHT6);
- gpu_state_print_fl(GL_LIGHT7);
- gpu_state_print_fl(GL_LIGHTING);
- gpu_state_print_fl(GL_LIGHT_MODEL_AMBIENT);
- gpu_state_print_fl(GL_LIGHT_MODEL_COLOR_CONTROL);
- gpu_state_print_fl(GL_LIGHT_MODEL_LOCAL_VIEWER);
- gpu_state_print_fl(GL_LIGHT_MODEL_TWO_SIDE);
- gpu_state_print_fl(GL_LINE_SMOOTH);
- gpu_state_print_fl(GL_LINE_SMOOTH_HINT);
- gpu_state_print_fl(GL_LINE_STIPPLE);
- gpu_state_print_fl(GL_LINE_STIPPLE_PATTERN);
- gpu_state_print_fl(GL_LINE_STIPPLE_REPEAT);
- gpu_state_print_fl(GL_LINE_WIDTH);
- gpu_state_print_fl(GL_LINE_WIDTH_GRANULARITY);
- gpu_state_print_fl(GL_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_LIST_BASE);
- gpu_state_print_fl(GL_LIST_INDEX);
- gpu_state_print_fl(GL_LIST_MODE);
- gpu_state_print_fl(GL_LOGIC_OP);
- gpu_state_print_fl(GL_LOGIC_OP_MODE);
- gpu_state_print_fl(GL_MAP1_COLOR_4);
- gpu_state_print_fl(GL_MAP1_GRID_DOMAIN);
- gpu_state_print_fl(GL_MAP1_GRID_SEGMENTS);
- gpu_state_print_fl(GL_MAP1_INDEX);
- gpu_state_print_fl(GL_MAP1_NORMAL);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_1);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_2);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_3);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_4);
- gpu_state_print_fl(GL_MAP1_VERTEX_3);
- gpu_state_print_fl(GL_MAP1_VERTEX_4);
- gpu_state_print_fl(GL_MAP2_COLOR_4);
- gpu_state_print_fl(GL_MAP2_GRID_DOMAIN);
- gpu_state_print_fl(GL_MAP2_GRID_SEGMENTS);
- gpu_state_print_fl(GL_MAP2_INDEX);
- gpu_state_print_fl(GL_MAP2_NORMAL);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_1);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_2);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_3);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_4);
- gpu_state_print_fl(GL_MAP2_VERTEX_3);
- gpu_state_print_fl(GL_MAP2_VERTEX_4);
- gpu_state_print_fl(GL_MAP_COLOR);
- gpu_state_print_fl(GL_MAP_STENCIL);
- gpu_state_print_fl(GL_MATRIX_MODE);
- gpu_state_print_fl(GL_MAX_3D_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_CLIP_PLANES);
- gpu_state_print_fl(GL_MAX_COLOR_MATRIX_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_DRAW_BUFFERS);
- gpu_state_print_fl(GL_MAX_ELEMENTS_INDICES);
- gpu_state_print_fl(GL_MAX_ELEMENTS_VERTICES);
- gpu_state_print_fl(GL_MAX_EVAL_ORDER);
- gpu_state_print_fl(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
- gpu_state_print_fl(GL_MAX_LIGHTS);
- gpu_state_print_fl(GL_MAX_LIST_NESTING);
- gpu_state_print_fl(GL_MAX_MODELVIEW_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_NAME_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_PIXEL_MAP_TABLE);
- gpu_state_print_fl(GL_MAX_PROJECTION_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_TEXTURE_COORDS);
- gpu_state_print_fl(GL_MAX_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_TEXTURE_LOD_BIAS);
- gpu_state_print_fl(GL_MAX_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_TEXTURE_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_TEXTURE_UNITS);
- gpu_state_print_fl(GL_MAX_VARYING_FLOATS);
- gpu_state_print_fl(GL_MAX_VERTEX_ATTRIBS);
- gpu_state_print_fl(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
- gpu_state_print_fl(GL_MAX_VIEWPORT_DIMS);
- gpu_state_print_fl(GL_MINMAX);
- gpu_state_print_fl(GL_MODELVIEW_MATRIX);
- gpu_state_print_fl(GL_MODELVIEW_STACK_DEPTH);
- gpu_state_print_fl(GL_MULTISAMPLE);
- gpu_state_print_fl(GL_NAME_STACK_DEPTH);
- gpu_state_print_fl(GL_NORMALIZE);
- gpu_state_print_fl(GL_NORMAL_ARRAY);
- gpu_state_print_fl(GL_NORMAL_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_NORMAL_ARRAY_STRIDE);
- gpu_state_print_fl(GL_NORMAL_ARRAY_TYPE);
- gpu_state_print_fl(GL_NUM_COMPRESSED_TEXTURE_FORMATS);
- gpu_state_print_fl(GL_PACK_ALIGNMENT);
- gpu_state_print_fl(GL_PACK_IMAGE_HEIGHT);
- gpu_state_print_fl(GL_PACK_LSB_FIRST);
- gpu_state_print_fl(GL_PACK_ROW_LENGTH);
- gpu_state_print_fl(GL_PACK_SKIP_IMAGES);
- gpu_state_print_fl(GL_PACK_SKIP_PIXELS);
- gpu_state_print_fl(GL_PACK_SKIP_ROWS);
- gpu_state_print_fl(GL_PACK_SWAP_BYTES);
- gpu_state_print_fl(GL_PERSPECTIVE_CORRECTION_HINT);
- gpu_state_print_fl(GL_PIXEL_MAP_A_TO_A_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_B_TO_B_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_G_TO_G_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_A_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_B_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_G_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_I_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_R_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_R_TO_R_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_S_TO_S_SIZE);
- gpu_state_print_fl(GL_PIXEL_PACK_BUFFER_BINDING);
- gpu_state_print_fl(GL_PIXEL_UNPACK_BUFFER_BINDING);
- gpu_state_print_fl(GL_POINT_DISTANCE_ATTENUATION);
- gpu_state_print_fl(GL_POINT_FADE_THRESHOLD_SIZE);
- gpu_state_print_fl(GL_POINT_SIZE);
- gpu_state_print_fl(GL_POINT_SIZE_GRANULARITY);
- gpu_state_print_fl(GL_POINT_SIZE_MAX);
- gpu_state_print_fl(GL_POINT_SIZE_MIN);
- gpu_state_print_fl(GL_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_POINT_SMOOTH);
- gpu_state_print_fl(GL_POINT_SMOOTH_HINT);
- gpu_state_print_fl(GL_POINT_SPRITE);
- gpu_state_print_fl(GL_POLYGON_MODE);
- gpu_state_print_fl(GL_POLYGON_OFFSET_FACTOR);
- gpu_state_print_fl(GL_POLYGON_OFFSET_FILL);
- gpu_state_print_fl(GL_POLYGON_OFFSET_LINE);
- gpu_state_print_fl(GL_POLYGON_OFFSET_POINT);
- gpu_state_print_fl(GL_POLYGON_OFFSET_UNITS);
- gpu_state_print_fl(GL_POLYGON_SMOOTH);
- gpu_state_print_fl(GL_POLYGON_SMOOTH_HINT);
- gpu_state_print_fl(GL_POLYGON_STIPPLE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_COLOR_TABLE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_COLOR_TABLE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_RED_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_RED_SCALE);
- gpu_state_print_fl(GL_PROJECTION_MATRIX);
- gpu_state_print_fl(GL_PROJECTION_STACK_DEPTH);
- gpu_state_print_fl(GL_READ_BUFFER);
- gpu_state_print_fl(GL_RED_BIAS);
- gpu_state_print_fl(GL_RED_BITS);
- gpu_state_print_fl(GL_RED_SCALE);
- gpu_state_print_fl(GL_RENDER_MODE);
- gpu_state_print_fl(GL_RESCALE_NORMAL);
- gpu_state_print_fl(GL_RGBA_MODE);
- gpu_state_print_fl(GL_SAMPLES);
- gpu_state_print_fl(GL_SAMPLE_BUFFERS);
- gpu_state_print_fl(GL_SAMPLE_COVERAGE_INVERT);
- gpu_state_print_fl(GL_SAMPLE_COVERAGE_VALUE);
- gpu_state_print_fl(GL_SCISSOR_BOX);
- gpu_state_print_fl(GL_SCISSOR_TEST);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_SIZE);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_STRIDE);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_TYPE);
- gpu_state_print_fl(GL_SELECTION_BUFFER_SIZE);
- gpu_state_print_fl(GL_SEPARABLE_2D);
- gpu_state_print_fl(GL_SHADE_MODEL);
- gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_GRANULARITY);
- gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_GRANULARITY);
- gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_STENCIL_BACK_FAIL);
- gpu_state_print_fl(GL_STENCIL_BACK_FUNC);
- gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_FAIL);
- gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_PASS);
- gpu_state_print_fl(GL_STENCIL_BACK_REF);
- gpu_state_print_fl(GL_STENCIL_BACK_VALUE_MASK);
- gpu_state_print_fl(GL_STENCIL_BACK_WRITEMASK);
- gpu_state_print_fl(GL_STENCIL_BITS);
- gpu_state_print_fl(GL_STENCIL_CLEAR_VALUE);
- gpu_state_print_fl(GL_STENCIL_FAIL);
- gpu_state_print_fl(GL_STENCIL_FUNC);
- gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_FAIL);
- gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_PASS);
- gpu_state_print_fl(GL_STENCIL_REF);
- gpu_state_print_fl(GL_STENCIL_TEST);
- gpu_state_print_fl(GL_STENCIL_VALUE_MASK);
- gpu_state_print_fl(GL_STENCIL_WRITEMASK);
- gpu_state_print_fl(GL_STEREO);
- gpu_state_print_fl(GL_SUBPIXEL_BITS);
- gpu_state_print_fl(GL_TEXTURE_1D);
- gpu_state_print_fl(GL_TEXTURE_2D);
- gpu_state_print_fl(GL_TEXTURE_3D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_1D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_2D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_3D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_CUBE_MAP);
- gpu_state_print_fl(GL_TEXTURE_COMPRESSION_HINT);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_SIZE);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_STRIDE);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_TYPE);
- gpu_state_print_fl(GL_TEXTURE_CUBE_MAP);
- gpu_state_print_fl(GL_TEXTURE_GEN_Q);
- gpu_state_print_fl(GL_TEXTURE_GEN_R);
- gpu_state_print_fl(GL_TEXTURE_GEN_S);
- gpu_state_print_fl(GL_TEXTURE_GEN_T);
- gpu_state_print_fl(GL_TEXTURE_MATRIX);
- gpu_state_print_fl(GL_TEXTURE_STACK_DEPTH);
- gpu_state_print_fl(GL_TRANSPOSE_COLOR_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_MODELVIEW_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_PROJECTION_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_TEXTURE_MATRIX);
- gpu_state_print_fl(GL_UNPACK_ALIGNMENT);
- gpu_state_print_fl(GL_UNPACK_IMAGE_HEIGHT);
- gpu_state_print_fl(GL_UNPACK_LSB_FIRST);
- gpu_state_print_fl(GL_UNPACK_ROW_LENGTH);
- gpu_state_print_fl(GL_UNPACK_SKIP_IMAGES);
- gpu_state_print_fl(GL_UNPACK_SKIP_PIXELS);
- gpu_state_print_fl(GL_UNPACK_SKIP_ROWS);
- gpu_state_print_fl(GL_UNPACK_SWAP_BYTES);
- gpu_state_print_fl(GL_VERTEX_ARRAY);
- gpu_state_print_fl(GL_VERTEX_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_VERTEX_ARRAY_SIZE);
- gpu_state_print_fl(GL_VERTEX_ARRAY_STRIDE);
- gpu_state_print_fl(GL_VERTEX_ARRAY_TYPE);
- gpu_state_print_fl(GL_VERTEX_PROGRAM_POINT_SIZE);
- gpu_state_print_fl(GL_VERTEX_PROGRAM_TWO_SIDE);
- gpu_state_print_fl(GL_VIEWPORT);
- gpu_state_print_fl(GL_ZOOM_X);
- gpu_state_print_fl(GL_ZOOM_Y);
-}
-
-#undef gpu_state_print_fl
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 1fb1e239310..fb246aa802e 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -78,6 +78,7 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -137,7 +138,7 @@ void GPU_render_text(
else if (!col)
glColor3f(1.0f, 1.0f, 1.0f);
- glPushMatrix();
+ gpuPushMatrix();
/* get the tab width */
ImBuf *first_ibuf = BKE_image_get_first_ibuf(ima);
@@ -155,12 +156,12 @@ void GPU_render_text(
character = BLI_str_utf8_as_unicode_and_size_safe(textstr + index, &index);
if (character == '\n') {
- glTranslatef(line_start, -line_height, 0.0f);
+ gpuTranslate2f(line_start, -line_height);
line_start = 0.0f;
continue;
}
else if (character == '\t') {
- glTranslatef(advance_tab, 0.0f, 0.0f);
+ gpuTranslate2f(advance_tab, 0.0f);
line_start -= advance_tab; /* so we can go back to the start of the line */
continue;
@@ -209,21 +210,22 @@ void GPU_render_text(
}
glEnd();
- glTranslatef(advance, 0.0f, 0.0f);
+ gpuTranslate2f(advance, 0.0f);
line_start -= advance; /* so we can go back to the start of the line */
}
- glPopMatrix();
+ gpuPopMatrix();
BKE_image_release_ibuf(ima, first_ibuf, NULL);
}
}
/* Checking powers of two for images since OpenGL ES requires it */
-
+#ifdef WITH_DDS
static bool is_power_of_2_resolution(int w, int h)
{
return is_power_of_2_i(w) && is_power_of_2_i(h);
}
+#endif
static bool is_over_resolution_limit(GLenum textarget, int w, int h)
{
@@ -418,7 +420,7 @@ void GPU_clear_tpage(bool force)
GTS.curima = NULL;
if (GTS.curtilemode != 0) {
glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
+ glLoadIdentity(); /* TEXTURE */
glMatrixMode(GL_MODELVIEW);
}
GTS.curtilemode = 0;
@@ -602,10 +604,10 @@ int GPU_verify_image(
GTS.curtileYRep != GTS.tileYRep)
{
glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
+ glLoadIdentity(); /* TEXTURE */
if (ima && (ima->tpageflag & IMA_TILES))
- glScalef(ima->xrep, ima->yrep, 1.0f);
+ glScalef(ima->xrep, ima->yrep, 0); /* TEXTURE */
glMatrixMode(GL_MODELVIEW);
}
@@ -1686,7 +1688,7 @@ void GPU_end_dupli_object(void)
}
void GPU_begin_object_materials(
- View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob,
+ View3D *v3d, RegionView3D *rv3d, Scene *scene, SceneLayer *sl, Object *ob,
bool glsl, bool *do_alpha_after)
{
Material *ma;
@@ -1725,8 +1727,10 @@ void GPU_begin_object_materials(
#ifdef WITH_GAMEENGINE
if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- ob = BKE_object_lod_matob_get(ob, scene);
+ ob = BKE_object_lod_matob_get(ob, sl);
}
+#else
+ UNUSED_VARS(sl);
#endif
/* initialize state */
@@ -2092,7 +2096,7 @@ void GPU_end_object_materials(void)
/* resetting the texture matrix after the scaling needed for tiled textures */
if (GTS.tilemode) {
glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
+ glLoadIdentity(); /* TEXTURE */
glMatrixMode(GL_MODELVIEW);
}
}
@@ -2169,8 +2173,8 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][
Lamp *la = base->object->data;
/* setup lamp transform */
- glPushMatrix();
- glLoadMatrixf((float *)viewmat);
+ gpuPushMatrix();
+ gpuLoadMatrix3D(viewmat);
/* setup light */
GPULightData light = {0};
@@ -2204,7 +2208,7 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][
GPU_basic_shader_light_set(count, &light);
- glPopMatrix();
+ gpuPopMatrix();
count++;
if (count == 8)
@@ -2252,15 +2256,6 @@ static void gpu_multisample(bool enable)
void GPU_state_init(void)
{
- float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
- float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 35);
- glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-
GPU_default_lights();
GPU_disable_program_point_size();
@@ -2276,37 +2271,16 @@ void GPU_state_init(void)
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
- glDisable(GL_FOG);
- glDisable(GL_LIGHTING);
- glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LOGIC_OP);
glDisable(GL_STENCIL_TEST);
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- /* default disabled, enable should be local per function */
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
- glPixelTransferi(GL_RED_SCALE, 1);
- glPixelTransferi(GL_RED_BIAS, 0);
- glPixelTransferi(GL_GREEN_SCALE, 1);
- glPixelTransferi(GL_GREEN_BIAS, 0);
- glPixelTransferi(GL_BLUE_SCALE, 1);
- glPixelTransferi(GL_BLUE_BIAS, 0);
- glPixelTransferi(GL_ALPHA_SCALE, 1);
- glPixelTransferi(GL_ALPHA_BIAS, 0);
-
- glPixelTransferi(GL_DEPTH_BIAS, 0);
- glPixelTransferi(GL_DEPTH_SCALE, 1);
glDepthRange(0.0, 1.0);
glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
+ glLoadIdentity(); /* TEXTURE */
glMatrixMode(GL_MODELVIEW);
glFrontFace(GL_CCW);
@@ -2314,8 +2288,6 @@ void GPU_state_init(void)
glDisable(GL_CULL_FACE);
gpu_multisample(false);
-
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
}
void GPU_enable_program_point_size(void)
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 1efc451f4a8..ce35c43bcec 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -32,9 +32,9 @@
#include "BKE_global.h"
-#include "GPU_debug.h"
-#include "GPU_glew.h"
+#include "GPU_batch.h"
#include "GPU_framebuffer.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -131,14 +131,16 @@ bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slo
}
}
- if (GPU_texture_depth(tex))
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
+ GG.currentfb = fb->object;
+
+ if (GPU_texture_stencil(tex) && GPU_texture_depth(tex))
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ else if (GPU_texture_depth(tex))
attachment = GL_DEPTH_ATTACHMENT;
else
attachment = GL_COLOR_ATTACHMENT0 + slot;
- glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
- GG.currentfb = fb->object;
-
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
@@ -166,7 +168,11 @@ void GPU_framebuffer_texture_detach(GPUTexture *tex)
GG.currentfb = fb->object;
}
- if (GPU_texture_depth(tex)) {
+ if (GPU_texture_stencil(tex) && GPU_texture_depth(tex)) {
+ fb->depthtex = NULL;
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ }
+ else if (GPU_texture_depth(tex)) {
fb->depthtex = NULL;
attachment = GL_DEPTH_ATTACHMENT;
}
@@ -212,14 +218,9 @@ void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
glEnable(GL_MULTISAMPLE);
}
- /* push matrices and set default viewport and matrix */
+ /* set default viewport */
glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
GG.currentfb = fb->object;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
}
void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
@@ -250,14 +251,9 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
glDrawBuffers(numslots, attachments);
glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
- /* push matrices and set default viewport and matrix */
+ /* set default viewport */
glViewport(0, 0, GPU_texture_width(fb->colortex[slot]), GPU_texture_height(fb->colortex[slot]));
GG.currentfb = fb->object;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
}
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
@@ -300,12 +296,6 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
{
- /* restore matrix */
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
/* restore attributes */
glPopAttrib();
}
@@ -379,20 +369,48 @@ void GPU_framebuffer_blur(
GPUFrameBuffer *fb, GPUTexture *tex,
GPUFrameBuffer *blurfb, GPUTexture *blurtex)
{
+ const float fullscreencos[4][2] = {{-1.0f, -1.0f}, {1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}};
+ const float fullscreenuvs[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}};
+
+ static VertexFormat format = {0};
+ static VertexBuffer vbo = {{0}};
+ static Batch batch = {{0}};
+
const float scaleh[2] = {1.0f / GPU_texture_width(blurtex), 0.0f};
const float scalev[2] = {0.0f, 1.0f / GPU_texture_height(tex)};
GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
- int scale_uniform, texture_source_uniform;
if (!blur_shader)
return;
- scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU");
- texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource");
+ /* Preparing to draw quad */
+ if (format.attrib_ct == 0) {
+ unsigned int i = 0;
+ /* Vertex format */
+ unsigned int pos = add_attrib(&format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
+ unsigned int uvs = add_attrib(&format, "uvs", GL_FLOAT, 2, KEEP_FLOAT);
+
+ /* Vertices */
+ VertexBuffer_init_with_format(&vbo, &format);
+ VertexBuffer_allocate_data(&vbo, 36);
+
+ for (int j = 0; j < 3; ++j) {
+ setAttrib(&vbo, uvs, i, fullscreenuvs[j]); setAttrib(&vbo, pos, i++, fullscreencos[j]);
+ }
+ for (int j = 1; j < 4; ++j) {
+ setAttrib(&vbo, uvs, i, fullscreenuvs[j]); setAttrib(&vbo, pos, i++, fullscreencos[j]);
+ }
+
+ Batch_init(&batch, GL_TRIANGLES, &vbo, NULL);
+ }
- /* Blurring horizontally */
+ glDisable(GL_DEPTH_TEST);
+
+ /* Load fresh matrices */
+ gpuMatrixBegin3D(); /* TODO: finish 2D API */
+ /* Blurring horizontally */
/* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid
* pushing unnecessary matrices onto the OpenGL stack. */
glBindFramebuffer(GL_FRAMEBUFFER, blurfb->object);
@@ -401,51 +419,66 @@ void GPU_framebuffer_blur(
/* avoid warnings from texture binding */
GG.currentfb = blurfb->object;
- GPU_shader_bind(blur_shader);
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh);
- GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
glViewport(0, 0, GPU_texture_width(blurtex), GPU_texture_height(blurtex));
- /* Preparing to draw quad */
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glDisable(GL_DEPTH_TEST);
-
GPU_texture_bind(tex, 0);
- /* Drawing quad */
- glBegin(GL_QUADS);
- glTexCoord2d(0, 0); glVertex2f(1, 1);
- glTexCoord2d(1, 0); glVertex2f(-1, 1);
- glTexCoord2d(1, 1); glVertex2f(-1, -1);
- glTexCoord2d(0, 1); glVertex2f(1, -1);
- glEnd();
+ Batch_set_builtin_program(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
+ Batch_Uniform2f(&batch, "ScaleU", scaleh[0], scaleh[1]);
+ Batch_Uniform1i(&batch, "textureSource", GL_TEXTURE0);
+ Batch_draw(&batch);
/* Blurring vertically */
-
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
GG.currentfb = fb->object;
glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev);
- GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
+
GPU_texture_bind(blurtex, 0);
- glBegin(GL_QUADS);
- glTexCoord2d(0, 0); glVertex2f(1, 1);
- glTexCoord2d(1, 0); glVertex2f(-1, 1);
- glTexCoord2d(1, 1); glVertex2f(-1, -1);
- glTexCoord2d(0, 1); glVertex2f(1, -1);
- glEnd();
+ /* Hack to make the following uniform stick */
+ Batch_set_builtin_program(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
+ Batch_Uniform2f(&batch, "ScaleU", scalev[0], scalev[1]);
+ Batch_Uniform1i(&batch, "textureSource", GL_TEXTURE0);
+ Batch_draw(&batch);
- GPU_shader_unbind();
+ gpuMatrixEnd();
+}
+
+void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, int read_slot, GPUFrameBuffer *fb_write, int write_slot, bool use_depth)
+{
+ GPUTexture *read_tex = (use_depth) ? fb_read->depthtex : fb_read->colortex[read_slot];
+ GPUTexture *write_tex = (use_depth) ? fb_write->depthtex : fb_write->colortex[write_slot];
+ int read_attach = (use_depth) ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + GPU_texture_framebuffer_attachment(read_tex);
+ int write_attach = (use_depth) ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + GPU_texture_framebuffer_attachment(write_tex);
+ int read_bind = GPU_texture_opengl_bindcode(read_tex);
+ int write_bind = GPU_texture_opengl_bindcode(write_tex);
+ const int read_w = GPU_texture_width(read_tex);
+ const int read_h = GPU_texture_height(read_tex);
+ const int write_w = GPU_texture_width(write_tex);
+ const int write_h = GPU_texture_height(write_tex);
+
+ /* read from multi-sample buffer */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb_read->object);
+ glFramebufferTexture2D(
+ GL_READ_FRAMEBUFFER, read_attach,
+ GL_TEXTURE_2D, read_bind, 0);
+ BLI_assert(glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+ /* write into new single-sample buffer */
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_write->object);
+ glFramebufferTexture2D(
+ GL_DRAW_FRAMEBUFFER, write_attach,
+ GL_TEXTURE_2D, write_bind, 0);
+ BLI_assert(glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+ glBlitFramebuffer(0, 0, read_w, read_h, 0, 0, write_w, write_h, (use_depth) ? GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ /* Restore previous framebuffer */
+ glBindFramebuffer(GL_FRAMEBUFFER, GG.currentfb);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
/* GPUOffScreen */
diff --git a/source/blender/gpu/intern/gpu_lamp.c b/source/blender/gpu/intern/gpu_lamp.c
new file mode 100644
index 00000000000..ee0bcb83a6a
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_lamp.c
@@ -0,0 +1,475 @@
+/*
+ * ***** 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) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_lamp.c
+ * \ingroup gpu
+ *
+ * Manages Opengl lights.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_lamp_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_group.h"
+
+#include "GPU_framebuffer.h"
+#include "GPU_glew.h"
+#include "GPU_lamp.h"
+#include "GPU_material.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "gpu_lamp_private.h"
+
+bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
+{
+ if (srl && srl->light_override)
+ return BKE_group_object_exists(srl->light_override, lamp->ob);
+ else if (ma && ma->group)
+ return BKE_group_object_exists(ma->group, lamp->ob);
+ else
+ return true;
+}
+
+static void gpu_lamp_calc_winmat(GPULamp *lamp)
+{
+ float temp, angle, pixsize, wsize;
+
+ if (lamp->type == LA_SUN) {
+ wsize = lamp->la->shadow_frustum_size;
+ orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
+ }
+ else if (lamp->type == LA_SPOT) {
+ angle = saacos(lamp->spotsi);
+ temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
+ pixsize = lamp->d / temp;
+ wsize = pixsize * 0.5f * lamp->size;
+ /* compute shadows according to X and Y scaling factors */
+ perspective_m4(
+ lamp->winmat,
+ -wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
+ -wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
+ lamp->d, lamp->clipend);
+ }
+}
+
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
+{
+ float mat[4][4];
+ float obmat_scale[3];
+
+ lamp->lay = lay;
+ lamp->hide = hide;
+
+ normalize_m4_m4_ex(mat, obmat, obmat_scale);
+
+ copy_v3_v3(lamp->vec, mat[2]);
+ copy_v3_v3(lamp->co, mat[3]);
+ copy_m4_m4(lamp->obmat, mat);
+ invert_m4_m4(lamp->imat, mat);
+
+ if (lamp->type == LA_SPOT) {
+ /* update spotlamp scale on X and Y axis */
+ lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
+ lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
+ }
+
+ if (GPU_lamp_has_shadow_buffer(lamp)) {
+ /* makeshadowbuf */
+ gpu_lamp_calc_winmat(lamp);
+ }
+}
+
+void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
+{
+ lamp->energy = energy;
+ if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
+
+ lamp->col[0] = r;
+ lamp->col[1] = g;
+ lamp->col[2] = b;
+}
+
+void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
+ float coeff_const, float coeff_lin, float coeff_quad)
+{
+ lamp->dist = distance;
+ lamp->att1 = att1;
+ lamp->att2 = att2;
+ lamp->coeff_const = coeff_const;
+ lamp->coeff_lin = coeff_lin;
+ lamp->coeff_quad = coeff_quad;
+}
+
+void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
+{
+ lamp->spotsi = cosf(spotsize * 0.5f);
+ lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
+}
+
+static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
+{
+ lamp->scene = scene;
+ lamp->ob = ob;
+ lamp->par = par;
+ lamp->la = la;
+
+ /* add_render_lamp */
+ lamp->mode = la->mode;
+ lamp->type = la->type;
+
+ lamp->energy = la->energy;
+ if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
+
+ lamp->col[0] = la->r;
+ lamp->col[1] = la->g;
+ lamp->col[2] = la->b;
+
+ GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
+
+ lamp->spotsi = la->spotsize;
+ if (lamp->mode & LA_HALO)
+ if (lamp->spotsi > DEG2RADF(170.0f))
+ lamp->spotsi = DEG2RADF(170.0f);
+ lamp->spotsi = cosf(lamp->spotsi * 0.5f);
+ lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
+ lamp->k = la->k;
+
+ lamp->dist = la->dist;
+ lamp->falloff_type = la->falloff_type;
+ lamp->att1 = la->att1;
+ lamp->att2 = la->att2;
+ lamp->coeff_const = la->coeff_const;
+ lamp->coeff_lin = la->coeff_lin;
+ lamp->coeff_quad = la->coeff_quad;
+ lamp->curfalloff = la->curfalloff;
+
+ /* initshadowbuf */
+ lamp->bias = 0.02f * la->bias;
+ lamp->size = la->bufsize;
+ lamp->d = la->clipsta;
+ lamp->clipend = la->clipend;
+
+ /* arbitrary correction for the fact we do no soft transition */
+ lamp->bias *= 0.25f;
+}
+
+static void gpu_lamp_shadow_free(GPULamp *lamp)
+{
+ if (lamp->tex) {
+ GPU_texture_free(lamp->tex);
+ lamp->tex = NULL;
+ }
+ if (lamp->depthtex) {
+ GPU_texture_free(lamp->depthtex);
+ lamp->depthtex = NULL;
+ }
+ if (lamp->fb) {
+ GPU_framebuffer_free(lamp->fb);
+ lamp->fb = NULL;
+ }
+ if (lamp->blurtex) {
+ GPU_texture_free(lamp->blurtex);
+ lamp->blurtex = NULL;
+ }
+ if (lamp->blurfb) {
+ GPU_framebuffer_free(lamp->blurfb);
+ lamp->blurfb = NULL;
+ }
+}
+
+static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size)
+{
+ return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
+}
+
+GPULamp *GPU_lamp_from_engine(Scene *scene, Object *ob, Object *par, struct RenderEngineType *re)
+{
+ GPULamp *lamp;
+ LinkData *link;
+
+ for (link = ob->gpulamp.first; link; link = link->next) {
+ lamp = (GPULamp *)link->data;
+
+ if ((lamp->par == par) && (lamp->scene == scene) && (lamp->re == re))
+ return link->data;
+ }
+
+ lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
+
+ link = MEM_callocN(sizeof(LinkData), "GPULampLink");
+ link->data = lamp;
+ BLI_addtail(&ob->gpulamp, link);
+
+ lamp->scene = scene;
+ lamp->ob = ob;
+ lamp->par = par;
+ lamp->la = ob->data;
+ lamp->re = re;
+
+ return lamp;
+}
+
+GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
+{
+ Lamp *la;
+ GPULamp *lamp;
+ LinkData *link;
+
+ for (link = ob->gpulamp.first; link; link = link->next) {
+ lamp = (GPULamp *)link->data;
+
+ if (lamp->par == par && lamp->scene == scene)
+ return link->data;
+ }
+
+ lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
+
+ link = MEM_callocN(sizeof(LinkData), "GPULampLink");
+ link->data = lamp;
+ BLI_addtail(&ob->gpulamp, link);
+
+ la = ob->data;
+ gpu_lamp_from_blender(scene, ob, par, la, lamp);
+
+ if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
+ (la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
+ {
+ /* opengl */
+ lamp->fb = GPU_framebuffer_create();
+ if (!lamp->fb) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
+ /* Shadow depth map */
+ lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
+ if (!lamp->depthtex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ /* Shadow color map */
+ lamp->tex = gpu_lamp_create_vsm_shadow_map(lamp->size);
+ if (!lamp->tex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ /* FBO and texture for blurring */
+ lamp->blurfb = GPU_framebuffer_create();
+ if (!lamp->blurfb) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ lamp->blurtex = gpu_lamp_create_vsm_shadow_map(lamp->size * 0.5);
+ if (!lamp->blurtex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ /* we need to properly bind to test for completeness */
+ GPU_texture_bind_as_framebuffer(lamp->blurtex);
+
+ if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
+ }
+ else {
+ lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
+ if (!lamp->tex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+ }
+
+ GPU_framebuffer_restore();
+
+ lamp->shadow_color[0] = la->shdwr;
+ lamp->shadow_color[1] = la->shdwg;
+ lamp->shadow_color[2] = la->shdwb;
+ }
+ else {
+ lamp->shadow_color[0] = 1.0;
+ lamp->shadow_color[1] = 1.0;
+ lamp->shadow_color[2] = 1.0;
+ }
+
+ return lamp;
+}
+
+void GPU_lamp_free(Object *ob)
+{
+ GPULamp *lamp;
+ LinkData *link;
+ LinkData *nlink;
+ Material *ma;
+
+ for (link = ob->gpulamp.first; link; link = link->next) {
+ lamp = link->data;
+
+ while (lamp->materials.first) {
+ nlink = lamp->materials.first;
+ ma = nlink->data;
+ BLI_freelinkN(&lamp->materials, nlink);
+
+ if (ma->gpumaterial.first)
+ GPU_material_free(&ma->gpumaterial);
+ }
+
+ gpu_lamp_shadow_free(lamp);
+
+ MEM_freeN(lamp);
+ }
+
+ BLI_freelistN(&ob->gpulamp);
+}
+
+bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
+{
+ return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
+ !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
+ lamp->tex && lamp->fb);
+}
+
+void GPU_lamp_update_buffer_mats(GPULamp *lamp)
+{
+ float rangemat[4][4], persmat[4][4];
+
+ /* initshadowbuf */
+ invert_m4_m4(lamp->viewmat, lamp->obmat);
+ normalize_v3(lamp->viewmat[0]);
+ normalize_v3(lamp->viewmat[1]);
+ normalize_v3(lamp->viewmat[2]);
+
+ /* makeshadowbuf */
+ mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
+
+ /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
+ unit_m4(rangemat);
+ rangemat[0][0] = 0.5f;
+ rangemat[1][1] = 0.5f;
+ rangemat[2][2] = 0.5f;
+ rangemat[3][0] = 0.5f;
+ rangemat[3][1] = 0.5f;
+ rangemat[3][2] = 0.5f;
+
+ mul_m4_m4m4(lamp->persmat, rangemat, persmat);
+}
+
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
+{
+ GPU_lamp_update_buffer_mats(lamp);
+
+ /* opengl */
+ glDisable(GL_SCISSOR_TEST);
+ GPU_texture_bind_as_framebuffer(lamp->tex);
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
+ GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
+
+ /* set matrices */
+ copy_m4_m4(viewmat, lamp->viewmat);
+ copy_m4_m4(winmat, lamp->winmat);
+ *winsize = lamp->size;
+}
+
+void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
+{
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
+ GPU_shader_unbind();
+ GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
+ }
+
+ GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
+ GPU_framebuffer_restore();
+ glEnable(GL_SCISSOR_TEST);
+}
+
+int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
+{
+ return lamp->la->shadowmap_type;
+}
+
+int GPU_lamp_shadow_bind_code(GPULamp *lamp)
+{
+ return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
+}
+
+float *GPU_lamp_dynpersmat(GPULamp *lamp)
+{
+ return &lamp->dynpersmat[0][0];
+}
+
+int GPU_lamp_shadow_layer(GPULamp *lamp)
+{
+ if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
+ return lamp->lay;
+ else
+ return -1;
+}
diff --git a/source/blender/gpu/intern/gpu_lamp_private.h b/source/blender/gpu/intern/gpu_lamp_private.h
new file mode 100644
index 00000000000..ef71385e66d
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_lamp_private.h
@@ -0,0 +1,86 @@
+/*
+ * ***** 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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_lamp_private.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_LAMP_PRIVATE_H__
+#define __GPU_LAMP_PRIVATE_H__
+
+#include "BLI_sys_types.h" /* for bool */
+
+struct GPULamp {
+ Scene *scene;
+ Object *ob;
+ Object *par;
+ Lamp *la;
+ struct RenderEngineType *re;
+
+ /* Old Viewport (pre-2.8) */
+ int type, mode, lay, hide;
+
+ float dynenergy, dyncol[3];
+ float energy, col[3];
+
+ float co[3], vec[3];
+ float dynco[3], dynvec[3];
+ float obmat[4][4];
+ float imat[4][4];
+ float dynimat[4][4];
+
+ float spotsi, spotbl, k;
+ float spotvec[2];
+ float dyndist, dynatt1, dynatt2;
+ float dist, att1, att2;
+ float coeff_const, coeff_lin, coeff_quad;
+ float shadow_color[3];
+
+ float bias, d, clipend;
+ int size;
+
+ int falloff_type;
+ struct CurveMapping *curfalloff;
+
+ float winmat[4][4];
+ float viewmat[4][4];
+ float persmat[4][4];
+ float dynpersmat[4][4];
+
+ GPUFrameBuffer *fb;
+ GPUFrameBuffer *blurfb;
+ GPUTexture *tex;
+ GPUTexture *depthtex;
+ GPUTexture *blurtex;
+
+ ListBase materials;
+
+ /* New viewport */
+ struct LampEngineData data;
+};
+
+#endif /* __GPU_LAMP_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 9e08f629bcb..153ae8ec8dc 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -60,11 +60,13 @@
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
+#include "GPU_lamp.h"
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "gpu_codegen.h"
+#include "gpu_lamp_private.h"
#ifdef WITH_OPENSUBDIV
# include "BKE_DerivedMesh.h"
@@ -128,50 +130,6 @@ struct GPUMaterial {
bool is_opensubdiv;
};
-struct GPULamp {
- Scene *scene;
- Object *ob;
- Object *par;
- Lamp *la;
-
- int type, mode, lay, hide;
-
- float dynenergy, dyncol[3];
- float energy, col[3];
-
- float co[3], vec[3];
- float dynco[3], dynvec[3];
- float obmat[4][4];
- float imat[4][4];
- float dynimat[4][4];
-
- float spotsi, spotbl, k;
- float spotvec[2];
- float dyndist, dynatt1, dynatt2;
- float dist, att1, att2;
- float coeff_const, coeff_lin, coeff_quad;
- float shadow_color[3];
-
- float bias, d, clipend;
- int size;
-
- int falloff_type;
- struct CurveMapping *curfalloff;
-
- float winmat[4][4];
- float viewmat[4][4];
- float persmat[4][4];
- float dynpersmat[4][4];
-
- GPUFrameBuffer *fb;
- GPUFrameBuffer *blurfb;
- GPUTexture *tex;
- GPUTexture *depthtex;
- GPUTexture *blurtex;
-
- ListBase materials;
-};
-
/* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
static void texture_rgb_blend(
GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
@@ -308,16 +266,6 @@ void GPU_material_free(ListBase *gpumaterial)
BLI_freelistN(gpumaterial);
}
-bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
-{
- if (srl && srl->light_override)
- return BKE_group_object_exists(srl->light_override, lamp->ob);
- else if (ma && ma->group)
- return BKE_group_object_exists(ma->group, lamp->ob);
- else
- return true;
-}
-
void GPU_material_bind(
GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
@@ -1016,7 +964,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
{
- BaseLegacy *base;
+ Base *base;
Scene *sce_iter;
for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
@@ -2222,391 +2170,6 @@ void GPU_materials_free(void)
/* Lamps and shadow buffers */
-static void gpu_lamp_calc_winmat(GPULamp *lamp)
-{
- float temp, angle, pixsize, wsize;
-
- if (lamp->type == LA_SUN) {
- wsize = lamp->la->shadow_frustum_size;
- orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
- }
- else if (lamp->type == LA_SPOT) {
- angle = saacos(lamp->spotsi);
- temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
- pixsize = lamp->d / temp;
- wsize = pixsize * 0.5f * lamp->size;
- /* compute shadows according to X and Y scaling factors */
- perspective_m4(
- lamp->winmat,
- -wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
- -wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
- lamp->d, lamp->clipend);
- }
-}
-
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
-{
- float mat[4][4];
- float obmat_scale[3];
-
- lamp->lay = lay;
- lamp->hide = hide;
-
- normalize_m4_m4_ex(mat, obmat, obmat_scale);
-
- copy_v3_v3(lamp->vec, mat[2]);
- copy_v3_v3(lamp->co, mat[3]);
- copy_m4_m4(lamp->obmat, mat);
- invert_m4_m4(lamp->imat, mat);
-
- if (lamp->type == LA_SPOT) {
- /* update spotlamp scale on X and Y axis */
- lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
- lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
- }
-
- if (GPU_lamp_has_shadow_buffer(lamp)) {
- /* makeshadowbuf */
- gpu_lamp_calc_winmat(lamp);
- }
-}
-
-void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
-{
- lamp->energy = energy;
- if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
-
- lamp->col[0] = r;
- lamp->col[1] = g;
- lamp->col[2] = b;
-}
-
-void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
- float coeff_const, float coeff_lin, float coeff_quad)
-{
- lamp->dist = distance;
- lamp->att1 = att1;
- lamp->att2 = att2;
- lamp->coeff_const = coeff_const;
- lamp->coeff_lin = coeff_lin;
- lamp->coeff_quad = coeff_quad;
-}
-
-void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
-{
- lamp->spotsi = cosf(spotsize * 0.5f);
- lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
-}
-
-static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
-{
- lamp->scene = scene;
- lamp->ob = ob;
- lamp->par = par;
- lamp->la = la;
-
- /* add_render_lamp */
- lamp->mode = la->mode;
- lamp->type = la->type;
-
- lamp->energy = la->energy;
- if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
-
- lamp->col[0] = la->r;
- lamp->col[1] = la->g;
- lamp->col[2] = la->b;
-
- GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
-
- lamp->spotsi = la->spotsize;
- if (lamp->mode & LA_HALO)
- if (lamp->spotsi > DEG2RADF(170.0f))
- lamp->spotsi = DEG2RADF(170.0f);
- lamp->spotsi = cosf(lamp->spotsi * 0.5f);
- lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
- lamp->k = la->k;
-
- lamp->dist = la->dist;
- lamp->falloff_type = la->falloff_type;
- lamp->att1 = la->att1;
- lamp->att2 = la->att2;
- lamp->coeff_const = la->coeff_const;
- lamp->coeff_lin = la->coeff_lin;
- lamp->coeff_quad = la->coeff_quad;
- lamp->curfalloff = la->curfalloff;
-
- /* initshadowbuf */
- lamp->bias = 0.02f * la->bias;
- lamp->size = la->bufsize;
- lamp->d = la->clipsta;
- lamp->clipend = la->clipend;
-
- /* arbitrary correction for the fact we do no soft transition */
- lamp->bias *= 0.25f;
-}
-
-static void gpu_lamp_shadow_free(GPULamp *lamp)
-{
- if (lamp->tex) {
- GPU_texture_free(lamp->tex);
- lamp->tex = NULL;
- }
- if (lamp->depthtex) {
- GPU_texture_free(lamp->depthtex);
- lamp->depthtex = NULL;
- }
- if (lamp->fb) {
- GPU_framebuffer_free(lamp->fb);
- lamp->fb = NULL;
- }
- if (lamp->blurtex) {
- GPU_texture_free(lamp->blurtex);
- lamp->blurtex = NULL;
- }
- if (lamp->blurfb) {
- GPU_framebuffer_free(lamp->blurfb);
- lamp->blurfb = NULL;
- }
-}
-
-static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size)
-{
- return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
-}
-
-GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
-{
- Lamp *la;
- GPULamp *lamp;
- LinkData *link;
-
- for (link = ob->gpulamp.first; link; link = link->next) {
- lamp = (GPULamp *)link->data;
-
- if (lamp->par == par && lamp->scene == scene)
- return link->data;
- }
-
- lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
-
- link = MEM_callocN(sizeof(LinkData), "GPULampLink");
- link->data = lamp;
- BLI_addtail(&ob->gpulamp, link);
-
- la = ob->data;
- gpu_lamp_from_blender(scene, ob, par, la, lamp);
-
- if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
- (la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
- {
- /* opengl */
- lamp->fb = GPU_framebuffer_create();
- if (!lamp->fb) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
- /* Shadow depth map */
- lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
- if (!lamp->depthtex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- /* Shadow color map */
- lamp->tex = gpu_lamp_create_vsm_shadow_map(lamp->size);
- if (!lamp->tex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- /* FBO and texture for blurring */
- lamp->blurfb = GPU_framebuffer_create();
- if (!lamp->blurfb) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- lamp->blurtex = gpu_lamp_create_vsm_shadow_map(lamp->size * 0.5);
- if (!lamp->blurtex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- /* we need to properly bind to test for completeness */
- GPU_texture_bind_as_framebuffer(lamp->blurtex);
-
- if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
- }
- else {
- lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
- if (!lamp->tex) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
-
- if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
- gpu_lamp_shadow_free(lamp);
- return lamp;
- }
- }
-
- GPU_framebuffer_restore();
-
- lamp->shadow_color[0] = la->shdwr;
- lamp->shadow_color[1] = la->shdwg;
- lamp->shadow_color[2] = la->shdwb;
- }
- else {
- lamp->shadow_color[0] = 1.0;
- lamp->shadow_color[1] = 1.0;
- lamp->shadow_color[2] = 1.0;
- }
-
- return lamp;
-}
-
-void GPU_lamp_free(Object *ob)
-{
- GPULamp *lamp;
- LinkData *link;
- LinkData *nlink;
- Material *ma;
-
- for (link = ob->gpulamp.first; link; link = link->next) {
- lamp = link->data;
-
- while (lamp->materials.first) {
- nlink = lamp->materials.first;
- ma = nlink->data;
- BLI_freelinkN(&lamp->materials, nlink);
-
- if (ma->gpumaterial.first)
- GPU_material_free(&ma->gpumaterial);
- }
-
- gpu_lamp_shadow_free(lamp);
-
- MEM_freeN(lamp);
- }
-
- BLI_freelistN(&ob->gpulamp);
-}
-
-bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
-{
- return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
- !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
- lamp->tex && lamp->fb);
-}
-
-void GPU_lamp_update_buffer_mats(GPULamp *lamp)
-{
- float rangemat[4][4], persmat[4][4];
-
- /* initshadowbuf */
- invert_m4_m4(lamp->viewmat, lamp->obmat);
- normalize_v3(lamp->viewmat[0]);
- normalize_v3(lamp->viewmat[1]);
- normalize_v3(lamp->viewmat[2]);
-
- /* makeshadowbuf */
- mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
-
- /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
- unit_m4(rangemat);
- rangemat[0][0] = 0.5f;
- rangemat[1][1] = 0.5f;
- rangemat[2][2] = 0.5f;
- rangemat[3][0] = 0.5f;
- rangemat[3][1] = 0.5f;
- rangemat[3][2] = 0.5f;
-
- mul_m4_m4m4(lamp->persmat, rangemat, persmat);
-}
-
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
-{
- GPU_lamp_update_buffer_mats(lamp);
-
- /* opengl */
- glDisable(GL_SCISSOR_TEST);
- GPU_texture_bind_as_framebuffer(lamp->tex);
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
- GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
-
- /* set matrices */
- copy_m4_m4(viewmat, lamp->viewmat);
- copy_m4_m4(winmat, lamp->winmat);
- *winsize = lamp->size;
-}
-
-void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
-{
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
- GPU_shader_unbind();
- GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
- }
-
- GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
- GPU_framebuffer_restore();
- glEnable(GL_SCISSOR_TEST);
-}
-
-int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
-{
- return lamp->la->shadowmap_type;
-}
-
-int GPU_lamp_shadow_bind_code(GPULamp *lamp)
-{
- return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
-}
-
-float *GPU_lamp_dynpersmat(GPULamp *lamp)
-{
- return &lamp->dynpersmat[0][0];
-}
-
-int GPU_lamp_shadow_layer(GPULamp *lamp)
-{
- if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
- return lamp->lay;
- else
- return -1;
-}
-
GPUNodeLink *GPU_lamp_get_data(
GPUMaterial *mat, GPULamp *lamp,
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy)
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index 855ccaa4999..8f8754f612d 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -29,6 +29,7 @@
* \ingroup gpu
*/
+#define SUPPRESS_GENERIC_MATRIX_API
#include "GPU_matrix.h"
#include "BLI_math_matrix.h"
@@ -80,7 +81,7 @@ void gpuMatrixBegin2D(void)
state.mode = MATRIX_MODE_2D;
state.top = 0;
unit_m3(ModelView2D);
- gpuOrtho2D(-1.0f, +1.0f, -1.0f, +1.0f); // or identity?
+ unit_m3(Projection2D);
}
void gpuMatrixBegin3D(void)
@@ -88,21 +89,9 @@ void gpuMatrixBegin3D(void)
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?
+ unit_m4(Projection3D);
}
-#if SUPPORT_LEGACY_MATRIX
-void gpuMatrixBegin3D_legacy(void)
-{
- /* copy top matrix from each legacy stack into new fresh stack */
- state.mode = MATRIX_MODE_3D;
- state.top = 0;
- state.dirty = true;
- glGetFloatv(GL_MODELVIEW_MATRIX, (float*)ModelView3D);
- glGetFloatv(GL_PROJECTION_MATRIX, (float*)Projection3D);
-}
-#endif
-
void gpuMatrixEnd(void)
{
state.mode = MATRIX_MODE_INACTIVE;
@@ -135,6 +124,14 @@ static void checkmat(cosnt float *m)
void gpuPushMatrix(void)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glPushMatrix();
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode != MATRIX_MODE_INACTIVE);
BLI_assert(state.top < MATRIX_STACK_DEPTH);
state.top++;
@@ -146,6 +143,14 @@ void gpuPushMatrix(void)
void gpuPopMatrix(void)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glPopMatrix();
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode != MATRIX_MODE_INACTIVE);
BLI_assert(state.top > 0);
state.top--;
@@ -154,12 +159,47 @@ void gpuPopMatrix(void)
void gpuLoadMatrix3D(const float m[4][4])
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glLoadMatrixf((const float*) m);
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode == MATRIX_MODE_3D);
copy_m4_m4(ModelView3D, m);
CHECKMAT(ModelView3D);
state.dirty = true;
}
+void gpuLoadProjectionMatrix3D(const float m[4][4])
+{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ GLenum mode;
+ glGetIntegerv(GL_MATRIX_MODE, (GLint*)&mode);
+ if (mode != GL_PROJECTION) {
+ glMatrixMode(GL_PROJECTION);
+ }
+
+ glLoadMatrixf((const float*) m);
+
+ if (mode != GL_PROJECTION_MATRIX) {
+ glMatrixMode(mode); /* restore */
+ }
+
+ state.dirty = true;
+ return;
+ }
+#endif
+
+ BLI_assert(state.mode == MATRIX_MODE_3D);
+ copy_m4_m4(Projection3D, m);
+ CHECKMAT(Projection3D);
+ state.dirty = true;
+}
+
void gpuLoadMatrix2D(const float m[3][3])
{
BLI_assert(state.mode == MATRIX_MODE_2D);
@@ -177,6 +217,11 @@ void gpuLoadIdentity(void)
case MATRIX_MODE_2D:
unit_m3(ModelView2D);
break;
+#if SUPPORT_LEGACY_MATRIX
+ case MATRIX_MODE_INACTIVE:
+ glLoadIdentity();
+ break;
+#endif
default:
BLI_assert(false);
}
@@ -185,6 +230,14 @@ void gpuLoadIdentity(void)
void gpuTranslate2f(float x, float y)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glTranslatef(x, y, 0.0f);
+ state.dirty = true;
+ return;
+ }
+#endif
+
Mat3 m;
unit_m3(m);
m[2][0] = x;
@@ -199,6 +252,14 @@ void gpuTranslate2fv(const float vec[2])
void gpuTranslate3f(float x, float y, float z)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glTranslatef(x, y, z);
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode == MATRIX_MODE_3D);
#if 1
translate_m4(ModelView3D, x, y, z);
@@ -244,6 +305,12 @@ void gpuScaleUniform(float factor)
gpuMultMatrix2D(m);
break;
}
+#if SUPPORT_LEGACY_MATRIX
+ case MATRIX_MODE_INACTIVE:
+ glScalef(factor, factor, factor); /* always scale Z since we can't distinguish 2D from 3D */
+ state.dirty = true;
+ break;
+#endif
default:
BLI_assert(false);
}
@@ -251,6 +318,14 @@ void gpuScaleUniform(float factor)
void gpuScale2f(float x, float y)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glScalef(x, y, 1.0f);
+ state.dirty = true;
+ return;
+ }
+#endif
+
Mat3 m = {{0.0f}};
m[0][0] = x;
m[1][1] = y;
@@ -265,6 +340,14 @@ void gpuScale2fv(const float vec[2])
void gpuScale3f(float x, float y, float z)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glScalef(x, y, z);
+ state.dirty = true;
+ return;
+ }
+#endif
+
Mat4 m = {{0.0f}};
m[0][0] = x;
m[1][1] = y;
@@ -280,6 +363,14 @@ void gpuScale3fv(const float vec[3])
void gpuMultMatrix3D(const float m[4][4])
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glMultMatrixf((const float*) m);
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode == MATRIX_MODE_3D);
mul_m4_m4_post(ModelView3D, m);
CHECKMAT(ModelView3D);
@@ -294,8 +385,35 @@ void gpuMultMatrix2D(const float m[3][3])
state.dirty = true;
}
+void gpuRotate2D(float deg)
+{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glRotatef(deg, 0.0f, 0.0f, 1.0f);
+ state.dirty = true;
+ return;
+ }
+#endif
+
+ BLI_assert(false); /* TODO: finish for MATRIX_MODE_2D */
+}
+
+void gpuRotate3f(float deg, float x, float y, float z)
+{
+ const float axis[3] = {x, y, z};
+ gpuRotate3fv(deg, axis);
+}
+
void gpuRotate3fv(float deg, const float axis[3])
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ glRotatef(deg, axis[0], axis[1], axis[2]);
+ state.dirty = true;
+ return;
+ }
+#endif
+
Mat4 m;
axis_angle_to_mat4(m, axis, DEG2RADF(deg));
gpuMultMatrix3D(m);
@@ -303,6 +421,21 @@ void gpuRotate3fv(float deg, const float axis[3])
void gpuRotateAxis(float deg, char axis)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ float a[3] = { 0.0f };
+ switch (axis) {
+ case 'X': a[0] = 1.0f; break;
+ case 'Y': a[1] = 1.0f; break;
+ case 'Z': a[2] = 1.0f; break;
+ default: BLI_assert(false); /* bad axis */
+ }
+ glRotatef(deg, a[0], a[1], a[2]);
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode == MATRIX_MODE_3D);
#if 1 /* rotate_m4 works in place, right? */
rotate_m4(ModelView3D, axis, DEG2RADF(deg));
@@ -340,7 +473,7 @@ static void mat4_ortho_set(float m[4][4], float left, float right, float bottom,
state.dirty = true;
}
-static void mat4_frustum_set(float m[][4], float left, float right, float bottom, float top, float near, float far)
+static void mat4_frustum_set(float m[4][4], float left, float right, float bottom, float top, float near, float far)
{
m[0][0] = 2.0f * near / (right - left);
m[1][0] = 0.0f;
@@ -433,6 +566,26 @@ static void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3
void gpuOrtho(float left, float right, float bottom, float top, float near, float far)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ GLenum mode;
+ glGetIntegerv(GL_MATRIX_MODE, (GLint*)&mode);
+ if (mode != GL_PROJECTION) {
+ glMatrixMode(GL_PROJECTION);
+ }
+
+ glLoadIdentity();
+ glOrtho(left, right, bottom, top, near, far);
+
+ if (mode != GL_PROJECTION_MATRIX) {
+ glMatrixMode(mode); /* restore */
+ }
+
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode == MATRIX_MODE_3D);
mat4_ortho_set(Projection3D, left, right, bottom, top, near, far);
CHECKMAT(Projection3D);
@@ -441,6 +594,26 @@ void gpuOrtho(float left, float right, float bottom, float top, float near, floa
void gpuOrtho2D(float left, float right, float bottom, float top)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ GLenum mode;
+ glGetIntegerv(GL_MATRIX_MODE, (GLint*)&mode);
+ if (mode != GL_PROJECTION) {
+ glMatrixMode(GL_PROJECTION);
+ }
+
+ glLoadIdentity();
+ glOrtho(left, right, bottom, top, -1.0f, 1.0f);
+
+ if (mode != GL_PROJECTION_MATRIX) {
+ glMatrixMode(mode); /* restore */
+ }
+
+ state.dirty = true;
+ return;
+ }
+#endif
+
/* TODO: this function, but correct */
BLI_assert(state.mode == MATRIX_MODE_2D);
Mat4 m;
@@ -452,6 +625,26 @@ void gpuOrtho2D(float left, float right, float bottom, float top)
void gpuFrustum(float left, float right, float bottom, float top, float near, float far)
{
+#if SUPPORT_LEGACY_MATRIX
+ if (state.mode == MATRIX_MODE_INACTIVE) {
+ GLenum mode;
+ glGetIntegerv(GL_MATRIX_MODE, (GLint*)&mode);
+ if (mode != GL_PROJECTION) {
+ glMatrixMode(GL_PROJECTION);
+ }
+
+ glLoadIdentity();
+ glFrustum(left, right, bottom, top, near, far);
+
+ if (mode != GL_PROJECTION_MATRIX) {
+ glMatrixMode(mode); /* restore */
+ }
+
+ state.dirty = true;
+ return;
+ }
+#endif
+
BLI_assert(state.mode == MATRIX_MODE_3D);
mat4_frustum_set(Projection3D, left, right, bottom, top, near, far);
CHECKMAT(Projection3D);
@@ -481,19 +674,23 @@ void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY,
gpuTranslate3f(-eyeX, -eyeY, -eyeZ);
}
-void gpuProject(const float obj[3], const float model[4][4], const float proj[4][4], const GLint view[4], float win[3])
+void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3])
{
float v[4];
- mul_v4_m4v3(v, model, obj);
+ mul_v4_m4v3(v, model, world);
mul_m4_v4(proj, v);
+ if (v[3] != 0.0f) {
+ mul_v3_fl(v, 1.0f / v[3]);
+ }
+
win[0] = view[0] + (view[2] * (v[0] + 1)) * 0.5f;
win[1] = view[1] + (view[3] * (v[1] + 1)) * 0.5f;
win[2] = (v[2] + 1) * 0.5f;
}
-bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const GLint view[4], float obj[3])
+bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3])
{
float pm[4][4];
float in[4];
@@ -502,6 +699,7 @@ bool gpuUnProject(const float win[3], const float model[4][4], const float proj[
mul_m4_m4m4(pm, proj, model);
if (!invert_m4(pm)) {
+ zero_v3(world);
return false;
}
@@ -522,19 +720,12 @@ bool gpuUnProject(const float win[3], const float model[4][4], const float proj[
mul_v4_m4v3(out, pm, in);
if (out[3] == 0.0f) {
+ copy_v3_v3(world, out);
return false;
}
- else {
- out[0] /= out[3];
- out[1] /= out[3];
- out[2] /= out[3];
-
- obj[0] = out[0];
- obj[1] = out[1];
- obj[2] = out[2];
- return true;
- }
+ mul_v3_v3fl(world, out, 1.0f / out[3]);
+ return true;
}
const float *gpuGetModelViewMatrix3D(float m[4][4])
@@ -579,38 +770,33 @@ const float *gpuGetProjectionMatrix3D(float m[4][4])
BLI_assert(state.mode == MATRIX_MODE_3D);
if (m) {
- copy_m4_m4(m, ModelView3D);
+ copy_m4_m4(m, Projection3D);
return (const float*)m;
}
else {
- return (const float*)ModelView3D;
+ return (const float*)Projection3D;
}
}
const float *gpuGetModelViewProjectionMatrix3D(float m[4][4])
{
+ if (m == NULL) {
+ static Mat4 temp;
+ m = temp;
+ }
+
#if SUPPORT_LEGACY_MATRIX
if (state.mode == MATRIX_MODE_INACTIVE) {
- if (m == NULL) {
- static Mat4 temp;
- m = temp;
- }
-
Mat4 proj;
- glGetFloatv(GL_MODELVIEW_MATRIX, (float*)proj);
- glGetFloatv(GL_PROJECTION_MATRIX, (float*)m);
- mul_m4_m4_post(m, proj);
+ glGetFloatv(GL_MODELVIEW_MATRIX, (float*)m);
+ glGetFloatv(GL_PROJECTION_MATRIX, (float*)proj);
+ mul_m4_m4_pre(m, proj);
return (const float*)m;
}
#endif
BLI_assert(state.mode == MATRIX_MODE_3D);
- if (m == NULL) {
- static Mat4 temp;
- m = temp;
- }
-
mul_m4_m4m4(m, Projection3D, ModelView3D);
return (const float*)m;
}
@@ -692,6 +878,27 @@ void gpuBindMatrices(GLuint program)
glUniformMatrix3fv(loc_N, 1, GL_FALSE, gpuGetNormalMatrix(NULL));
}
+ /* also needed by material.glsl
+ * - ProjectionMatrixInverse
+ * - ModelViewMatrixInverse
+ */
+ GLint loc_MV_inv = glGetUniformLocation(program, "ModelViewInverseMatrix");
+ GLint loc_P_inv = glGetUniformLocation(program, "ProjectionInverseMatrix");
+
+ if (loc_MV_inv != -1) {
+ Mat4 m;
+ gpuGetModelViewMatrix3D(m);
+ invert_m4(m);
+ glUniformMatrix4fv(loc_MV_inv, 1, GL_FALSE, (const float*) m);
+ }
+
+ if (loc_P_inv != -1) {
+ Mat4 m;
+ gpuGetProjectionMatrix3D(m);
+ invert_m4(m);
+ glUniformMatrix4fv(loc_P_inv, 1, GL_FALSE, (const float*) m);
+ }
+
state.dirty = false;
}
@@ -699,11 +906,3 @@ bool gpuMatricesDirty(void)
{
return state.dirty;
}
-
-#if SUPPORT_LEGACY_MATRIX
-void gpuMatrixUpdate_legacy(void)
-{
- BLI_assert(state.mode == MATRIX_MODE_INACTIVE);
- state.dirty = true;
-}
-#endif
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 58582232cd5..c384fa01fc6 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -29,109 +29,86 @@
* Interface for accessing gpu-related methods for selection. The semantics will be
* similar to glRenderMode(GL_SELECT) since the goal is to maintain compatibility.
*/
+#include <stdlib.h>
+
#include "GPU_select.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-
+
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
#include "BLI_utildefines.h"
-/* Ad hoc number of queries to allocate to skip doing many glGenQueries */
-#define ALLOC_QUERIES 200
-
-typedef struct GPUQueryState {
+#include "gpu_select_private.h"
+
+/* Internal algorithm used */
+enum {
+ /** GL_SELECT, legacy OpenGL selection */
+ ALGO_GL_LEGACY = 1,
+ /** glBegin/EndQuery(GL_SAMPLES_PASSED... ), `gpu_select_query.c`
+ * Only sets 4th component (ID) correctly. */
+ ALGO_GL_QUERY = 2,
+ /** Read depth buffer for every drawing pass and extract depths, `gpu_select_pick.c`
+ * Only sets 4th component (ID) correctly. */
+ ALGO_GL_PICK = 3,
+};
+
+typedef struct GPUSelectState {
/* To ignore selection id calls when not initialized */
bool select_is_active;
- /* Tracks whether a query has been issued so that gpu_load_id can end the previous one */
- bool query_issued;
- /* array holding the OpenGL query identifiers */
- unsigned int *queries;
- /* array holding the id corresponding to each query */
- unsigned int *id;
- /* number of queries in *queries and *id */
- unsigned int num_of_queries;
- /* index to the next query to start */
- unsigned int active_query;
/* flag to cache user preference for occlusion based selection */
bool use_gpu_select;
- /* cache on initialization */
- unsigned int *buffer;
- /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/
- unsigned int bufsize;
/* mode of operation */
char mode;
- unsigned int index;
- int oldhits;
-} GPUQueryState;
+ /* internal algorithm for selection */
+ char algorithm;
+ /* allow GPU_select_begin/end without drawing */
+ bool use_cache;
+} GPUSelectState;
-static GPUQueryState g_query_state = {0};
+static GPUSelectState g_select_state = {0};
/**
* initialize and provide buffer for results
*/
-void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, char mode, int oldhits)
+void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rcti *input, char mode, int oldhits)
{
- g_query_state.select_is_active = true;
- g_query_state.query_issued = false;
- g_query_state.active_query = 0;
- g_query_state.use_gpu_select = GPU_select_query_check_active();
- g_query_state.num_of_queries = 0;
- g_query_state.bufsize = bufsize;
- g_query_state.buffer = buffer;
- g_query_state.mode = mode;
- g_query_state.index = 0;
- g_query_state.oldhits = oldhits;
+ g_select_state.select_is_active = true;
+ g_select_state.use_gpu_select = GPU_select_query_check_active();
+ g_select_state.mode = mode;
- if (!g_query_state.use_gpu_select) {
- glSelectBuffer(bufsize, (GLuint *)buffer);
- glRenderMode(GL_SELECT);
- glInitNames();
- glPushName(-1);
+ if (ELEM(g_select_state.mode, GPU_SELECT_PICK_ALL, GPU_SELECT_PICK_NEAREST)) {
+ g_select_state.algorithm = ALGO_GL_PICK;
+ }
+ else if (!g_select_state.use_gpu_select) {
+ g_select_state.algorithm = ALGO_GL_LEGACY;
}
else {
- float viewport[4];
-
- g_query_state.num_of_queries = ALLOC_QUERIES;
-
- g_query_state.queries = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.queries), "gpu selection queries");
- g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids");
- glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
- /* disable writing to the framebuffer */
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- /* In order to save some fill rate we minimize the viewport using rect.
- * We need to get the region of the scissor so that our geometry doesn't
- * get rejected before the depth test. Should probably cull rect against
- * scissor for viewport but this is a rare case I think */
- glGetFloatv(GL_SCISSOR_BOX, viewport);
- if (!input || input->xmin == input->xmax) {
- glViewport(viewport[0], viewport[1], 24, 24);
- }
- else {
- glViewport(viewport[0], viewport[1], (int)(input->xmax - input->xmin), (int)(input->ymax - input->ymin));
- }
+ g_select_state.algorithm = ALGO_GL_QUERY;
+ }
- /* occlusion queries operates on fragments that pass tests and since we are interested on all
- * objects in the view frustum independently of their order, we need to disable the depth test */
- if (mode == GPU_SELECT_ALL) {
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
+ switch (g_select_state.algorithm) {
+ case ALGO_GL_LEGACY:
+ {
+ g_select_state.use_cache = false;
+ glSelectBuffer(bufsize, (GLuint *)buffer);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+ glPushName(-1);
+ break;
}
- else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
- glClear(GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_LEQUAL);
+ case ALGO_GL_QUERY:
+ {
+ g_select_state.use_cache = false;
+ gpu_select_query_begin((unsigned int (*)[4])buffer, bufsize / 4, input, mode, oldhits);
+ break;
}
- else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_EQUAL);
+ default: /* ALGO_GL_PICK */
+ {
+ gpu_select_pick_begin((unsigned int (*)[4])buffer, bufsize / 4, input, mode);
+ break;
}
}
}
@@ -146,41 +123,24 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, c
bool GPU_select_load_id(unsigned int id)
{
/* if no selection mode active, ignore */
- if (!g_query_state.select_is_active)
+ if (!g_select_state.select_is_active)
return true;
- if (!g_query_state.use_gpu_select) {
- glLoadName(id);
- }
- else {
- if (g_query_state.query_issued) {
- glEndQuery(GL_SAMPLES_PASSED);
+ switch (g_select_state.algorithm) {
+ case ALGO_GL_LEGACY:
+ {
+ glLoadName(id);
+ return true;
}
- /* if required, allocate extra queries */
- if (g_query_state.active_query == g_query_state.num_of_queries) {
- g_query_state.num_of_queries += ALLOC_QUERIES;
- g_query_state.queries = MEM_reallocN(g_query_state.queries, g_query_state.num_of_queries * sizeof(*g_query_state.queries));
- g_query_state.id = MEM_reallocN(g_query_state.id, g_query_state.num_of_queries * sizeof(*g_query_state.id));
- glGenQueries(ALLOC_QUERIES, &g_query_state.queries[g_query_state.active_query]);
+ case ALGO_GL_QUERY:
+ {
+ return gpu_select_query_load_id(id);
}
-
- glBeginQuery(GL_SAMPLES_PASSED, g_query_state.queries[g_query_state.active_query]);
- g_query_state.id[g_query_state.active_query] = id;
- g_query_state.active_query++;
- g_query_state.query_issued = true;
-
- if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && g_query_state.index < g_query_state.oldhits) {
- if (g_query_state.buffer[g_query_state.index * 4 + 3] == id) {
- g_query_state.index++;
- return true;
- }
- else {
- return false;
- }
+ default: /* ALGO_GL_PICK */
+ {
+ return gpu_select_pick_load_id(id);
}
}
-
- return true;
}
/**
@@ -191,59 +151,27 @@ bool GPU_select_load_id(unsigned int id)
unsigned int GPU_select_end(void)
{
unsigned int hits = 0;
- if (!g_query_state.use_gpu_select) {
- glPopName();
- hits = glRenderMode(GL_RENDER);
- }
- else {
- int i;
- if (g_query_state.query_issued) {
- glEndQuery(GL_SAMPLES_PASSED);
+ switch (g_select_state.algorithm) {
+ case ALGO_GL_LEGACY:
+ {
+ glPopName();
+ hits = glRenderMode(GL_RENDER);
+ break;
}
-
- for (i = 0; i < g_query_state.active_query; i++) {
- unsigned int result;
- glGetQueryObjectuiv(g_query_state.queries[i], GL_QUERY_RESULT, &result);
- if (result > 0) {
- if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) {
- int maxhits = g_query_state.bufsize / 4;
-
- if (hits < maxhits) {
- g_query_state.buffer[hits * 4] = 1;
- g_query_state.buffer[hits * 4 + 1] = 0xFFFF;
- g_query_state.buffer[hits * 4 + 2] = 0xFFFF;
- g_query_state.buffer[hits * 4 + 3] = g_query_state.id[i];
-
- hits++;
- }
- else {
- hits = -1;
- break;
- }
- }
- else {
- int j;
- /* search in buffer and make selected object first */
- for (j = 0; j < g_query_state.oldhits; j++) {
- if (g_query_state.buffer[j * 4 + 3] == g_query_state.id[i]) {
- g_query_state.buffer[j * 4 + 1] = 0;
- g_query_state.buffer[j * 4 + 2] = 0;
- }
- }
- break;
- }
- }
+ case ALGO_GL_QUERY:
+ {
+ hits = gpu_select_query_end();
+ break;
+ }
+ default: /* ALGO_GL_PICK */
+ {
+ hits = gpu_select_pick_end();
+ break;
}
-
- glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries);
- MEM_freeN(g_query_state.queries);
- MEM_freeN(g_query_state.id);
- glPopAttrib();
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
- g_query_state.select_is_active = false;
+ g_select_state.select_is_active = false;
return hits;
}
@@ -253,10 +181,43 @@ unsigned int GPU_select_end(void)
*/
bool GPU_select_query_check_active(void)
{
- return ((U.gpu_select_method == USER_SELECT_USE_OCCLUSION_QUERY) ||
- ((U.gpu_select_method == USER_SELECT_AUTO) &&
- (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) ||
- /* unsupported by nouveau, gallium 0.4, see: T47940 */
- GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE))));
+ return ELEM(U.gpu_select_method, USER_SELECT_USE_OCCLUSION_QUERY, USER_SELECT_AUTO);
+}
+
+/* ----------------------------------------------------------------------------
+ * Caching
+ *
+ * Support multiple begin/end's as long as they are within the initial region.
+ * Currently only used by ALGO_GL_PICK.
+ */
+
+void GPU_select_cache_begin(void)
+{
+ /* validate on GPU_select_begin, clear if not supported */
+ BLI_assert(g_select_state.use_cache == false);
+ g_select_state.use_cache = true;
+ if (g_select_state.algorithm == ALGO_GL_PICK) {
+ gpu_select_pick_cache_begin();
+ }
+}
+
+void GPU_select_cache_load_id(void)
+{
+ BLI_assert(g_select_state.use_cache == true);
+ if (g_select_state.algorithm == ALGO_GL_PICK) {
+ gpu_select_pick_cache_load_id();
+ }
+}
+
+void GPU_select_cache_end(void)
+{
+ if (g_select_state.algorithm == ALGO_GL_PICK) {
+ gpu_select_pick_cache_end();
+ }
+ g_select_state.use_cache = false;
+}
+bool GPU_select_is_cached(void)
+{
+ return g_select_state.use_cache && gpu_select_pick_is_cached();
}
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
new file mode 100644
index 00000000000..780ffd82671
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -0,0 +1,740 @@
+/*
+ * ***** 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) 2017 Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_select_pick.c
+ * \ingroup gpu
+ *
+ * Custom select code for picking small regions (not efficient for large regions).
+ * `gpu_select_pick_*` API.
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "GPU_select.h"
+#include "GPU_extensions.h"
+#include "GPU_glew.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_rect.h"
+#include "BLI_listbase.h"
+#include "BLI_math_vector.h"
+#include "BLI_utildefines.h"
+
+#include "gpu_select_private.h"
+
+#include "BLI_strict_flags.h"
+
+/* #define DEBUG_PRINT */
+
+/* Alloc number for depths */
+#define ALLOC_DEPTHS 200
+
+/* Z-depth of cleared depth buffer */
+#define DEPTH_MAX 0xffffffff
+
+/* ----------------------------------------------------------------------------
+ * SubRectStride
+ */
+
+/* For looping over a sub-region of a rect, could be moved into 'rct.c'*/
+typedef struct SubRectStride {
+ unsigned int start; /* start here */
+ unsigned int span; /* read these */
+ unsigned int span_len; /* len times (read span 'len' times). */
+ unsigned int skip; /* skip those */
+} SubRectStride;
+
+/* we may want to change back to float if uint isn't well supported */
+typedef unsigned int depth_t;
+
+/**
+ * Calculate values needed for looping over a sub-region (smaller buffer within a larger buffer).
+ *
+ * 'src' must be bigger than 'dst'.
+ */
+static void rect_subregion_stride_calc(const rcti *src, const rcti *dst, SubRectStride *r_sub)
+{
+ const int src_x = BLI_rcti_size_x(src);
+ // const int src_y = BLI_rcti_size_y(src);
+ const int dst_x = BLI_rcti_size_x(dst);
+ const int dst_y = BLI_rcti_size_y(dst);
+ const int x = dst->xmin - src->xmin;
+ const int y = dst->ymin - src->ymin;
+
+ BLI_assert(src->xmin <= dst->xmin && src->ymin <= dst->ymin &&
+ src->ymax >= dst->ymax && src->ymax >= dst->ymax);
+ BLI_assert(x >= 0 && y >= 0);
+
+ r_sub->start = (unsigned int)((src_x * y) + x);
+ r_sub->span = (unsigned int)dst_x;
+ r_sub->span_len = (unsigned int)dst_y;
+ r_sub->skip = (unsigned int)(src_x - dst_x);
+}
+
+/**
+ * Ignore depth clearing as a change,
+ * only check if its been changed _and_ filled in (ignore clearing since XRAY does this).
+ */
+BLI_INLINE bool depth_is_filled(const depth_t *prev, const depth_t *curr)
+{
+ return (*prev != *curr) && (*curr != DEPTH_MAX);
+}
+
+/* ----------------------------------------------------------------------------
+ * DepthBufCache
+ *
+ * Result of reading glReadPixels,
+ * use for both cache and non-cached storage.
+ */
+
+/* store result of glReadPixels */
+typedef struct DepthBufCache {
+ struct DepthBufCache *next, *prev;
+ unsigned int id;
+ depth_t buf[0];
+} DepthBufCache;
+
+static DepthBufCache *depth_buf_malloc(unsigned int rect_len)
+{
+ DepthBufCache *rect = MEM_mallocN(sizeof(DepthBufCache) + sizeof(depth_t) * rect_len, __func__);
+ rect->id = SELECT_ID_NONE;
+ return rect;
+}
+
+static bool depth_buf_rect_depth_any(
+ const DepthBufCache *rect_depth,
+ unsigned int rect_len)
+{
+ const depth_t *curr = rect_depth->buf;
+ for (unsigned int i = 0; i < rect_len; i++, curr++) {
+ if (*curr != DEPTH_MAX) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool depth_buf_subrect_depth_any(
+ const DepthBufCache *rect_depth,
+ const SubRectStride *sub_rect)
+{
+ const depth_t *curr = rect_depth->buf + sub_rect->start;
+ for (unsigned int i = 0; i < sub_rect->span_len; i++) {
+ const depth_t *curr_end = curr + sub_rect->span;
+ for (; curr < curr_end; curr++, curr++) {
+ if (*curr != DEPTH_MAX) {
+ return true;
+ }
+ }
+ curr += sub_rect->skip;
+ }
+ return false;
+}
+
+static bool depth_buf_rect_depth_any_filled(
+ const DepthBufCache *rect_prev, const DepthBufCache *rect_curr,
+ unsigned int rect_len)
+{
+#if 0
+ return memcmp(rect_depth_a->buf, rect_depth_b->buf, rect_len * sizeof(depth_t)) != 0;
+#else
+ const depth_t *prev = rect_prev->buf;
+ const depth_t *curr = rect_curr->buf;
+ for (unsigned int i = 0; i < rect_len; i++, curr++, prev++) {
+ if (depth_is_filled(prev, curr)) {
+ return true;
+ }
+ }
+ return false;
+#endif
+}
+
+/**
+ * Both buffers are the same size, just check if the sub-rect contains any differences.
+ */
+static bool depth_buf_subrect_depth_any_filled(
+ const DepthBufCache *rect_src, const DepthBufCache *rect_dst,
+ const SubRectStride *sub_rect)
+{
+ /* same as above but different rect sizes */
+ const depth_t *prev = rect_src->buf + sub_rect->start;
+ const depth_t *curr = rect_dst->buf + sub_rect->start;
+ for (unsigned int i = 0; i < sub_rect->span_len; i++) {
+ const depth_t *curr_end = curr + sub_rect->span;
+ for (; curr < curr_end; prev++, curr++) {
+ if (depth_is_filled(prev, curr)) {
+ return true;
+ }
+ }
+ prev += sub_rect->skip;
+ curr += sub_rect->skip;
+ }
+ return false;
+}
+
+/* ----------------------------------------------------------------------------
+ * DepthID
+ *
+ * Internal structure for storing hits.
+ */
+
+typedef struct DepthID {
+ unsigned int id;
+ depth_t depth;
+} DepthID;
+
+static int depth_id_cmp(const void *v1, const void *v2)
+{
+ const DepthID *d1 = v1, *d2 = v2;
+ if (d1->id < d2->id) {
+ return -1;
+ }
+ else if (d1->id > d2->id) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+static int depth_cmp(const void *v1, const void *v2)
+{
+ const DepthID *d1 = v1, *d2 = v2;
+ if (d1->depth < d2->depth) {
+ return -1;
+ }
+ else if (d1->depth > d2->depth) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* depth sorting */
+typedef struct GPUPickState {
+ /* cache on initialization */
+ unsigned int (*buffer)[4];
+
+ /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/
+ unsigned int bufsize;
+ /* mode of operation */
+ char mode;
+
+ /* OpenGL drawing, never use when (is_cached == true). */
+ struct {
+ /* The current depth, accumulated as we draw */
+ DepthBufCache *rect_depth;
+ /* Scratch buffer, avoid allocs every time (when not caching) */
+ DepthBufCache *rect_depth_test;
+
+ /* Pass to glReadPixels (x, y, w, h) */
+ int clip_readpixels[4];
+
+ /* Set after first draw */
+ bool is_init;
+ unsigned int prev_id;
+ } gl;
+
+ /* src: data stored in 'cache' and 'gl',
+ * dst: use when cached region is smaller (where src -> dst isn't 1:1) */
+ struct {
+ rcti clip_rect;
+ unsigned int rect_len;
+ } src, dst;
+
+ /* Store cache between `GPU_select_cache_begin/end` */
+ bool use_cache;
+ bool is_cached;
+ struct {
+ /* Cleanup used for iterating over both source and destination buffers:
+ * src.clip_rect -> dst.clip_rect */
+ SubRectStride sub_rect;
+
+ /* List of DepthBufCache, sized of 'src.clip_rect' */
+ ListBase bufs;
+ } cache;
+
+ /* Pickign methods */
+ union {
+ /* GPU_SELECT_PICK_ALL */
+ struct {
+ DepthID *hits;
+ unsigned int hits_len;
+ unsigned int hits_len_alloc;
+ } all;
+
+ /* GPU_SELECT_PICK_NEAREST */
+ struct {
+ unsigned int *rect_id;
+ } nearest;
+ };
+} GPUPickState;
+
+
+static GPUPickState g_pick_state = {0};
+
+void gpu_select_pick_begin(
+ unsigned int (*buffer)[4], unsigned int bufsize,
+ const rcti *input, char mode)
+{
+ GPUPickState *ps = &g_pick_state;
+
+#ifdef DEBUG_PRINT
+ printf("%s: mode=%d, use_cache=%d, is_cache=%d\n", __func__, mode, ps->use_cache, ps->is_cached);
+#endif
+
+ ps->bufsize = bufsize;
+ ps->buffer = buffer;
+ ps->mode = mode;
+
+ const unsigned int rect_len = (unsigned int)(BLI_rcti_size_x(input) * BLI_rcti_size_y(input));
+ ps->dst.clip_rect = *input;
+ ps->dst.rect_len = rect_len;
+
+ /* Restrict OpenGL operations for when we don't have cache */
+ if (ps->is_cached == false) {
+
+ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
+ /* disable writing to the framebuffer */
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+
+ if (mode == GPU_SELECT_PICK_ALL) {
+ glDepthFunc(GL_ALWAYS);
+ }
+ else {
+ glDepthFunc(GL_LEQUAL);
+ }
+
+ float viewport[4];
+ glGetFloatv(GL_SCISSOR_BOX, viewport);
+
+ ps->src.clip_rect = *input;
+ ps->src.rect_len = rect_len;
+
+ ps->gl.clip_readpixels[0] = (int)viewport[0];
+ ps->gl.clip_readpixels[1] = (int)viewport[1];
+ ps->gl.clip_readpixels[2] = BLI_rcti_size_x(&ps->src.clip_rect);
+ ps->gl.clip_readpixels[3] = BLI_rcti_size_y(&ps->src.clip_rect);
+
+ glViewport(UNPACK4(ps->gl.clip_readpixels));
+
+ /* It's possible we don't want to clear depth buffer,
+ * so existing elements are masked by current z-buffer. */
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ /* scratch buffer (read new values here) */
+ ps->gl.rect_depth_test = depth_buf_malloc(rect_len);
+ ps->gl.rect_depth = depth_buf_malloc(rect_len);
+
+ /* set initial 'far' value */
+#if 0
+ glReadPixels(UNPACK4(ps->gl.clip_readpixels), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, ps->gl.rect_depth->buf);
+#else
+ for (unsigned int i = 0; i < rect_len; i++) {
+ ps->gl.rect_depth->buf[i] = DEPTH_MAX;
+ }
+#endif
+
+ ps->gl.is_init = false;
+ ps->gl.prev_id = 0;
+ }
+ else {
+ /* Using cache (ps->is_cached == true) */
+ /* src.clip_rect -> dst.clip_rect */
+ rect_subregion_stride_calc(&ps->src.clip_rect, &ps->dst.clip_rect, &ps->cache.sub_rect);
+ BLI_assert(ps->gl.rect_depth == NULL);
+ BLI_assert(ps->gl.rect_depth_test == NULL);
+ }
+
+ if (mode == GPU_SELECT_PICK_ALL) {
+ ps->all.hits = MEM_mallocN(sizeof(*ps->all.hits) * ALLOC_DEPTHS, __func__);
+ ps->all.hits_len = 0;
+ ps->all.hits_len_alloc = ALLOC_DEPTHS;
+ }
+ else {
+ /* Set to 0xff for SELECT_ID_NONE */
+ ps->nearest.rect_id = MEM_mallocN(sizeof(unsigned int) * ps->dst.rect_len, __func__);
+ memset(ps->nearest.rect_id, 0xff, sizeof(unsigned int) * ps->dst.rect_len);
+ }
+}
+
+/**
+ * Given 2x depths, we know are different - update the depth information
+ * use for both cached/uncached depth buffers.
+ */
+static void gpu_select_load_id_pass_all(const DepthBufCache *rect_curr)
+{
+ GPUPickState *ps = &g_pick_state;
+ const unsigned int id = rect_curr->id;
+ /* find the best depth for this pass and store in 'all.hits' */
+ depth_t depth_best = DEPTH_MAX;
+
+#define EVAL_TEST() \
+ if (depth_best > *curr) { \
+ depth_best = *curr; \
+ } ((void)0)
+
+ if (ps->is_cached == false) {
+ const depth_t *curr = rect_curr->buf;
+ BLI_assert(ps->src.rect_len == ps->dst.rect_len);
+ const unsigned int rect_len = ps->src.rect_len;
+ for (unsigned int i = 0; i < rect_len; i++, curr++) {
+ EVAL_TEST();
+ }
+ }
+ else {
+ /* same as above but different rect sizes */
+ const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
+ for (unsigned int i = 0; i < ps->cache.sub_rect.span_len; i++) {
+ const depth_t *curr_end = curr + ps->cache.sub_rect.span;
+ for (; curr < curr_end; curr++) {
+ EVAL_TEST();
+ }
+ curr += ps->cache.sub_rect.skip;
+ }
+ }
+
+#undef EVAL_TEST
+
+ /* ensure enough space */
+ if (UNLIKELY(ps->all.hits_len == ps->all.hits_len_alloc)) {
+ ps->all.hits_len_alloc += ALLOC_DEPTHS;
+ ps->all.hits = MEM_reallocN(ps->all.hits, ps->all.hits_len_alloc * sizeof(*ps->all.hits));
+ }
+ DepthID *d = &ps->all.hits[ps->all.hits_len++];
+ d->id = id;
+ d->depth = depth_best;
+}
+
+static void gpu_select_load_id_pass_nearest(const DepthBufCache *rect_prev, const DepthBufCache *rect_curr)
+{
+ GPUPickState *ps = &g_pick_state;
+ const unsigned int id = rect_curr->id;
+ /* keep track each pixels ID in 'nearest.rect_id' */
+ if (id != SELECT_ID_NONE) {
+ unsigned int *id_ptr = ps->nearest.rect_id;
+
+ /* Check against DEPTH_MAX because XRAY will clear the buffer,
+ * so previously set values will become unset.
+ * In this case just leave those id's left as-is. */
+#define EVAL_TEST() \
+ if (depth_is_filled(prev, curr)) { \
+ *id_ptr = id; \
+ } ((void)0)
+
+ if (ps->is_cached == false) {
+ const depth_t *prev = rect_prev->buf;
+ const depth_t *curr = rect_curr->buf;
+ BLI_assert(ps->src.rect_len == ps->dst.rect_len);
+ const unsigned int rect_len = ps->src.rect_len;
+ for (unsigned int i = 0; i < rect_len; i++, curr++, prev++, id_ptr++) {
+ EVAL_TEST();
+ }
+ }
+ else {
+ /* same as above but different rect sizes */
+ const depth_t *prev = rect_prev->buf + ps->cache.sub_rect.start;
+ const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
+ for (unsigned int i = 0; i < ps->cache.sub_rect.span_len; i++) {
+ const depth_t *curr_end = curr + ps->cache.sub_rect.span;
+ for (; curr < curr_end; prev++, curr++, id_ptr++) {
+ EVAL_TEST();
+ }
+ prev += ps->cache.sub_rect.skip;
+ curr += ps->cache.sub_rect.skip;
+ }
+ }
+
+#undef EVAL_TEST
+ }
+}
+
+
+bool gpu_select_pick_load_id(unsigned int id)
+{
+ GPUPickState *ps = &g_pick_state;
+ if (ps->gl.is_init) {
+ const unsigned int rect_len = ps->src.rect_len;
+ glReadPixels(UNPACK4(ps->gl.clip_readpixels), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, ps->gl.rect_depth_test->buf);
+ /* perform initial check since most cases the array remains unchanged */
+
+ bool do_pass = false;
+ if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
+ if (depth_buf_rect_depth_any(ps->gl.rect_depth_test, rect_len)) {
+ ps->gl.rect_depth_test->id = ps->gl.prev_id;
+ gpu_select_load_id_pass_all(ps->gl.rect_depth_test);
+ do_pass = true;
+ }
+ }
+ else {
+ if (depth_buf_rect_depth_any_filled(ps->gl.rect_depth, ps->gl.rect_depth_test, rect_len)) {
+ ps->gl.rect_depth_test->id = ps->gl.prev_id;
+ gpu_select_load_id_pass_nearest(ps->gl.rect_depth, ps->gl.rect_depth_test);
+ do_pass = true;
+ }
+ }
+
+ if (do_pass) {
+ /* Store depth in cache */
+ if (ps->use_cache) {
+ BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth);
+ ps->gl.rect_depth = depth_buf_malloc(ps->src.rect_len);
+ }
+
+ SWAP(DepthBufCache *, ps->gl.rect_depth, ps->gl.rect_depth_test);
+
+ if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
+ /* we want new depths every time */
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+ }
+ }
+
+ ps->gl.is_init = true;
+ ps->gl.prev_id = id;
+
+ return true;
+}
+
+unsigned int gpu_select_pick_end(void)
+{
+ GPUPickState *ps = &g_pick_state;
+
+#ifdef DEBUG_PRINT
+ printf("%s\n", __func__);
+#endif
+
+ if (ps->is_cached == false) {
+ if (ps->gl.is_init) {
+ /* force finishing last pass */
+ gpu_select_pick_load_id(ps->gl.prev_id);
+ }
+
+ glPopAttrib();
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }
+
+ /* assign but never free directly since it may be in cache */
+ DepthBufCache *rect_depth_final;
+
+ /* Store depth in cache */
+ if (ps->use_cache && !ps->is_cached) {
+ BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth);
+ ps->gl.rect_depth = NULL;
+ rect_depth_final = ps->cache.bufs.last;
+ }
+ else if (ps->is_cached) {
+ rect_depth_final = ps->cache.bufs.last;
+ }
+ else {
+ /* common case, no cache */
+ rect_depth_final = ps->gl.rect_depth;
+ }
+
+ unsigned int maxhits = g_pick_state.bufsize;
+ DepthID *depth_data;
+ unsigned int depth_data_len = 0;
+
+ if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
+ depth_data = ps->all.hits;
+ depth_data_len = ps->all.hits_len;
+ /* move ownership */
+ ps->all.hits = NULL;
+ ps->all.hits_len = 0;
+ ps->all.hits_len_alloc = 0;
+ }
+ else {
+ /* GPU_SELECT_PICK_NEAREST */
+
+ /* Over alloc (unlikely we have as many depths as pixels) */
+ unsigned int depth_data_len_first_pass = 0;
+ depth_data = MEM_mallocN(ps->dst.rect_len * sizeof(*depth_data), __func__);
+
+ /* Partially de-duplicating copy,
+ * when contiguous ID's are found - update their closest depth.
+ * This isn't essential but means there is less data to sort. */
+
+#define EVAL_TEST(i_src, i_dst) \
+ { \
+ const unsigned int id = ps->nearest.rect_id[i_dst]; \
+ if (id != SELECT_ID_NONE) { \
+ const depth_t depth = rect_depth_final->buf[i_src]; \
+ if (depth_last == NULL || depth_last->id != id) { \
+ DepthID *d = &depth_data[depth_data_len_first_pass++]; \
+ d->id = id; \
+ d->depth = depth; \
+ } \
+ else if (depth_last->depth > depth) { \
+ depth_last->depth = depth; \
+ } \
+ } \
+ } ((void)0)
+
+ {
+ DepthID *depth_last = NULL;
+ if (ps->is_cached == false) {
+ for (unsigned int i = 0; i < ps->src.rect_len; i++) {
+ EVAL_TEST(i, i);
+ }
+ }
+ else {
+ /* same as above but different rect sizes */
+ unsigned int i_src = ps->cache.sub_rect.start, i_dst = 0;
+ for (unsigned int j = 0; j < ps->cache.sub_rect.span_len; j++) {
+ const unsigned int i_src_end = i_src + ps->cache.sub_rect.span;
+ for (; i_src < i_src_end; i_src++, i_dst++) {
+ EVAL_TEST(i_src, i_dst);
+ }
+ i_src += ps->cache.sub_rect.skip;
+ }
+ }
+ }
+
+#undef EVAL_TEST
+
+ qsort(depth_data, depth_data_len_first_pass, sizeof(DepthID), depth_id_cmp);
+
+ /* Sort by ID's then keep the best depth for each ID */
+ depth_data_len = 0;
+ {
+ DepthID *depth_last = NULL;
+ for (unsigned int i = 0; i < depth_data_len_first_pass; i++) {
+ if (depth_last == NULL || depth_last->id != depth_data[i].id) {
+ depth_last = &depth_data[depth_data_len++];
+ *depth_last = depth_data[i];
+ }
+ else if (depth_last->depth > depth_data[i].depth) {
+ depth_last->depth = depth_data[i].depth;
+ }
+ }
+ }
+ }
+
+ /* Finally sort each unique (id, depth) pair by depth
+ * so the final hit-list is sorted by depth (nearest first) */
+ unsigned int hits = 0;
+
+ if (depth_data_len > maxhits) {
+ hits = (unsigned int)-1;
+ }
+ else {
+ /* leave sorting up to the caller */
+ qsort(depth_data, depth_data_len, sizeof(DepthID), depth_cmp);
+
+ for (unsigned int i = 0; i < depth_data_len; i++) {
+#ifdef DEBUG_PRINT
+ printf(" hit: %u: depth %u\n", depth_data[i].id, depth_data[i].depth);
+#endif
+ /* first 3 are dummy values */
+ g_pick_state.buffer[hits][0] = 1;
+ g_pick_state.buffer[hits][1] = 0x0; /* depth_data[i].depth; */ /* unused */
+ g_pick_state.buffer[hits][2] = 0x0; /* z-far is currently never used. */
+ g_pick_state.buffer[hits][3] = depth_data[i].id;
+ hits++;
+ }
+ BLI_assert(hits < maxhits);
+ }
+
+ MEM_freeN(depth_data);
+
+ MEM_SAFE_FREE(ps->gl.rect_depth);
+ MEM_SAFE_FREE(ps->gl.rect_depth_test);
+
+ if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
+ /* 'hits' already freed as 'depth_data' */
+ }
+ else {
+ MEM_freeN(ps->nearest.rect_id);
+ ps->nearest.rect_id = NULL;
+ }
+
+ if (ps->use_cache) {
+ ps->is_cached = true;
+ }
+
+ return hits;
+}
+
+/* ----------------------------------------------------------------------------
+ * Caching
+ *
+ * Support multiple begin/end's reusing depth buffers.
+ */
+
+void gpu_select_pick_cache_begin(void)
+{
+ BLI_assert(g_pick_state.use_cache == false);
+#ifdef DEBUG_PRINT
+ printf("%s\n", __func__);
+#endif
+ g_pick_state.use_cache = true;
+ g_pick_state.is_cached = false;
+}
+
+void gpu_select_pick_cache_end(void)
+{
+#ifdef DEBUG_PRINT
+ printf("%s: with %d buffers\n", __func__, BLI_listbase_count(&g_pick_state.cache.bufs));
+#endif
+ g_pick_state.use_cache = false;
+ g_pick_state.is_cached = false;
+
+ BLI_freelistN(&g_pick_state.cache.bufs);
+}
+
+/* is drawing needed? */
+bool gpu_select_pick_is_cached(void)
+{
+ return g_pick_state.is_cached;
+}
+
+void gpu_select_pick_cache_load_id(void)
+{
+ BLI_assert(g_pick_state.is_cached == true);
+ GPUPickState *ps = &g_pick_state;
+#ifdef DEBUG_PRINT
+ printf("%s (building depth from cache)\n", __func__);
+#endif
+ for (DepthBufCache *rect_depth = ps->cache.bufs.first; rect_depth; rect_depth = rect_depth->next) {
+ if (rect_depth->next != NULL) {
+ /* we know the buffers differ, but this sub-region may not.
+ * double check before adding an id-pass */
+ if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
+ if (depth_buf_subrect_depth_any(rect_depth->next, &ps->cache.sub_rect)) {
+ gpu_select_load_id_pass_all(rect_depth->next);
+ }
+ }
+ else {
+ if (depth_buf_subrect_depth_any_filled(rect_depth, rect_depth->next, &ps->cache.sub_rect)) {
+ gpu_select_load_id_pass_nearest(rect_depth, rect_depth->next);
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/gpu/intern/gpu_select_private.h b/source/blender/gpu/intern/gpu_select_private.h
new file mode 100644
index 00000000000..8935bd7b253
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_select_private.h
@@ -0,0 +1,53 @@
+/*
+ * ***** 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Antony Riakiotakis.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_select_private.h
+ * \ingroup gpu
+ *
+ * Selection implementations.
+ */
+
+#ifndef __GPU_SELECT_PRIVATE_H__
+#define __GPU_SELECT_PRIVATE_H__
+
+/* gpu_select_pick */
+void gpu_select_pick_begin(unsigned int (*buffer)[4], unsigned int bufsize, const rcti *input, char mode);
+bool gpu_select_pick_load_id(unsigned int id);
+unsigned int gpu_select_pick_end(void);
+
+void gpu_select_pick_cache_begin(void);
+void gpu_select_pick_cache_end(void);
+bool gpu_select_pick_is_cached(void);
+void gpu_select_pick_cache_load_id(void);
+
+/* gpu_select_sample_query */
+void gpu_select_query_begin(unsigned int (*buffer)[4], unsigned int bufsize, const rcti *input, char mode, int oldhits);
+bool gpu_select_query_load_id(unsigned int id);
+unsigned int gpu_select_query_end(void);
+
+
+#define SELECT_ID_NONE ((unsigned int)0xffffffff)
+
+#endif /* __GPU_SELECT_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
new file mode 100644
index 00000000000..ba5fefc5227
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -0,0 +1,209 @@
+/*
+ * ***** 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Antony Riakiotakis.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_select_sample_query.c
+ * \ingroup gpu
+ *
+ * Interface for accessing gpu-related methods for selection. The semantics will be
+ * similar to glRenderMode(GL_SELECT) since the goal is to maintain compatibility.
+ */
+
+#include <stdlib.h>
+
+#include "GPU_select.h"
+#include "GPU_extensions.h"
+#include "GPU_glew.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_rect.h"
+
+#include "BLI_utildefines.h"
+
+#include "gpu_select_private.h"
+
+
+/* Ad hoc number of queries to allocate to skip doing many glGenQueries */
+#define ALLOC_QUERIES 200
+
+typedef struct GPUQueryState {
+ /* Tracks whether a query has been issued so that gpu_load_id can end the previous one */
+ bool query_issued;
+ /* array holding the OpenGL query identifiers */
+ unsigned int *queries;
+ /* array holding the id corresponding to each query */
+ unsigned int *id;
+ /* number of queries in *queries and *id */
+ unsigned int num_of_queries;
+ /* index to the next query to start */
+ unsigned int active_query;
+ /* cache on initialization */
+ unsigned int (*buffer)[4];
+ /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/
+ unsigned int bufsize;
+ /* mode of operation */
+ char mode;
+ unsigned int index;
+ int oldhits;
+} GPUQueryState;
+
+static GPUQueryState g_query_state = {0};
+
+
+void gpu_select_query_begin(
+ unsigned int (*buffer)[4], unsigned int bufsize,
+ const rcti *input, char mode,
+ int oldhits)
+{
+ float viewport[4];
+
+ g_query_state.query_issued = false;
+ g_query_state.active_query = 0;
+ g_query_state.num_of_queries = 0;
+ g_query_state.bufsize = bufsize;
+ g_query_state.buffer = buffer;
+ g_query_state.mode = mode;
+ g_query_state.index = 0;
+ g_query_state.oldhits = oldhits;
+
+ g_query_state.num_of_queries = ALLOC_QUERIES;
+
+ g_query_state.queries = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.queries), "gpu selection queries");
+ g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids");
+ glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
+
+ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
+ /* disable writing to the framebuffer */
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ /* In order to save some fill rate we minimize the viewport using rect.
+ * We need to get the region of the scissor so that our geometry doesn't
+ * get rejected before the depth test. Should probably cull rect against
+ * scissor for viewport but this is a rare case I think */
+ glGetFloatv(GL_SCISSOR_BOX, viewport);
+ glViewport(viewport[0], viewport[1], BLI_rcti_size_x(input), BLI_rcti_size_y(input));
+
+ /* occlusion queries operates on fragments that pass tests and since we are interested on all
+ * objects in the view frustum independently of their order, we need to disable the depth test */
+ if (mode == GPU_SELECT_ALL) {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+ else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_LEQUAL);
+ }
+ else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDepthFunc(GL_EQUAL);
+ }
+}
+
+bool gpu_select_query_load_id(unsigned int id)
+{
+ if (g_query_state.query_issued) {
+ glEndQuery(GL_SAMPLES_PASSED);
+ }
+ /* if required, allocate extra queries */
+ if (g_query_state.active_query == g_query_state.num_of_queries) {
+ g_query_state.num_of_queries += ALLOC_QUERIES;
+ g_query_state.queries = MEM_reallocN(g_query_state.queries, g_query_state.num_of_queries * sizeof(*g_query_state.queries));
+ g_query_state.id = MEM_reallocN(g_query_state.id, g_query_state.num_of_queries * sizeof(*g_query_state.id));
+ glGenQueries(ALLOC_QUERIES, &g_query_state.queries[g_query_state.active_query]);
+ }
+
+ glBeginQuery(GL_SAMPLES_PASSED, g_query_state.queries[g_query_state.active_query]);
+ g_query_state.id[g_query_state.active_query] = id;
+ g_query_state.active_query++;
+ g_query_state.query_issued = true;
+
+ if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && g_query_state.index < g_query_state.oldhits) {
+ if (g_query_state.buffer[g_query_state.index][3] == id) {
+ g_query_state.index++;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+unsigned int gpu_select_query_end(void)
+{
+ int i;
+
+ unsigned int hits = 0;
+ const unsigned int maxhits = g_query_state.bufsize;
+
+ if (g_query_state.query_issued) {
+ glEndQuery(GL_SAMPLES_PASSED);
+ }
+
+ for (i = 0; i < g_query_state.active_query; i++) {
+ unsigned int result;
+ glGetQueryObjectuiv(g_query_state.queries[i], GL_QUERY_RESULT, &result);
+ if (result > 0) {
+ if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) {
+
+ if (hits < maxhits) {
+ g_query_state.buffer[hits][0] = 1;
+ g_query_state.buffer[hits][1] = 0xFFFF;
+ g_query_state.buffer[hits][2] = 0xFFFF;
+ g_query_state.buffer[hits][3] = g_query_state.id[i];
+
+ hits++;
+ }
+ else {
+ hits = -1;
+ break;
+ }
+ }
+ else {
+ int j;
+ /* search in buffer and make selected object first */
+ for (j = 0; j < g_query_state.oldhits; j++) {
+ if (g_query_state.buffer[j][3] == g_query_state.id[i]) {
+ g_query_state.buffer[j][1] = 0;
+ g_query_state.buffer[j][2] = 0;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries);
+ MEM_freeN(g_query_state.queries);
+ MEM_freeN(g_query_state.id);
+ glPopAttrib();
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ return hits;
+}
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 295182b3153..40653622d12 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -34,11 +34,11 @@
#include "BKE_global.h"
#include "GPU_compositing.h"
-#include "GPU_debug.h"
#include "GPU_extensions.h"
#include "GPU_shader.h"
#include "GPU_uniformbuffer.h"
#include "GPU_texture.h"
+#include "GPU_matrix.h"
#include "gpu_shader_private.h"
@@ -50,7 +50,9 @@
extern char datatoc_gpu_shader_depth_only_frag_glsl[];
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_checker_frag_glsl[];
+extern char datatoc_gpu_shader_diag_stripes_frag_glsl[];
extern char datatoc_gpu_shader_simple_lighting_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[];
extern char datatoc_gpu_shader_2D_vert_glsl[];
@@ -61,6 +63,7 @@ extern char datatoc_gpu_shader_2D_image_vert_glsl[];
extern char datatoc_gpu_shader_3D_image_vert_glsl[];
extern char datatoc_gpu_shader_image_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[];
extern char datatoc_gpu_shader_image_interlace_frag_glsl[];
extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
@@ -75,25 +78,34 @@ extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
extern char datatoc_gpu_shader_instance_vert_glsl[];
extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl[];
extern char datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_screen_aligned_axis_name_vert_glsl[];
+extern char datatoc_gpu_shader_instance_camera_vert_glsl[];
+extern char datatoc_gpu_shader_instance_distance_line_vert_glsl[];
+extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
+extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
-extern char datatoc_gpu_shader_point_uniform_color_smooth_frag_glsl[];
-extern char datatoc_gpu_shader_point_uniform_color_outline_smooth_frag_glsl[];
-extern char datatoc_gpu_shader_point_varying_color_outline_smooth_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl[];
extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_point_varying_size_vert_glsl[];
extern char datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl[];
-extern char datatoc_gpu_shader_3D_point_uniform_size_smooth_vert_glsl[];
-extern char datatoc_gpu_shader_3D_point_uniform_size_outline_smooth_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_uniform_size_outline_aa_vert_glsl[];
extern char datatoc_gpu_shader_2D_point_varying_size_varying_color_vert_glsl[];
-extern char datatoc_gpu_shader_2D_point_uniform_size_smooth_vert_glsl[];
-extern char datatoc_gpu_shader_2D_point_uniform_size_outline_smooth_vert_glsl[];
-extern char datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_smooth_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl[];
+
+extern char datatoc_gpu_shader_2D_line_dashed_vert_glsl[];
+extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[];
extern char datatoc_gpu_shader_edges_front_back_persp_vert_glsl[];
extern char datatoc_gpu_shader_edges_front_back_persp_geom_glsl[];
@@ -115,7 +127,7 @@ extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
-extern char datatoc_gpu_shader_fx_vert_glsl[];
+extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
@@ -484,6 +496,8 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
}
#endif
+ shader->interface = ShaderInterface_create(shader->program);
+
return shader;
}
@@ -492,6 +506,7 @@ void GPU_shader_bind(GPUShader *shader)
BLI_assert(shader && shader->program);
glUseProgram(shader->program);
+ gpuBindMatrices(shader->program);
}
void GPU_shader_unbind(void)
@@ -515,6 +530,9 @@ void GPU_shader_free(GPUShader *shader)
if (shader->uniform_interface)
MEM_freeN(shader->uniform_interface);
+ if (shader->interface)
+ ShaderInterface_discard(shader->interface);
+
MEM_freeN(shader);
}
@@ -532,18 +550,23 @@ int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
return glGetUniformBlockIndex(shader->program, name);
}
-void *GPU_shader_get_interface(GPUShader *shader)
+void *GPU_fx_shader_get_interface(GPUShader *shader)
{
return shader->uniform_interface;
}
+void *GPU_shader_get_interface(GPUShader *shader)
+{
+ return shader->interface;
+}
+
/* Clement : Temp */
int GPU_shader_get_program(GPUShader *shader)
{
return (int)shader->program;
}
-void GPU_shader_set_interface(GPUShader *shader, void *interface)
+void GPU_fx_shader_set_interface(GPUShader *shader, void *interface)
{
shader->uniform_interface = interface;
}
@@ -665,6 +688,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_edges_overlay_frag_glsl,
datatoc_gpu_shader_edges_overlay_geom_glsl },
[GPU_SHADER_SIMPLE_LIGHTING] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_simple_lighting_frag_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl },
[GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_image_vert_glsl,
datatoc_gpu_shader_image_mask_uniform_color_frag_glsl },
@@ -679,6 +703,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_image_interlace_frag_glsl },
[GPU_SHADER_2D_CHECKER] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_checker_frag_glsl },
+ [GPU_SHADER_2D_DIAG_STRIPES] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_diag_stripes_frag_glsl },
+
[GPU_SHADER_2D_UNIFORM_COLOR] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_2D_FLAT_COLOR] = { datatoc_gpu_shader_2D_flat_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
@@ -686,6 +712,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_2D_smooth_color_frag_glsl },
[GPU_SHADER_2D_IMAGE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_shuffle_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
@@ -700,23 +728,38 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl,
datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_2D_LINE_DASHED_COLOR] = { datatoc_gpu_shader_2D_line_dashed_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl },
+
+ [GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR] =
+ { datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_frag_glsl},
+ [GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR] = { datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
[GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR] = { datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] = { datatoc_gpu_shader_instance_screen_aligned_axis_name_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+
+ [GPU_SHADER_CAMERA] = { datatoc_gpu_shader_instance_camera_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_DISTANCE_LINES] = { datatoc_gpu_shader_instance_distance_line_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
[GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR] =
{ datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
[GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR] =
{ datatoc_gpu_shader_2D_point_varying_size_varying_color_vert_glsl,
datatoc_gpu_shader_point_varying_color_frag_glsl },
- [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH] =
- { datatoc_gpu_shader_2D_point_uniform_size_smooth_vert_glsl,
- datatoc_gpu_shader_point_uniform_color_smooth_frag_glsl },
- [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH] =
- { datatoc_gpu_shader_2D_point_uniform_size_outline_smooth_vert_glsl,
- datatoc_gpu_shader_point_uniform_color_outline_smooth_frag_glsl },
- [GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_SMOOTH] =
- { datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_smooth_vert_glsl,
- datatoc_gpu_shader_point_varying_color_outline_smooth_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_aa_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl },
[GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl,
datatoc_gpu_shader_point_uniform_color_frag_glsl },
[GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR] = { datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl,
@@ -726,23 +769,27 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR] =
{ datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl,
datatoc_gpu_shader_point_varying_color_frag_glsl },
- [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH] =
- { datatoc_gpu_shader_3D_point_uniform_size_smooth_vert_glsl,
- datatoc_gpu_shader_point_uniform_color_smooth_frag_glsl },
- [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH] =
- { datatoc_gpu_shader_3D_point_uniform_size_outline_smooth_vert_glsl,
- datatoc_gpu_shader_point_uniform_color_outline_smooth_frag_glsl },
+ [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
+ { datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_aa_frag_glsl },
+ [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_3D_point_uniform_size_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
[GPU_SHADER_INSTANCE_UNIFORM_COLOR] = { datatoc_gpu_shader_instance_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE] =
{ datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR] = { datatoc_gpu_shader_instance_edges_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_gpu_shader_instance_edges_variying_color_geom_glsl},
};
if (builtin_shaders[shader] == NULL) {
/* just a few special cases */
const char *defines = (shader == GPU_SHADER_SMOKE_COBA) ? "#define USE_COBA;\n" :
- (shader == GPU_SHADER_SIMPLE_LIGHTING) ? "#define USE_NORMALS;\n" : NULL;
+ (shader == GPU_SHADER_SIMPLE_LIGHTING) ? "#define USE_NORMALS;\n" :
+ (shader == GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR) ? "#define USE_INSTANCE_COLOR;\n" : NULL;
const GPUShaderStages *stages = builtin_shader_stages + shader;
@@ -754,14 +801,6 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
stages = &legacy_fancy_edges;
}
- if (shader == GPU_SHADER_EDGES_FRONT_BACK_PERSP && !GLEW_VERSION_3_2) {
- /* TODO: remove after switch to core profile (maybe) */
- static const GPUShaderStages legacy_fancy_edges =
- { datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl,
- datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl };
- stages = &legacy_fancy_edges;
- }
-
/* common case */
builtin_shaders[shader] = GPU_shader_create(stages->vert, stages->frag, stages->geom,
NULL, defines, 0, 0, 0);
@@ -792,7 +831,7 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effect, bool persp)
switch (effect) {
case GPU_SHADER_FX_SSAO:
- shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
break;
case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
@@ -837,7 +876,7 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effect, bool persp)
break;
case GPU_SHADER_FX_DEPTH_RESOLVE:
- shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
+ shader = GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
break;
}
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h
index d5193e09aa4..10ffc17f0d5 100644
--- a/source/blender/gpu/intern/gpu_shader_private.h
+++ b/source/blender/gpu/intern/gpu_shader_private.h
@@ -25,6 +25,7 @@
#pragma once
#include "GPU_glew.h"
+#include "gawain/shader_interface.h"
struct GPUShader {
GLuint program; /* handle for full program (links shader stages below) */
@@ -33,8 +34,8 @@ struct GPUShader {
GLuint geometry; /* handle for geometry shader */
GLuint fragment; /* handle for fragment shader */
- int totattrib; /* total number of attributes */
- int uniforms; /* required uniforms */
-
void *uniform_interface; /* cached uniform interface for shader. Data depends on shader */
+ /* NOTE: ^-- only FX compositing shaders use this */
+
+ ShaderInterface *interface; /* cached uniform & attrib interface for shader */
};
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 3513250993e..88dbe0c2ed9 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -62,19 +62,30 @@ struct GPUTexture {
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
int fb_attachment; /* slot the texture is attached to */
bool depth; /* is a depth texture? */
+ bool stencil; /* is a stencil texture? */
};
-static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, GLenum *format, bool *is_depth)
+static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, GLenum *format, GLenum *data_format, bool *is_depth, bool *is_stencil)
{
if (data_type == GPU_DEPTH_COMPONENT24 ||
data_type == GPU_DEPTH_COMPONENT16 ||
data_type == GPU_DEPTH_COMPONENT32F)
{
*is_depth = true;
+ *is_stencil = false;
+ *data_format = GL_FLOAT;
*format = GL_DEPTH_COMPONENT;
}
+ else if (data_type == GPU_DEPTH24_STENCIL8) {
+ *is_depth = true;
+ *is_stencil = true;
+ *data_format = GL_UNSIGNED_INT_24_8;
+ *format = GL_DEPTH_STENCIL;
+ }
else {
*is_depth = false;
+ *is_stencil = false;
+ *data_format = GL_FLOAT;
switch (components) {
case 1: *format = GL_RED; break;
@@ -93,9 +104,10 @@ static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type,
case GPU_RG32F: return GL_RG32F;
case GPU_RG16F: return GL_RG16F;
case GPU_RGBA8: return GL_RGBA8;
+ case GPU_R16F: return GL_R16F;
case GPU_R8: return GL_R8;
/* Special formats texture & renderbuffer */
- /* ** Add Format here **/
+ case GPU_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
/* Texture only format */
/* ** Add Format here **/
/* Special formats texture only */
@@ -148,20 +160,20 @@ static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int c
/* This tries to allocate video memory for a given texture
* If alloc fails, lower the resolution until it fits. */
static bool GPU_texture_try_alloc(
- GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, int channels,
- bool try_rescale, const float *fpixels, float **rescaled_fpixels)
+ GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, GLenum data_format,
+ int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
{
int r_width;
switch (proxy) {
case GL_PROXY_TEXTURE_1D:
- glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, GL_FLOAT, NULL);
+ glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
break;
case GL_PROXY_TEXTURE_2D:
- glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, NULL);
+ glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
break;
case GL_PROXY_TEXTURE_3D:
- glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, NULL);
+ glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
break;
}
@@ -182,11 +194,11 @@ static bool GPU_texture_try_alloc(
if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
if (proxy == GL_PROXY_TEXTURE_1D)
- glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, GL_FLOAT, NULL);
+ glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
else if (proxy == GL_PROXY_TEXTURE_2D)
- glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, NULL);
+ glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
else if (proxy == GL_PROXY_TEXTURE_3D)
- glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, NULL);
+ glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
}
@@ -213,7 +225,7 @@ static GPUTexture *GPU_texture_create_nD(
GPUTextureFormat data_type, int components, int samples,
const bool can_rescale, char err_out[256])
{
- GLenum format, internalformat, proxy;
+ GLenum format, internalformat, proxy, data_format;
float *rescaled_fpixels = NULL;
const float *pix;
bool valid;
@@ -228,6 +240,7 @@ static GPUTexture *GPU_texture_create_nD(
tex->d = d;
tex->number = -1;
tex->refcount = 1;
+ tex->fb_attachment = -1;
if (n == 1) {
if (h == 0)
@@ -245,12 +258,10 @@ static GPUTexture *GPU_texture_create_nD(
tex->target_base = tex->target = GL_TEXTURE_3D;
}
- tex->fb_attachment = -1;
-
if (samples && n == 2 && d == 0)
tex->target = GL_TEXTURE_2D_MULTISAMPLE;
- internalformat = GPU_texture_get_format(components, data_type, &format, &tex->depth);
+ internalformat = GPU_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil);
/* Generate Texture object */
glGenTextures(1, &tex->bindcode);
@@ -278,7 +289,7 @@ static GPUTexture *GPU_texture_create_nD(
proxy = GL_PROXY_TEXTURE_1D;
}
- valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, components, can_rescale, fpixels,
+ valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, data_format, components, can_rescale, fpixels,
&rescaled_fpixels);
if (!valid) {
@@ -294,7 +305,7 @@ static GPUTexture *GPU_texture_create_nD(
pix = (rescaled_fpixels) ? rescaled_fpixels : fpixels;
if (tex->target == GL_TEXTURE_1D) {
- glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, GL_FLOAT, pix);
+ glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, data_format, pix);
}
else if (tex->target == GL_TEXTURE_1D_ARRAY ||
tex->target == GL_TEXTURE_2D ||
@@ -303,14 +314,14 @@ static GPUTexture *GPU_texture_create_nD(
if (samples) {
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
if (pix)
- glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, GL_FLOAT, pix);
+ glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pix);
}
else {
- glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, pix);
+ glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, data_format, pix);
}
}
else {
- glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, pix);
+ glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, pix);
}
if (rescaled_fpixels)
@@ -494,6 +505,11 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, 0, false, err_out);
}
+GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256])
+{
+ return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH24_STENCIL8, 1, 0, false, err_out);
+}
+
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256])
{
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, samples, false, err_out);
@@ -708,11 +724,16 @@ int GPU_texture_height(const GPUTexture *tex)
return tex->h;
}
-int GPU_texture_depth(const GPUTexture *tex)
+bool GPU_texture_depth(const GPUTexture *tex)
{
return tex->depth;
}
+bool GPU_texture_stencil(const GPUTexture *tex)
+{
+ return tex->stencil;
+}
+
int GPU_texture_opengl_bindcode(const GPUTexture *tex)
{
return tex->bindcode;
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 62ba06b7a0a..7c2cb8cd4bb 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -33,11 +33,14 @@
#include <string.h>
+#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "DNA_vec_types.h"
+#include "BKE_global.h"
+
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_immediate.h"
@@ -55,98 +58,172 @@ struct GPUViewport {
GPUTexture *debug_depth;
int size[2];
- /* Viewport Buffer Storage */
- /* TODO indentify to what engine conf are theses buffers */
- DefaultFramebufferList *fbl;
- DefaultTextureList *txl;
- DefaultPassList *psl;
- StorageList *stl;
+ ListBase data; /* ViewportEngineData wrapped in LinkData */
+ unsigned int data_hash; /* If hash mismatch we free all ViewportEngineData in this viewport */
- char engine_name[32];
+ FramebufferList *fbl;
+ TextureList *txl;
};
-static void GPU_viewport_buffers_free(GPUViewport *viewport);
-static void GPU_viewport_passes_free(GPUViewport *viewport);
-static void GPU_viewport_storage_free(GPUViewport *viewport);
+static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl);
+static void GPU_viewport_storage_free(StorageList *stl);
+static void GPU_viewport_passes_free(PassList *psl);
GPUViewport *GPU_viewport_create(void)
{
GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport");
viewport->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList");
- viewport->psl = MEM_callocN(sizeof(PassList), "PassList");
- viewport->stl = MEM_callocN(sizeof(StorageList), "StorageList");
viewport->size[0] = viewport->size[1] = -1;
return viewport;
}
-void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str)
+void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
{
- *fbs = viewport->fbl;
- *txs = viewport->txl;
- *pss = viewport->psl;
- *str = viewport->stl;
+ LinkData *ld = MEM_callocN(sizeof(LinkData), "LinkData");
+ ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
+ data->engine_type = engine_type;
+
+ data->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
+ data->txl = MEM_callocN(sizeof(TextureList), "TextureList");
+ data->psl = MEM_callocN(sizeof(PassList), "PassList");
+ data->stl = MEM_callocN(sizeof(StorageList), "StorageList");
+
+ ld->data = data;
+ BLI_addtail(&viewport->data, ld);
+
+ return data;
}
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine)
+static void GPU_viewport_engines_data_free(GPUViewport *viewport)
{
- /* add one pixel because of scissor test */
- int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
+ LinkData *next;
+ for (LinkData *link = viewport->data.first; link; link = next) {
+ next = link->next;
+ ViewportEngineData *data = link->data;
-#ifndef WITH_VIEWPORT_CACHE_TEST
- /* TODO for testing only, we need proper cache invalidation */
- GPU_viewport_passes_free(viewport);
-#endif
+ GPU_viewport_buffers_free(data->fbl, data->txl);
+ GPU_viewport_passes_free(data->psl);
+ GPU_viewport_storage_free(data->stl);
+
+ MEM_freeN(data->fbl);
+ MEM_freeN(data->txl);
+ MEM_freeN(data->psl);
+ MEM_freeN(data->stl);
+
+ MEM_freeN(data);
+
+ BLI_remlink(&viewport->data, link);
+ MEM_freeN(link);
+ }
+}
+
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type)
+{
+ for (LinkData *link = viewport->data.first; link; link = link->next) {
+ ViewportEngineData *vdata = link->data;
+ if (vdata->engine_type == engine_type) {
+ return vdata;
+ }
+ }
+ return NULL;
+}
+
+void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport)
+{
+ return viewport->fbl;
+}
- if (!STREQ(engine, viewport->engine_name)) {
- GPU_viewport_storage_free(viewport);
- GPU_viewport_buffers_free(viewport);
+void *GPU_viewport_texture_list_get(GPUViewport *viewport)
+{
+ return viewport->txl;
+}
+
+void GPU_viewport_size_get(GPUViewport *viewport, int *size)
+{
+ size[0] = viewport->size[0];
+ size[1] = viewport->size[1];
+}
+
+bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash)
+{
+ bool dirty = false;
+
+ /* TODO for testing only, we need proper cache invalidation */
+ if (G.debug_value != 666 && G.debug_value != 667) {
+ for (LinkData *link = viewport->data.first; link; link = link->next) {
+ ViewportEngineData *data = link->data;
+ GPU_viewport_passes_free(data->psl);
+ }
+ dirty = true;
+ }
- BLI_strncpy(viewport->engine_name, engine, 32);
+ if (viewport->data_hash != hash) {
+ GPU_viewport_engines_data_free(viewport);
+ dirty = true;
}
- if (viewport->fbl->default_fb) {
+ viewport->data_hash = hash;
+
+ return dirty;
+}
+
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
+{
+ DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
+ DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
+
+ /* add one pixel because of scissor test */
+ int rect_w = BLI_rcti_size_x(rect) + 1;
+ int rect_h = BLI_rcti_size_y(rect) + 1;
+
+ if (dfbl->default_fb) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
- GPU_viewport_buffers_free(viewport);
+ GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
+
+ for (LinkData *link = viewport->data.first; link; link = link->next) {
+ ViewportEngineData *data = link->data;
+ GPU_viewport_buffers_free(data->fbl, data->txl);
+ }
}
}
- if (!viewport->fbl->default_fb) {
+ if (!dfbl->default_fb) {
bool ok = true;
viewport->size[0] = rect_w;
viewport->size[1] = rect_h;
- viewport->fbl->default_fb = GPU_framebuffer_create();
- if (!viewport->fbl->default_fb) {
+ dfbl->default_fb = GPU_framebuffer_create();
+ if (!dfbl->default_fb) {
ok = false;
goto cleanup;
}
/* Color */
/* No multi samples for now */
- viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
- if (!viewport->txl->color) {
+ dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
+ if (!dtxl->color) {
ok = false;
goto cleanup;
}
- if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) {
+ if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->color, 0)) {
ok = false;
goto cleanup;
}
/* Depth */
- viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
- if (!viewport->txl->depth) {
+ dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
+ if (!dtxl->depth) {
ok = false;
goto cleanup;
}
- else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) {
+ else if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0)) {
ok = false;
goto cleanup;
}
- else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) {
+ else if (!GPU_framebuffer_check_valid(dfbl->default_fb, NULL)) {
ok = false;
goto cleanup;
}
@@ -161,12 +238,14 @@ cleanup:
GPU_framebuffer_restore();
}
- GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0);
+ GPU_framebuffer_slots_bind(dfbl->default_fb, 0);
}
static void draw_ofs_to_screen(GPUViewport *viewport)
{
- GPUTexture *color = viewport->txl->color;
+ DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
+
+ GPUTexture *color = dtxl->color;
const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color);
@@ -176,12 +255,11 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
-
GPU_texture_bind(color, 0);
immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
- immBegin(GL_QUADS, 4);
+ immBegin(GL_TRIANGLE_STRIP, 4);
immAttrib2f(texcoord, 0.0f, 0.0f);
immVertex2f(pos, 0.0f, 0.0f);
@@ -189,12 +267,12 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
immAttrib2f(texcoord, 1.0f, 0.0f);
immVertex2f(pos, w, 0.0f);
- immAttrib2f(texcoord, 1.0f, 1.0f);
- immVertex2f(pos, w, h);
-
immAttrib2f(texcoord, 0.0f, 1.0f);
immVertex2f(pos, 0.0f, h);
+ immAttrib2f(texcoord, 1.0f, 1.0f);
+ immVertex2f(pos, w, h);
+
immEnd();
GPU_texture_unbind(color);
@@ -204,21 +282,22 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
void GPU_viewport_unbind(GPUViewport *viewport)
{
- if (viewport->fbl->default_fb) {
+ DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
+
+ if (dfbl->default_fb) {
GPU_framebuffer_texture_unbind(NULL, NULL);
GPU_framebuffer_restore();
glEnable(GL_SCISSOR_TEST);
+ glDisable(GL_DEPTH_TEST);
/* This might be bandwidth limiting */
draw_ofs_to_screen(viewport);
}
}
-static void GPU_viewport_buffers_free(GPUViewport *viewport)
+static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl)
{
- FramebufferList *fbl = (FramebufferList *)viewport->fbl;
- TextureList *txl = (TextureList *)viewport->txl;
int i;
for (i = MAX_BUFFERS - 1; i > -1; --i) {
GPUFrameBuffer *fb = fbl->framebuffers[i];
@@ -236,10 +315,8 @@ static void GPU_viewport_buffers_free(GPUViewport *viewport)
}
}
-static void GPU_viewport_storage_free(GPUViewport *viewport)
+static void GPU_viewport_storage_free(StorageList *stl)
{
- StorageList *stl = (StorageList *)viewport->stl;
-
for (int i = MAX_STORAGE - 1; i > -1; --i) {
void *storage = stl->storage[i];
if (storage) {
@@ -249,12 +326,9 @@ static void GPU_viewport_storage_free(GPUViewport *viewport)
}
}
-static void GPU_viewport_passes_free(GPUViewport *viewport)
+static void GPU_viewport_passes_free(PassList *psl)
{
- PassList *psl = (PassList *)viewport->psl;
- int i;
-
- for (i = MAX_PASSES - 1; i > -1; --i) {
+ for (int i = MAX_PASSES - 1; i > -1; --i) {
struct DRWPass *pass = psl->passes[i];
if (pass) {
DRW_pass_free(pass);
@@ -266,15 +340,13 @@ static void GPU_viewport_passes_free(GPUViewport *viewport)
void GPU_viewport_free(GPUViewport *viewport)
{
- GPU_viewport_debug_depth_free(viewport);
- GPU_viewport_buffers_free(viewport);
- GPU_viewport_passes_free(viewport);
- GPU_viewport_storage_free(viewport);
+ GPU_viewport_engines_data_free(viewport);
+ GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
MEM_freeN(viewport->fbl);
MEM_freeN(viewport->txl);
- MEM_freeN(viewport->psl);
- MEM_freeN(viewport->stl);
+
+ GPU_viewport_debug_depth_free(viewport);
}
/****************** debug ********************/
@@ -320,7 +392,7 @@ void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, con
immUniform1f("zfar", zfar);
immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
- immBegin(GL_QUADS, 4);
+ immBegin(GL_TRIANGLE_STRIP, 4);
immAttrib2f(texcoord, 0.0f, 0.0f);
immVertex2f(pos, 0.0f, 0.0f);
@@ -328,12 +400,12 @@ void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, con
immAttrib2f(texcoord, 1.0f, 0.0f);
immVertex2f(pos, w, 0.0f);
- immAttrib2f(texcoord, 1.0f, 1.0f);
- immVertex2f(pos, w, h);
-
immAttrib2f(texcoord, 0.0f, 1.0f);
immVertex2f(pos, 0.0f, h);
+ immAttrib2f(texcoord, 1.0f, 1.0f);
+ immVertex2f(pos, w, h);
+
immEnd();
GPU_texture_unbind(viewport->debug_depth);
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl
index a6c00b080b2..f5217a9d238 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl
@@ -1,6 +1,7 @@
uniform mat4 ModelViewProjectionMatrix;
+/* Keep in sync with intern/opencolorio/gpu_shader_display_transform_vertex.glsl */
#if __VERSION__ == 120
attribute vec2 texCoord;
attribute vec2 pos;
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl
new file mode 100644
index 00000000000..85aab7e06ef
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl
@@ -0,0 +1,25 @@
+
+// Draw dashed lines, perforated in screen space.
+// Based on a (3D) version by Mike Erwin.
+
+#if __VERSION__ == 120
+ noperspective varying float distance_along_line;
+ #define fragColor gl_FragColor
+#else
+ noperspective in float distance_along_line;
+ out vec4 fragColor;
+#endif
+
+uniform float dash_width;
+uniform float dash_width_on;
+uniform vec4 color1;
+uniform vec4 color2;
+
+void main()
+{
+ if (mod(distance_along_line, dash_width) <= dash_width_on) {
+ fragColor = color1;
+ } else {
+ fragColor = color2;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl
new file mode 100644
index 00000000000..7b4207142e6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl
@@ -0,0 +1,22 @@
+
+// Draw dashed lines, perforated in screen space.
+// Based on a (3D) version by Mike Erwin.
+
+uniform mat4 ModelViewProjectionMatrix;
+
+#if __VERSION__ == 120
+ attribute vec2 pos;
+ attribute vec2 line_origin; // = pos for one vertex of the line
+ noperspective varying float distance_along_line;
+#else
+ in vec2 pos;
+ in vec2 line_origin;
+ noperspective out float distance_along_line;
+#endif
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+
+ distance_along_line = distance(line_origin, pos);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_smooth_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl
index 201e5e90ecc..201e5e90ecc 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_smooth_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_smooth_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl
index a37ae16f837..a37ae16f837 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_smooth_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_smooth_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl
index d3a142cc7bd..d3a142cc7bd 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_smooth_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_smooth_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl
index 287f95b48ab..287f95b48ab 100644
--- a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_smooth_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_smooth_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl
index d05920002ed..d05920002ed 100644
--- a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_smooth_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
index a0141f1ab2c..5f7455582cd 100644
--- a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
@@ -21,6 +21,10 @@
#define STIPPLE_DIAG_STRIPES 4
#define STIPPLE_DIAG_STRIPES_SWAP 5
+#ifndef NO_SPECULAR
+uniform mat4 ProjectionMatrix;
+#endif
+
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
#if defined(USE_FLAT_NORMAL)
varying vec3 eyespace_vert_pos;
@@ -163,7 +167,7 @@ void main()
#ifndef NO_SPECULAR
/* view vector computation, depends on orthographics or perspective */
- vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
+ vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
#endif
for (int i = 0; i < NUM_SCENE_LIGHTS; i++) {
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
index 42fbdadf1d1..dbf6c267f14 100644
--- a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
@@ -1,4 +1,8 @@
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat3 NormalMatrix;
+
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
#if defined(USE_FLAT_NORMAL)
varying vec3 eyespace_vert_pos;
@@ -29,15 +33,15 @@ varying float gl_ClipDistance[6];
void main()
{
- vec4 co = gl_ModelViewMatrix * gl_Vertex;
+ vec4 co = ModelViewMatrix * gl_Vertex;
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
#if !defined(USE_FLAT_NORMAL)
- varying_normal = normalize(gl_NormalMatrix * gl_Normal);
+ varying_normal = normalize(NormalMatrix * gl_Normal);
#endif
#if defined(USE_FLAT_NORMAL)
/* transform vertex into eyespace */
- eyespace_vert_pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
+ eyespace_vert_pos = (ModelViewMatrix * gl_Vertex).xyz;
#endif
#ifndef USE_SOLID_LIGHTING
@@ -45,7 +49,7 @@ void main()
#endif
#endif
- gl_Position = gl_ProjectionMatrix * co;
+ gl_Position = ProjectionMatrix * co;
#ifdef CLIP_WORKAROUND
int i;
diff --git a/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl b/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl
new file mode 100644
index 00000000000..74cf1c5a3dc
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl
@@ -0,0 +1,24 @@
+
+uniform vec4 color1;
+uniform vec4 color2;
+uniform int size1;
+uniform int size2;
+
+#if __VERSION__ == 120
+ #define fragColor gl_FragColor
+#else
+ out vec4 fragColor;
+#endif
+
+void main()
+{
+ float phase = mod((gl_FragCoord.x + gl_FragCoord.y), (size1 + size2));
+
+ if (phase < size1)
+ {
+ fragColor = color1;
+ }
+ else {
+ fragColor = color2;
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
index 71a43d1b7ae..fb1d0aafe05 100644
--- a/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
@@ -1,5 +1,5 @@
-//mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelViewProjectionMatrix;
in vec3 pos;
in float edgeWidthModulator;
@@ -8,6 +8,6 @@ out vec4 pos_xformed;
out float widthModulator;
void main() {
- pos_xformed = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);
+ pos_xformed = ModelViewProjectionMatrix * vec4(pos, 1.0);
widthModulator = edgeWidthModulator;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
index 3819203bcd9..45f86e036a1 100644
--- a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
@@ -1,5 +1,13 @@
-varying vec3 coords;
+#if __VERSION__ == 120
+ varying vec3 coords;
+ #define fragColor gl_FragColor
+#else
+ in vec3 coords;
+ out vec4 fragColor;
+ #define texture1D texture
+ #define texture3D texture
+#endif
uniform sampler3D flame_texture;
uniform sampler1D spectrum_texture;
@@ -13,5 +21,5 @@ void main()
color.rgb = emission.a * emission.rgb;
color.a = emission.a;
- gl_FragColor = color;
+ fragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl
new file mode 100644
index 00000000000..cf2d28343cc
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl
@@ -0,0 +1,16 @@
+
+#if __VERSION__ == 120
+ attribute vec2 pos;
+ attribute vec2 uvs;
+ varying vec4 uvcoordsvar;
+#else
+ in vec2 pos;
+ in vec2 uvs;
+ out vec4 uvcoordsvar;
+#endif
+
+void main()
+{
+ uvcoordsvar = vec4(uvs, 0.0, 0.0);
+ gl_Position = vec4(pos, 0.0, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
index e04cd7d3306..3ba455d34e7 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
@@ -1,5 +1,10 @@
uniform sampler2D depthbuffer;
-varying vec4 uvcoordsvar;
+
+#if __VERSION__ == 120
+ varying vec4 uvcoordsvar;
+#else
+ in vec4 uvcoordsvar;
+#endif
void main(void)
{
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
index 338ef6d51a7..6b3f1b99594 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -16,17 +16,35 @@ uniform vec4 dof_params;
// viewvectors for reconstruction of world space
uniform vec4 viewvecs[3];
-// coordinates on framebuffer in normalized (0.0-1.0) uv space
-varying vec4 uvcoordsvar;
-
-/* color texture coordinates, offset by a small amount */
-varying vec2 color_uv1;
-varying vec2 color_uv2;
-
-varying vec2 depth_uv1;
-varying vec2 depth_uv2;
-varying vec2 depth_uv3;
-varying vec2 depth_uv4;
+#if __VERSION__ == 120
+ // coordinates on framebuffer in normalized (0.0-1.0) uv space
+ varying vec4 uvcoordsvar;
+
+ /* color texture coordinates, offset by a small amount */
+ varying vec2 color_uv1;
+ varying vec2 color_uv2;
+
+ varying vec2 depth_uv1;
+ varying vec2 depth_uv2;
+ varying vec2 depth_uv3;
+ varying vec2 depth_uv4;
+
+ #define FragColor gl_FragColor
+#else
+ // coordinates on framebuffer in normalized (0.0-1.0) uv space
+ in vec4 uvcoordsvar;
+
+ /* color texture coordinates, offset by a small amount */
+ in vec2 color_uv1;
+ in vec2 color_uv2;
+
+ in vec2 depth_uv1;
+ in vec2 depth_uv2;
+ in vec2 depth_uv3;
+ in vec2 depth_uv4;
+
+ out vec4 FragColor;
+#endif
float calculate_far_coc(in float zdepth)
@@ -102,7 +120,7 @@ void first_pass()
coc = max(calculate_near_coc(zdepth), coc);
final_coc = max(max(coc.x, coc.y), max(coc.z, coc.w));
- gl_FragColor = vec4(color.rgb, final_coc);
+ FragColor = vec4(color.rgb, final_coc);
}
/* second pass, gaussian blur the downsampled image */
@@ -119,7 +137,7 @@ void second_pass()
color += texture2D(colorbuffer, uvcoordsvar.xy - 2.5 * invrendertargetdim) * 0.09375;
color += texture2D(colorbuffer, uvcoordsvar.xy - 4.5 * invrendertargetdim) * 0.015625;
- gl_FragColor = color;
+ FragColor = color;
}
@@ -129,7 +147,7 @@ void third_pass()
vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
vec4 color_blurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy);
float coc = 2.0 * max(color_blurred.a, color.a); -color.a;
- gl_FragColor = vec4(color.rgb, coc);
+ FragColor = vec4(color.rgb, coc);
}
@@ -141,7 +159,7 @@ void fourth_pass()
color += texture2D(colorbuffer, uvcoordsvar.xw);
color += texture2D(colorbuffer, uvcoordsvar.yw);
- gl_FragColor = color / 4.0;
+ FragColor = color / 4.0;
}
vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
@@ -188,7 +206,7 @@ void fifth_pass()
color /= dot(factors, vec4(1.0));
/* using original color is not correct, but use that for now because alpha of
* blurred buffers uses CoC instead */
- gl_FragColor = vec4(color.rgb, color_orig.a);
+ FragColor = vec4(color.rgb, color_orig.a);
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
index 182113367d3..46feb91de6e 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
@@ -20,18 +20,42 @@ uniform vec4 dof_params;
/* viewvectors for reconstruction of world space */
uniform vec4 viewvecs[3];
-/* initial uv coordinate */
-varying vec2 uvcoord;
-
-/* coordinate used for calculating radius et al set in geometry shader */
-varying vec2 particlecoord;
-varying vec4 color;
+#if __VERSION__ == 120
+ /* initial uv coordinate */
+ varying vec2 uvcoord;
+
+ /* coordinate used for calculating radius et al set in geometry shader */
+ varying vec2 particlecoord;
+ varying vec4 color;
+
+ /* downsampling coordinates */
+ varying vec2 downsample1;
+ varying vec2 downsample2;
+ varying vec2 downsample3;
+ varying vec2 downsample4;
+
+ #define fragData0 gl_FragData[0]
+ #define fragData1 gl_FragData[1]
+ #define fragData2 gl_FragData[2]
+#else
+ /* initial uv coordinate */
+ in vec2 uvcoord;
+
+ /* coordinate used for calculating radius et al set in geometry shader */
+ in vec2 particlecoord;
+ flat in vec4 color;
+
+ /* downsampling coordinates */
+ in vec2 downsample1;
+ in vec2 downsample2;
+ in vec2 downsample3;
+ in vec2 downsample4;
+
+ layout(location = 0) out vec4 fragData0;
+ layout(location = 1) out vec4 fragData1;
+ layout(location = 2) out vec4 fragData2;
+#endif
-/* downsampling coordinates */
-varying vec2 downsample1;
-varying vec2 downsample2;
-varying vec2 downsample3;
-varying vec2 downsample4;
#define M_PI 3.1415926535897932384626433832795
@@ -82,16 +106,16 @@ void downsample_pass()
float norm_far = dot(far_weights, vec4(1.0));
/* now write output to weighted buffers. */
- gl_FragData[0] = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z +
+ fragData0 = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z +
color4 * near_weights.w;
- gl_FragData[1] = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z +
+ fragData1 = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z +
color4 * far_weights.w;
if (norm_near > 0.0)
- gl_FragData[0] /= norm_near;
+ fragData0 /= norm_near;
if (norm_far > 0.0)
- gl_FragData[1] /= norm_far;
- gl_FragData[2] = vec4(near_coc, far_coc, 0.0, 1.0);
+ fragData1 /= norm_far;
+ fragData2 = vec4(near_coc, far_coc, 0.0, 1.0);
}
/* accumulate color in the near/far blur buffers */
@@ -102,16 +126,16 @@ void accumulate_pass(void) {
if (dof_params.w == 0.0)
r = 1.0;
else
- r = cos(M_PI / dof_params.w) /
- (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI))));
+ r = cos(M_PI / dof_params.w) /
+ (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI))));
if (dot(particlecoord, particlecoord) > r * r)
discard;
- gl_FragData[0] = color;
+ fragData0 = color;
}
-#define MERGE_THRESHOLD 4.0
+#define MERGE_THRESHOLD 4.0
/* combine the passes, */
void final_pass(void) {
vec4 finalcolor;
@@ -152,7 +176,9 @@ void final_pass(void) {
finalcolor = mix(finalcolor, nearcolor, nearweight / totalweight);
}
- gl_FragData[0] = finalcolor;
+ fragData0 = finalcolor;
+ // fragData0 = vec4(nearweight, farweight, 0.0, 1.0);
+ // fragData0 = vec4(nearcolor.rgb, 1.0);
}
void main()
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
index 4c650e7695f..c9a726a007e 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
@@ -24,7 +24,7 @@ uniform sampler2D cocbuffer;
#else
in vec2 uvcoord[];
out vec2 particlecoord;
- out vec4 color;
+ flat out vec4 color;
#endif
#define M_PI 3.1415926535897932384626433832795
@@ -46,21 +46,23 @@ void main()
vec2 offset_far = vec2(offset_val * 0.5) / vec2(rendertargetdim.x, rendertargetdim.y);
- gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
color = colortex;
+
+ gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
particlecoord = vec2(-1.0, -1.0);
EmitVertex();
+
gl_Position = POS + vec4(-offset_far.x, offset_far.y, 0.0, 0.0);
particlecoord = vec2(-1.0, 1.0);
- color = colortex;
EmitVertex();
+
gl_Position = POS + vec4(offset_far.x, -offset_far.y, 0.0, 0.0);
particlecoord = vec2(1.0, -1.0);
- color = colortex;
EmitVertex();
+
gl_Position = POS + vec4(offset_far.x, offset_far.y, 0.0, 0.0);
particlecoord = vec2(1.0, 1.0);
- color = colortex;
EmitVertex();
+
EndPrimitive();
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
index 09a0c75facc..78fe0e563f2 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
@@ -1,27 +1,47 @@
-uniform vec2 invrendertargetdim;
-uniform ivec2 rendertargetdim;
-/* initial uv coordinate */
-varying vec2 uvcoord;
-/* coordinate used for calculating radius et al set in geometry shader */
-varying vec2 particlecoord;
+#if __VERSION__ == 120
+ attribute vec2 pos;
+ attribute vec2 uvs;
+ /* initial uv coordinate */
+ varying vec2 uvcoord;
+
+ /* coordinate used for calculating radius et al set in geometry shader */
+ varying vec2 particlecoord;
+
+ /* downsampling coordinates */
+ varying vec2 downsample1;
+ varying vec2 downsample2;
+ varying vec2 downsample3;
+ varying vec2 downsample4;
+#else
+ in vec2 pos;
+ in vec2 uvs;
+ /* initial uv coordinate */
+ out vec2 uvcoord;
+
+ /* coordinate used for calculating radius et al set in geometry shader */
+ out vec2 particlecoord;
+
+ /* downsampling coordinates */
+ out vec2 downsample1;
+ out vec2 downsample2;
+ out vec2 downsample3;
+ out vec2 downsample4;
+#endif
-/* downsampling coordinates */
-varying vec2 downsample1;
-varying vec2 downsample2;
-varying vec2 downsample3;
-varying vec2 downsample4;
+uniform vec2 invrendertargetdim;
+uniform ivec2 rendertargetdim;
void vert_dof_downsample()
{
/* gather pixels from neighbors. half dimensions means we offset half a pixel to
* get this right though it's possible we may lose a pixel at some point */
- downsample1 = gl_MultiTexCoord0.xy + vec2(-0.5, -0.5) * invrendertargetdim;
- downsample2 = gl_MultiTexCoord0.xy + vec2(-0.5, 0.5) * invrendertargetdim;
- downsample3 = gl_MultiTexCoord0.xy + vec2(0.5, 0.5) * invrendertargetdim;
- downsample4 = gl_MultiTexCoord0.xy + vec2(0.5, -0.5) * invrendertargetdim;
+ downsample1 = uvs.xy + vec2(-0.5, -0.5) * invrendertargetdim;
+ downsample2 = uvs.xy + vec2(-0.5, 0.5) * invrendertargetdim;
+ downsample3 = uvs.xy + vec2(0.5, 0.5) * invrendertargetdim;
+ downsample4 = uvs.xy + vec2(0.5, -0.5) * invrendertargetdim;
- gl_Position = gl_Vertex;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
/* geometry shading pass, calculate a texture coordinate based on the indexed id */
@@ -42,8 +62,8 @@ void vert_dof_coc_scatter_pass()
void vert_dof_final()
{
- uvcoord = gl_MultiTexCoord0.xy;
- gl_Position = gl_Vertex;
+ uvcoord = uvs;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void main()
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
index 63b57d5775c..eb2b6b04da8 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
@@ -1,51 +1,72 @@
uniform vec2 invrendertargetdim;
-//texture coordinates for framebuffer read
-varying vec4 uvcoordsvar;
-/* color texture coordinates, offset by a small amount */
-varying vec2 color_uv1;
-varying vec2 color_uv2;
+#if __VERSION__ == 120
+ attribute vec2 pos;
+ attribute vec2 uvs;
-varying vec2 depth_uv1;
-varying vec2 depth_uv2;
-varying vec2 depth_uv3;
-varying vec2 depth_uv4;
+ //texture coordinates for framebuffer read
+ varying vec4 uvcoordsvar;
+
+ /* color texture coordinates, offset by a small amount */
+ varying vec2 color_uv1;
+ varying vec2 color_uv2;
+
+ varying vec2 depth_uv1;
+ varying vec2 depth_uv2;
+ varying vec2 depth_uv3;
+ varying vec2 depth_uv4;
+#else
+ in vec2 pos;
+ in vec2 uvs;
+
+ //texture coordinates for framebuffer read
+ out vec4 uvcoordsvar;
+
+ /* color texture coordinates, offset by a small amount */
+ out vec2 color_uv1;
+ out vec2 color_uv2;
+
+ out vec2 depth_uv1;
+ out vec2 depth_uv2;
+ out vec2 depth_uv3;
+ out vec2 depth_uv4;
+#endif
//very simple shader for gull screen FX, just pass values on
void vert_generic()
{
- uvcoordsvar = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
+ uvcoordsvar = vec4(uvs, 0.0, 0.0);
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_first_pass()
{
/* we offset the texture coordinates by 1.5 pixel,
* then we reuse that to sample the surrounding pixels */
- color_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
- color_uv2 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
+ color_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim;
+ color_uv2 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim;
- depth_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
- depth_uv2 = gl_MultiTexCoord0.xy + vec2(-0.5, -1.5) * invrendertargetdim;
- depth_uv3 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
- depth_uv4 = gl_MultiTexCoord0.xy + vec2(1.5, -1.5) * invrendertargetdim;
+ depth_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim;
+ depth_uv2 = uvs.xy + vec2(-0.5, -1.5) * invrendertargetdim;
+ depth_uv3 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim;
+ depth_uv4 = uvs.xy + vec2(1.5, -1.5) * invrendertargetdim;
- gl_Position = gl_Vertex;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_fourth_pass()
{
vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
- uvcoordsvar = gl_MultiTexCoord0.xxyy +
+ uvcoordsvar = uvs.xxyy +
halfpixel *
vec4(invrendertargetdim.x,
invrendertargetdim.x,
invrendertargetdim.y,
invrendertargetdim.y);
- gl_Position = gl_Vertex;
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_fifth_pass()
@@ -53,8 +74,8 @@ void vert_dof_fifth_pass()
vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
color_uv1 = vec2(0.5, 1.5) * invrendertargetdim;
- uvcoordsvar = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
+ uvcoordsvar = vec4(uvs, 0.0, 0.0);
+ gl_Position = vec4(pos, 0.0, 1.0);
}
void main()
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
index 1dc49b52be1..7aa6786d292 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
@@ -1,14 +1,17 @@
+uniform mat4 ProjectionMatrix;
+
/* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
* we change the factors from the article to fit the OpennGL model. */
#ifdef PERSP_MATRIX
+
/* perspective camera code */
vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
{
float d = 2.0 * depth - 1.0;
- float zview = -gl_ProjectionMatrix[3][2] / (d + gl_ProjectionMatrix[2][2]);
+ float zview = -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
}
@@ -18,7 +21,7 @@ vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
vec4 d = 2.0 * depth - vec4(1.0);
/* return positive value, so sign differs! */
- return vec4(gl_ProjectionMatrix[3][2]) / (d + vec4(gl_ProjectionMatrix[2][2]));
+ return vec4(ProjectionMatrix[3][2]) / (d + vec4(ProjectionMatrix[2][2]));
}
#else
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
index 50c8e255162..4a6cc09f5ea 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
@@ -1,3 +1,4 @@
+
// color buffer
uniform sampler2D colorbuffer;
@@ -9,8 +10,15 @@ uniform sampler1D ssao_concentric_tex;
// depth buffer
uniform sampler2D depthbuffer;
-// coordinates on framebuffer in normalized (0.0-1.0) uv space
-varying vec4 uvcoordsvar;
+
+#if __VERSION__ == 120
+ // coordinates on framebuffer in normalized (0.0-1.0) uv space
+ varying vec4 uvcoordsvar;
+ #define FragColor gl_FragColor
+#else
+ in vec4 uvcoordsvar;
+ out vec4 FragColor;
+#endif
/* ssao_params.x : pixel scale for the ssao radious */
/* ssao_params.y : factor for the ssao darkening */
@@ -46,9 +54,9 @@ float calculate_ssao_factor(float depth)
/* find the offset in screen space by multiplying a point
* in camera space at the depth of the point by the projection matrix. */
vec2 offset;
- float homcoord = gl_ProjectionMatrix[2][3] * position.z + gl_ProjectionMatrix[3][3];
- offset.x = gl_ProjectionMatrix[0][0] * ssao_params.x / homcoord;
- offset.y = gl_ProjectionMatrix[1][1] * ssao_params.x / homcoord;
+ float homcoord = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3];
+ offset.x = ProjectionMatrix[0][0] * ssao_params.x / homcoord;
+ offset.y = ProjectionMatrix[1][1] * ssao_params.x / homcoord;
/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
offset *= 0.5;
@@ -90,5 +98,5 @@ void main()
float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
vec4 scene_col = texture2D(colorbuffer, uvcoordsvar.xy);
vec3 final_color = mix(scene_col.rgb, ssao_color.rgb, calculate_ssao_factor(depth));
- gl_FragColor = vec4(final_color.rgb, scene_col.a);
+ FragColor = vec4(final_color.rgb, scene_col.a);
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
deleted file mode 100644
index 5194e414520..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-varying vec4 uvcoordsvar;
-
-//very simple shader for full screen FX, just pass values on
-
-void main()
-{
- uvcoordsvar = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
index fe630dbeddb..545910d39ca 100644
--- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
@@ -1,3 +1,6 @@
+
+uniform mat4 ProjectionMatrix;
+
uniform int PrimitiveIdBase;
uniform int osd_active_uv_offset;
@@ -69,7 +72,7 @@ void emit_flat(int index, vec3 normal)
set_mtface_vertex_attrs(st);
- gl_Position = gl_ProjectionMatrix * inpt[index].v.position;
+ gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
@@ -90,7 +93,7 @@ void emit_smooth(int index)
set_mtface_vertex_attrs(st);
- gl_Position = gl_ProjectionMatrix * inpt[index].v.position;
+ gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl
new file mode 100644
index 00000000000..fa4f41b79fb
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl
@@ -0,0 +1,22 @@
+
+#if __VERSION__ == 120
+ varying vec2 texCoord_interp;
+ #define fragColor gl_FragColor
+#else
+ in vec2 texCoord_interp;
+ out vec4 fragColor;
+ #define texture2D texture
+#endif
+
+uniform sampler2D image;
+uniform vec4 color;
+uniform vec4 shuffle;
+
+void main()
+{
+ vec4 sample = texture2D(image, texCoord_interp);
+ fragColor = vec4(sample.r * shuffle.r +
+ sample.g * shuffle.g +
+ sample.b * shuffle.b +
+ sample.a * shuffle.a) * color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl
new file mode 100644
index 00000000000..aec8fd9b0a1
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl
@@ -0,0 +1,50 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in float pos;
+
+/* ---- Per instance Attribs ---- */
+in vec3 color;
+in vec4 corners[2]; /* trouble fetching vec2 */
+in float depth;
+in vec4 tria;
+in mat4 InstanceModelMatrix;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ vec3 pPos;
+
+ if (pos == 1.0) {
+ pPos = vec3(corners[0].xy, depth);
+ }
+ else if (pos == 2.0) {
+ pPos = vec3(corners[0].zw, depth);
+ }
+ else if (pos == 3.0) {
+ pPos = vec3(corners[1].xy, depth);
+ }
+ else if (pos == 4.0) {
+ pPos = vec3(corners[1].zw, depth);
+ }
+ else if (pos == 5.0) {
+ pPos = vec3(tria.xy, depth);
+ }
+ else if (pos == 6.0) {
+ vec2 ofs = tria.xy - corners[0].xy;
+ ofs.x = -ofs.x;
+ pPos = vec3(corners[1].zw + ofs, depth);
+ }
+ else if (pos == 7.0) {
+ pPos = vec3(tria.zw, depth);
+ }
+ else {
+ pPos = vec3(0.0);
+ }
+
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pPos, 1.0);
+
+ finalColor = vec4(color, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl
new file mode 100644
index 00000000000..142df70e68a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl
@@ -0,0 +1,25 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos;
+
+/* ---- Per instance Attribs ---- */
+in vec3 color;
+in float start;
+in float end;
+in mat4 InstanceModelMatrix;
+
+uniform float size;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ float len = end - start;
+ vec3 sta = vec3(0.0, 0.0, -start);
+
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * -len + sta, 1.0);
+ gl_PointSize = size;
+ finalColor = vec4(color, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl
new file mode 100644
index 00000000000..6f580ef3ff6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl
@@ -0,0 +1,57 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. This geometry shader
+// decides which edge type to use if endpoints disagree.
+
+uniform mat4 ProjectionMatrix;
+
+uniform bool drawFront = true;
+uniform bool drawBack = true;
+uniform bool drawSilhouette = true;
+
+layout(lines) in;
+layout(line_strip, max_vertices = 2) out;
+
+in vec4 MV_pos[];
+in float edgeClass[];
+in vec3 fCol[];
+
+flat out vec4 finalColor;
+
+void emitLine(vec4 color)
+{
+ gl_Position = ProjectionMatrix * MV_pos[0];
+ EmitVertex();
+ gl_Position = ProjectionMatrix * MV_pos[1];
+ finalColor = color;
+ EmitVertex();
+ EndPrimitive();
+}
+
+void main()
+{
+ float finalEdgeClass = max(edgeClass[0], edgeClass[1]);
+
+ if (finalEdgeClass > 0.0f) {
+ // front-facing edge
+ if (drawFront)
+ emitLine(vec4(fCol[0], 0.75));
+ }
+ else if (finalEdgeClass < 0.0f) {
+ // back-facing edge
+ if (drawBack)
+ emitLine(vec4(fCol[0], 0.5));
+ }
+ else {
+ // exactly one face is front-facing, silhouette edge
+ if (drawSilhouette)
+ emitLine(vec4(fCol[0], 1.0));
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
new file mode 100644
index 00000000000..5d1e949c1d4
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
@@ -0,0 +1,64 @@
+
+// Draw "fancy" wireframe, displaying front-facing, back-facing and
+// silhouette lines differently.
+// Mike Erwin, April 2015
+
+// After working with this shader a while, convinced we should make
+// separate shaders for perpective & ortho. (Oct 2016)
+
+// Due to perspective, the line segment's endpoints might disagree on
+// whether the adjacent faces are front facing. We use a geometry
+// shader to resolve this properly.
+
+uniform mat4 ViewMatrix;
+
+in vec3 pos;
+in vec3 N1, N2; // normals of faces this edge joins (object coords)
+
+/* instance attrib */
+in vec3 color;
+in mat4 InstanceModelMatrix;
+
+out vec4 MV_pos;
+out float edgeClass;
+out vec3 fCol;
+
+// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
+
+mat3 NormalMatrix;
+
+bool front(vec3 N, vec3 eye)
+{
+ return dot(NormalMatrix * N, eye) > 0.0;
+}
+
+void main()
+{
+ vec3 eye;
+
+ mat4 ModelViewMatrix = ViewMatrix * InstanceModelMatrix;
+
+ MV_pos = ModelViewMatrix * vec4(pos, 1.0);
+
+ NormalMatrix = transpose(inverse(mat3(ModelViewMatrix)));
+
+ /* if persp */
+ if (ViewMatrix[3][3] == 0.0) {
+ eye = normalize(-MV_pos.xyz);
+ }
+ else {
+ eye = vec3(0.0, 0.0, 1.0);
+ }
+
+ bool face_1_front = front(N1, eye);
+ bool face_2_front = front(N2, eye);
+
+ if (face_1_front && face_2_front)
+ edgeClass = 1.0; // front-facing edge
+ else if (face_1_front || face_2_front)
+ edgeClass = 0.0; // exactly one face is front-facing, silhouette edge
+ else
+ edgeClass = -1.0; // back-facing edge
+
+ fCol = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
new file mode 100644
index 00000000000..ce82dc6af2a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
@@ -0,0 +1,29 @@
+
+uniform mat4 ViewMatrix;
+uniform mat4 ViewProjectionMatrix;
+uniform mat4 ModelMatrix;
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos;
+in vec3 nor;
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec4 color;
+
+out vec3 normal;
+flat out vec4 finalColor;
+
+void main()
+{
+ mat4 FinalModelMatrix = ModelMatrix * InstanceModelMatrix;
+ mat4 ModelViewProjectionMatrix = ViewProjectionMatrix * FinalModelMatrix;
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attrib */
+ mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * FinalModelMatrix)));
+
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ normal = NormalMatrix * nor;
+
+ finalColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl
new file mode 100644
index 00000000000..a39bfde41ee
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl
@@ -0,0 +1,29 @@
+
+uniform mat4 ViewProjectionMatrix;
+uniform vec3 screen_vecs[2];
+
+/* ---- Instanciated Attribs ---- */
+in vec3 pos; /* using Z as axis id */
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec3 color;
+in float size;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ vec3 offset;
+
+ if (pos.z == 0.0)
+ offset = vec3(1.125, 0.0, 0.0);
+ else if (pos.z == 1.0)
+ offset = vec3(0.0, 1.125, 0.0);
+ else
+ offset = vec3(0.0, 0.0, 1.125);
+
+ vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y;
+ gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset * size, 1.0) + vec4(screen_pos * size, 0.0));
+ finalColor = vec4(color, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl
index 43a7e42153a..ebda79558c7 100644
--- a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl
@@ -29,7 +29,7 @@ void main() {
float mid_stroke = 0.5 * (radii[1] + radii[2]);
- vec4 backgroundColor = vec4(finalColor.rgb, 0.0);
+ vec4 backgroundColor = vec4(finalOutlineColor.rgb, 0.0);
if (dist > mid_stroke)
fragColor = mix(finalOutlineColor, backgroundColor, smoothstep(radii[1], radii[0], dist));
diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl
index 69afefa685f..6f33491af55 100644
--- a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl
@@ -26,7 +26,7 @@ void main() {
gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
// pass through unchanged
- gl_PointSize = size;
+ gl_PointSize = size + pixel_fudge; // 0.5 pixel_fudge on either side
finalColor = color;
finalOutlineColor = outlineColor;
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 0f3ffa8244b..ef30f8ae6c5 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1,3 +1,18 @@
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat4 ModelViewMatrixInverse;
+uniform mat4 ProjectionMatrixInverse;
+uniform mat3 NormalMatrix;
+
+#if __VERSION__ == 120
+ #define fragColor gl_FragColor
+#else
+ out vec4 fragColor;
+ #define texture2D texture
+ #define textureCube texture
+#endif
+
/* Converters */
float convert_rgba_to_float(vec4 color)
@@ -177,7 +192,7 @@ void geom(
out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback)
{
local = co;
- view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
+ view = (ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
global = (viewinvmat * vec4(local, 1.0)).xyz;
orco = attorco;
uv_attribute(attuv, uv);
@@ -1413,8 +1428,8 @@ void mtex_bump_init_objspace(
out float fPrevMagnitude_out, out vec3 vNacc_out,
out vec3 vR1, out vec3 vR2, out float fDet)
{
- mat3 obj2view = to_mat3(gl_ModelViewMatrix);
- mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse);
+ mat3 obj2view = to_mat3(ModelViewMatrix);
+ mat3 view2obj = to_mat3(ModelViewMatrixInverse);
vec3 vSigmaS = view2obj * dFdx(surf_pos);
vec3 vSigmaT = view2obj * dFdy(surf_pos);
@@ -1670,7 +1685,7 @@ void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
{
- outnormal = normalize(gl_NormalMatrix * texnormal);
+ outnormal = normalize(NormalMatrix * texnormal);
}
void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
@@ -1794,7 +1809,7 @@ void lamp_visibility_clamp(float visifac, out float outvisifac)
void world_paper_view(vec3 vec, out vec3 outvec)
{
vec3 nvec = normalize(vec);
- outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
+ outvec = (ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
}
void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
@@ -1828,7 +1843,7 @@ void world_blend(vec3 vec, out float blend)
void shade_view(vec3 co, out vec3 view)
{
/* handle perspective/orthographic */
- view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
+ view = (ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
}
void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
@@ -2346,7 +2361,7 @@ void shade_mist_factor(
if (enable == 1.0) {
float fac, zcor;
- zcor = (gl_ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
+ zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
if (misttype == 0.0) fac *= fac;
@@ -2605,11 +2620,11 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
{
- vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
- vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+ vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (ProjectionMatrixInverse * v);
vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
- worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+ worldvec = (ModelViewMatrixInverse * co).xyz;
}
void node_background(vec4 color, float strength, vec3 N, out vec4 result)
@@ -2634,7 +2649,7 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
void node_fresnel(float ior, vec3 N, vec3 I, out float result)
{
/* handle perspective/orthographic */
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
float eta = max(ior, 0.00001);
result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
@@ -2646,7 +2661,7 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float
{
/* fresnel */
float eta = max(1.0 - blend, 0.00001);
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
@@ -2700,7 +2715,7 @@ void node_geometry(
true_normal = normal;
/* handle perspective/orthographic */
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
incoming = -(toworld * vec4(I_view, 0.0)).xyz;
parametric = vec3(0.0);
@@ -2719,7 +2734,7 @@ void node_tex_coord(
uv = attr_uv;
object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
camera = vec3(I.xy, -I.z);
- vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
+ vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
vec3 shade_I;
@@ -2734,13 +2749,13 @@ void node_tex_coord_background(
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection)
{
- vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
- vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+ vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (ProjectionMatrixInverse * v);
vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
co = normalize(co);
- vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+ vec3 coords = (ModelViewMatrixInverse * co).xyz;
generated = coords;
normal = -coords;
@@ -2748,7 +2763,7 @@ void node_tex_coord_background(
object = coords;
camera = vec3(co.xy, -co.z);
- window = (gl_ProjectionMatrix[3][3] == 0.0) ?
+ window = (ProjectionMatrix[3][3] == 0.0) ?
vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_smooth_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl
index 8c8d81f6997..8c8d81f6997 100644
--- a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_smooth_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_smooth_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl
index f83785de95e..f83785de95e 100644
--- a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_smooth_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_smooth_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl
index d6cbe2d9a22..d6cbe2d9a22 100644
--- a/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_smooth_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
index b485d2cce86..d7cdec9441d 100644
--- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
@@ -1,16 +1,25 @@
uniform vec2 ScaleU;
uniform sampler2D textureSource;
+#if __VERSION__ == 120
+ varying vec2 texCoord_interp;
+ #define fragColor gl_FragColor
+#else
+ in vec2 texCoord_interp;
+ out vec4 fragColor;
+ #define texture2D texture
+#endif
+
void main()
{
vec4 color = vec4(0.0);
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-3.0 * ScaleU.x, -3.0 * ScaleU.y)) * 0.015625;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-2.0 * ScaleU.x, -2.0 * ScaleU.y)) * 0.09375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-1.0 * ScaleU.x, -1.0 * ScaleU.y)) * 0.234375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(0.0, 0.0)) * 0.3125;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y)) * 0.234375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y)) * 0.09375;
- color += texture2D(textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y)) * 0.015625;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(-3.0 * ScaleU.x, -3.0 * ScaleU.y)) * 0.015625;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(-2.0 * ScaleU.x, -2.0 * ScaleU.y)) * 0.09375;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(-1.0 * ScaleU.x, -1.0 * ScaleU.y)) * 0.234375;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(0.0, 0.0)) * 0.3125;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y)) * 0.234375;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y)) * 0.09375;
+ color += texture2D(textureSource, texCoord_interp.st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y)) * 0.015625;
- gl_FragColor = color;
+ fragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
index 5d00108b052..a0e5b022e67 100644
--- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
@@ -1,6 +1,18 @@
+uniform mat4 ModelViewProjectionMatrix;
+
+#if __VERSION__ == 120
+ attribute vec2 pos;
+ attribute vec2 uvs;
+ varying vec2 texCoord_interp;
+#else
+ in vec2 pos;
+ in vec2 uvs;
+ out vec2 texCoord_interp;
+#endif
+
void main()
{
- gl_Position = ftransform();
- gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ texCoord_interp = uvs;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl
index 9828787fb04..4eacd08d5af 100644
--- a/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl
@@ -1,12 +1,21 @@
+#ifndef USE_INSTANCE_COLOR
uniform vec4 color;
+#endif
uniform vec3 light;
#if __VERSION__ == 120
varying vec3 normal;
+#ifdef USE_INSTANCE_COLOR
+ varying vec4 finalColor;
+#endif
#define fragColor gl_FragColor
#else
in vec3 normal;
+#ifdef USE_INSTANCE_COLOR
+ flat in vec4 finalColor;
+ #define color finalColor
+#endif
out vec4 fragColor;
#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl
new file mode 100644
index 00000000000..260539f76d7
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl
@@ -0,0 +1,17 @@
+
+uniform vec3 light;
+
+#if __VERSION__ == 120
+ varying vec3 normal;
+ varying vec4 finalColor;
+ #define fragColor gl_FragColor
+#else
+ in vec3 normal;
+ in vec4 finalColor;
+ out vec4 fragColor;
+#endif
+
+void main()
+{
+ fragColor = finalColor * max(0.0, dot(normalize(normal), light));
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
index 6ded453225e..fcb385ed30a 100644
--- a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
@@ -1,5 +1,13 @@
-varying vec3 coords;
+#if __VERSION__ == 120
+ varying vec3 coords;
+ #define fragColor gl_FragColor
+#else
+ in vec3 coords;
+ out vec4 fragColor;
+ #define texture1D texture
+ #define texture3D texture
+#endif
uniform vec3 active_color;
uniform float step_size;
@@ -44,5 +52,5 @@ void main()
vec4 color = transfer_function * density_scale;
#endif
- gl_FragColor = color;
+ fragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
index 297486ae26a..f49272d0913 100644
--- a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
@@ -1,5 +1,11 @@
-varying vec3 coords;
+uniform mat4 ModelViewProjectionMatrix;
+
+#if __VERSION__ == 120
+ varying vec3 coords;
+#else
+ out vec3 coords;
+#endif
uniform vec3 min_location;
uniform vec3 invsize;
@@ -7,6 +13,6 @@ uniform vec3 ob_sizei;
void main()
{
- gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0);
+ gl_Position = ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0);
coords = (gl_Vertex.xyz - min_location) * invsize;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index db0068d2f3d..5a6b237b3be 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -1,3 +1,8 @@
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat3 NormalMatrix;
+
#ifdef USE_OPENSUBDIV
in vec3 normal;
in vec4 position;
@@ -7,8 +12,13 @@ out block {
} outpt;
#endif
-varying vec3 varposition;
-varying vec3 varnormal;
+#if __VERSION__ == 120
+ varying vec3 varposition;
+ varying vec3 varnormal;
+#else
+ out vec3 varposition;
+ out vec3 varnormal;
+#endif
#ifdef CLIP_WORKAROUND
varying float gl_ClipDistance[6];
@@ -89,11 +99,11 @@ void main()
vec3 normal = gl_Normal;
#endif
- vec4 co = gl_ModelViewMatrix * position;
+ vec4 co = ModelViewMatrix * position;
varposition = co.xyz;
- varnormal = normalize(gl_NormalMatrix * normal);
- gl_Position = gl_ProjectionMatrix * co;
+ varnormal = normalize(NormalMatrix * normal);
+ gl_Position = ProjectionMatrix * co;
#ifdef CLIP_WORKAROUND
int i;
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
index d45a4b316a8..7a39c3fc674 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
@@ -1,7 +1,11 @@
-varying vec3 varposition;
-varying vec3 varnormal;
-
+#if __VERSION__ == 120
+ varying vec3 varposition;
+ varying vec3 varnormal;
+#else
+ out vec3 varposition;
+ out vec3 varnormal;
+#endif
/* Color, keep in sync with: gpu_shader_vertex.glsl */
diff --git a/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl b/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
index 3761bf350eb..9035a311ecb 100644
--- a/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
@@ -2,7 +2,13 @@
* This fragment shader was initially found at http://fabiensanglard.net/shadowmappingVSM/index.php
*/
-varying vec4 v_position;
+#if __VERSION__ == 120
+ varying vec4 v_position;
+ #define fragColor gl_FragColor
+#else
+ in vec4 v_position;
+ out vec4 fragColor;
+#endif
void main()
{
@@ -17,5 +23,6 @@ void main()
float dy = dFdy(depth);
moment2 += 0.25 * (dx * dx + dy * dy);
- gl_FragColor = vec4(moment1, moment2, 0.0, 0.0);
+ fragColor = vec4(moment1, moment2, 0.0, 0.0);
+ // TODO: write to a 2-component target --^
}
diff --git a/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl b/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
index 224c3e78adc..96ea22b3483 100644
--- a/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
@@ -1,7 +1,14 @@
-varying vec4 v_position;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+#if __VERSION__ == 120
+ varying vec4 v_position;
+#else
+ out vec4 v_position;
+#endif
void main()
{
- gl_Position = ftransform();
+ gl_Position = ModelViewProjectionMatrix * gl_Vertex;
v_position = gl_Position;
}