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.txt9
-rw-r--r--source/blender/gpu/GPU_extensions.h2
-rw-r--r--source/blender/gpu/GPU_framebuffer.h1
-rw-r--r--source/blender/gpu/GPU_shader.h9
-rw-r--r--source/blender/gpu/GPU_uniformbuffer.h44
-rw-r--r--source/blender/gpu/GPU_viewport.h42
-rw-r--r--source/blender/gpu/gawain/batch.c86
-rw-r--r--source/blender/gpu/gawain/batch.h2
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c15
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c38
-rw-r--r--source/blender/gpu/intern/gpu_shader.c40
-rw-r--r--source/blender/gpu/intern/gpu_texture.c1
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c105
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c196
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_groundline_vert.glsl8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl11
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_instance_vert.glsl10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl24
19 files changed, 654 insertions, 5 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index c5531b8542e..364e77123d9 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -31,6 +31,7 @@ set(INC
../imbuf
../makesdna
../makesrna
+ ../draw
../editors/include
@@ -64,6 +65,7 @@ set(SRC
intern/gpu_select.c
intern/gpu_shader.c
intern/gpu_texture.c
+ intern/gpu_uniformbuffer.c
intern/gpu_viewport.c
gawain/attrib_binding.c
@@ -122,6 +124,7 @@ set(SRC
GPU_select.h
GPU_shader.h
GPU_texture.h
+ GPU_uniformbuffer.h
GPU_viewport.h
intern/gpu_codegen.h
@@ -145,10 +148,16 @@ data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_interlace_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_instance_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_groundline_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_3D_lamp_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)
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 31ad8243c4b..ff00a83d00b 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -53,6 +53,8 @@ int GPU_max_textures(void);
float GPU_max_texture_anisotropy(void);
int GPU_max_color_texture_samples(void);
int GPU_max_cube_map_size(void);
+int GPU_max_ubo_binds(void);
+int GPU_max_ubo_size(void);
int GPU_color_depth(void);
void GPU_get_dfdy_factors(float fac[2]);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 989b874fd38..9611a6f0577 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -52,6 +52,7 @@ void GPU_texture_bind_as_framebuffer(struct GPUTexture *tex);
GPUFrameBuffer *GPU_framebuffer_create(void);
bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot);
void GPU_framebuffer_texture_detach(struct GPUTexture *tex);
+void GPU_framebuffer_bind(GPUFrameBuffer *fb);
void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot);
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, struct GPUTexture *tex);
void GPU_framebuffer_free(GPUFrameBuffer *fb);
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 394e751ed9b..b36954dd010 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -38,6 +38,7 @@ extern "C" {
typedef struct GPUShader GPUShader;
struct GPUTexture;
+struct GPUUniformBuffer;
/* GPU Shader
* - only for fragment shaders now
@@ -69,14 +70,17 @@ void GPU_shader_free(GPUShader *shader);
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);
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,
int arraysize, const float *value);
void GPU_shader_uniform_vector_int(GPUShader *shader, int location, int length,
int arraysize, const int *value);
+void GPU_shader_uniform_buffer(GPUShader *shader, int location, struct GPUUniformBuffer *ubo);
void GPU_shader_uniform_texture(GPUShader *shader, int location, struct GPUTexture *tex);
void GPU_shader_uniform_int(GPUShader *shader, int location, int value);
void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number);
@@ -104,6 +108,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_IMAGE_COLOR,
/* for simple 3D drawing */
GPU_SHADER_3D_UNIFORM_COLOR,
+ GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE,
GPU_SHADER_3D_FLAT_COLOR,
GPU_SHADER_3D_SMOOTH_COLOR,
GPU_SHADER_3D_DEPTH_ONLY,
@@ -126,6 +131,10 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH,
GPU_SHADER_3D_POINT_VARYING_SIZE_UNIFORM_COLOR,
GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR,
+ /* lamp drawing */
+ GPU_SHADER_3D_GROUNDPOINT,
+ GPU_SHADER_3D_GROUNDLINE,
+ GPU_SHADER_3D_LAMP_COMMON,
GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
} GPUBuiltinShader;
diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
new file mode 100644
index 00000000000..bcb6e1077b7
--- /dev/null
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -0,0 +1,44 @@
+/*
+ * ***** 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): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_uniformbuffer.h
+ * \ingroup gpu
+ */
+
+typedef struct GPUUniformBuffer GPUUniformBuffer;
+
+GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256]);
+void GPU_uniformbuffer_free(GPUUniformBuffer *ubo);
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data);
+
+void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number);
+#if 0
+void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo);
+#endif
+
+int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo);
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index fce509377ab..e44657a4647 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -34,12 +34,52 @@
#include <stdbool.h>
+#include "DNA_vec_types.h"
+
+#include "GPU_framebuffer.h"
+#include "GPU_texture.h"
+
typedef struct GPUViewport GPUViewport;
-GPUViewport *GPU_viewport_create(void);
+#define MAX_BUFFERS 8
+#define MAX_TEXTURES 16
+#define MAX_PASSES 16
+
+/* All FramebufferLists are just the same pointers with different names */
+typedef struct FramebufferList {
+ struct GPUFrameBuffer *framebuffers[MAX_BUFFERS];
+} FramebufferList;
+
+typedef struct TextureList {
+ struct GPUTexture *textures[MAX_TEXTURES];
+} TextureList;
+
+typedef struct PassList {
+ struct DRWPass *passes[MAX_TEXTURES];
+} PassList;
+/* Buffer and textures used by the viewport by default */
+typedef struct DefaultFramebufferList {
+ struct GPUFrameBuffer *default_fb;
+} DefaultFramebufferList;
+
+typedef struct DefaultTextureList {
+ struct GPUTexture *color;
+ struct GPUTexture *depth;
+} DefaultTextureList;
+
+typedef struct DefaultPassList {
+ struct DRWPass *non_meshes_pass;
+ struct DRWPass *ob_center_pass;
+} DefaultPassList;
+
+GPUViewport *GPU_viewport_create(void);
+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);
+
/* debug */
bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]);
void GPU_viewport_debug_depth_free(GPUViewport *viewport);
diff --git a/source/blender/gpu/gawain/batch.c b/source/blender/gpu/gawain/batch.c
index a60865d41d2..99c13301177 100644
--- a/source/blender/gpu/gawain/batch.c
+++ b/source/blender/gpu/gawain/batch.c
@@ -247,3 +247,89 @@ void Batch_draw(Batch* batch)
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)
+{
+ if (batch->vao_id)
+ glBindVertexArray(batch->vao_id);
+ else
+ Batch_prime(batch);
+
+ if (batch->program_dirty)
+ Batch_update_program_bindings(batch);
+
+ const GLint loc = glGetAttribLocation(batch->program, "InstanceModelMatrix");
+
+#if TRUST_NO_ONE
+ assert(loc != -1);
+#endif
+
+ glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
+ glEnableVertexAttribArray(loc);
+ glVertexAttribPointer(loc + 0, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)0);
+ glEnableVertexAttribArray(loc + 1);
+ glVertexAttribPointer(loc + 1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)(sizeof(float)*4));
+ glEnableVertexAttribArray(loc + 2);
+ glVertexAttribPointer(loc + 2, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)(2 * sizeof(float)*4));
+ glEnableVertexAttribArray(loc + 3);
+ glVertexAttribPointer(loc + 3, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4*4, (GLvoid*)(3 * sizeof(float)*4));
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glVertexAttribDivisor(loc + 0, 1);
+ glVertexAttribDivisor(loc + 1, 1);
+ glVertexAttribDivisor(loc + 2, 1);
+ glVertexAttribDivisor(loc + 3, 1);
+
+ // 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
index 932ee182703..8b5c48cca79 100644
--- a/source/blender/gpu/gawain/batch.h
+++ b/source/blender/gpu/gawain/batch.h
@@ -57,6 +57,8 @@ 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*);
+void Batch_draw_stupid(Batch* batch);
+void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count);
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index e8fd4b8b8b1..d7ed65e853e 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -69,6 +69,8 @@ static struct GPUGlobal {
GLint maxtexsize;
GLint maxcubemapsize;
GLint maxtextures;
+ GLint maxubosize;
+ GLint maxubobinds;
bool extdisabled;
int colordepth;
int samples_color_texture_max;
@@ -121,6 +123,16 @@ int GPU_max_cube_map_size(void)
return GG.maxcubemapsize;
}
+int GPU_max_ubo_binds(void)
+{
+ return GG.maxubobinds;
+}
+
+int GPU_max_ubo_size(void)
+{
+ return GG.maxubosize;
+}
+
void GPU_get_dfdy_factors(float fac[2])
{
copy_v2_v2(fac, GG.dfdyfactors);
@@ -154,6 +166,9 @@ void gpu_extensions_init(void)
else
GG.max_anisotropy = 1.0f;
+ glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &GG.maxubobinds);
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GG.maxubosize);
+
GLint r, g, b;
glGetIntegerv(GL_RED_BITS, &r);
glGetIntegerv(GL_GREEN_BITS, &g);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 2ef8018e5e9..1efc451f4a8 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -260,6 +260,43 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
glPushMatrix();
}
+void GPU_framebuffer_bind(GPUFrameBuffer *fb)
+{
+ int numslots = 0, i;
+ GLenum attachments[4];
+ GLenum readattachement = 0;
+ GPUTexture *tex;
+
+ for (i = 0; i < 4; i++) {
+ if (fb->colortex[i]) {
+ attachments[numslots] = GL_COLOR_ATTACHMENT0 + i;
+ tex = fb->colortex[i];
+
+ if (!readattachement)
+ readattachement = GL_COLOR_ATTACHMENT0 + i;
+
+ numslots++;
+ }
+ }
+
+ /* bind framebuffer */
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
+
+ if (numslots == 0) {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ tex = fb->depthtex;
+ }
+ else {
+ /* last bound prevails here, better allow explicit control here too */
+ glDrawBuffers(numslots, attachments);
+ glReadBuffer(readattachement);
+ }
+
+ glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
+ GG.currentfb = fb->object;
+}
+
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
{
@@ -283,7 +320,6 @@ void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
/* push matrices and set default viewport and matrix */
glViewport(0, 0, GPU_texture_width(fb->colortex[slot]), GPU_texture_height(fb->colortex[slot]));
GG.currentfb = fb->object;
- GG.currentfb = fb->object;
}
bool GPU_framebuffer_bound(GPUFrameBuffer *fb)
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index b81c19d5c70..0d6fd5f7b99 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -37,6 +37,7 @@
#include "GPU_debug.h"
#include "GPU_extensions.h"
#include "GPU_shader.h"
+#include "GPU_uniformbuffer.h"
#include "GPU_texture.h"
#include "gpu_shader_private.h"
@@ -64,10 +65,16 @@ extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_3D_instance_vert_glsl[];
extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
+extern char datatoc_gpu_shader_3D_groundline_vert_glsl[];
+extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
+extern char datatoc_gpu_shader_3D_lamp_vert_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[];
@@ -511,11 +518,24 @@ int GPU_shader_get_uniform(GPUShader *shader, const char *name)
return glGetUniformLocation(shader->program, name);
}
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+
+ return glGetUniformBlockIndex(shader->program, name);
+}
+
void *GPU_shader_get_interface(GPUShader *shader)
{
return shader->uniform_interface;
}
+/* Clement : Temp */
+int GPU_shader_get_program(GPUShader *shader)
+{
+ return (int)shader->program;
+}
+
void GPU_shader_set_interface(GPUShader *shader, void *interface)
{
shader->uniform_interface = interface;
@@ -563,6 +583,17 @@ void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int ou
}
}
+void GPU_shader_uniform_buffer(GPUShader *shader, int location, GPUUniformBuffer *ubo)
+{
+ int bindpoint = GPU_uniformbuffer_bindpoint(ubo);
+
+ if (location == -1) {
+ return;
+ }
+
+ glUniformBlockBinding(shader->program, location, bindpoint);
+}
+
void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
{
int number = GPU_texture_bound_number(tex);
@@ -645,12 +676,21 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_2D_IMAGE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE] = { datatoc_gpu_shader_3D_instance_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 },
[GPU_SHADER_3D_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl,
datatoc_gpu_shader_3D_smooth_color_frag_glsl },
[GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl },
+ [GPU_SHADER_3D_GROUNDPOINT] = { datatoc_gpu_shader_3D_groundpoint_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_groundline_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ datatoc_gpu_shader_3D_groundline_geom_glsl },
+
+ [GPU_SHADER_3D_LAMP_COMMON] = { datatoc_gpu_shader_3D_lamp_vert_glsl,
+ datatoc_gpu_shader_uniform_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] =
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 6fb658e20eb..3513250993e 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -91,6 +91,7 @@ static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type,
/* Formats texture & renderbuffer */
case GPU_RGBA16F: return GL_RGBA16F;
case GPU_RG32F: return GL_RG32F;
+ case GPU_RG16F: return GL_RG16F;
case GPU_RGBA8: return GL_RGBA8;
case GPU_R8: return GL_R8;
/* Special formats texture & renderbuffer */
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
new file mode 100644
index 00000000000..76aa1a8226f
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -0,0 +1,105 @@
+/*
+ * ***** 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): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_uniformbuffer.c
+ * \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
+#include "GPU_extensions.h"
+#include "GPU_glew.h"
+#include "GPU_uniformbuffer.h"
+
+struct GPUUniformBuffer {
+ int size; /* in bytes */
+ GLuint bindcode; /* opengl identifier for UBO */
+ int bindpoint; /* current binding point */
+};
+
+GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256])
+{
+ GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBuffer), "GPUUniformBuffer");
+ ubo->size = size;
+
+ /* Generate Buffer object */
+ glGenBuffers(1, &ubo->bindcode);
+
+ if (!ubo->bindcode) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUUniformBuffer: UBO create failed");
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ if (ubo->size > GPU_max_ubo_size()) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUUniformBuffer: UBO too big");
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+ return ubo;
+}
+
+void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
+{
+ glDeleteBuffers(1, &ubo->bindcode);
+ MEM_freeN(ubo);
+}
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
+{
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+}
+
+void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
+{
+ if (number >= GPU_max_ubo_binds()) {
+ fprintf(stderr, "Not enough UBO slots.\n");
+ return;
+ }
+
+ if (ubo->bindcode != 0) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
+ }
+
+ ubo->bindpoint = number;
+}
+
+int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
+{
+ return ubo->bindpoint;
+} \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index a4fb3494639..b1964857ab1 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -31,10 +31,19 @@
* System that manages viewport drawing.
*/
+#include <string.h>
+
+#include "BLI_rect.h"
+
+#include "DNA_vec_types.h"
+
+#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_immediate.h"
-#include "GPU_viewport.h"
#include "GPU_texture.h"
+#include "GPU_viewport.h"
+
+#include "DRW_engine.h"
#include "MEM_guardedalloc.h"
@@ -43,19 +52,200 @@ struct GPUViewport {
/* debug */
GPUTexture *debug_depth;
- int debug_width, debug_height;
+ int size[2];
+
+ /* Viewport Buffer Storage */
+ /* TODO indentify to what engine conf are theses buffers */
+ DefaultFramebufferList *fbl;
+ DefaultTextureList *txl;
+ DefaultPassList *psl;
};
+static void GPU_viewport_buffers_free(GPUViewport *viewport);
+static void GPU_viewport_passes_free(GPUViewport *viewport);
+
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->size[0] = viewport->size[1] = -1;
+
return viewport;
}
+void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss)
+{
+ *fbs = viewport->fbl;
+ *txs = viewport->txl;
+ *pss = viewport->psl;
+}
+
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
+{
+ /* add one pixel because of scissor test */
+ int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
+
+#ifndef WITH_VIEWPORT_CACHE_TEST
+ /* TODO for testing only, we need proper cache invalidation */
+ GPU_viewport_passes_free(viewport);
+#endif
+
+ if (viewport->fbl->default_fb) {
+ if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
+ GPU_viewport_buffers_free(viewport);
+ }
+ }
+
+ if (!viewport->fbl->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) {
+ 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) {
+ ok = false;
+ goto cleanup;
+ }
+
+ if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) {
+ ok = false;
+ goto cleanup;
+ }
+
+ /* Depth */
+ viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
+ if (!viewport->txl->depth) {
+ ok = false;
+ goto cleanup;
+ }
+ else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) {
+ ok = false;
+ goto cleanup;
+ }
+ else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) {
+ ok = false;
+ goto cleanup;
+ }
+
+cleanup:
+ if (!ok) {
+ GPU_viewport_free(viewport);
+ MEM_freeN(viewport);
+ return;
+ }
+
+ GPU_framebuffer_restore();
+ }
+
+ GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0);
+}
+
+static void draw_ofs_to_screen(GPUViewport *viewport)
+{
+ GPUTexture *color = viewport->txl->color;
+
+ const float w = (float)GPU_texture_width(color);
+ const float h = (float)GPU_texture_height(color);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned texcoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT);
+ 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);
+
+ immAttrib2f(texcoord, 0.0f, 0.0f);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ 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);
+
+ immEnd();
+
+ GPU_texture_unbind(color);
+
+ immUnbindProgram();
+}
+
+void GPU_viewport_unbind(GPUViewport *viewport)
+{
+ if (viewport->fbl->default_fb) {
+ GPU_framebuffer_texture_unbind(NULL, NULL);
+ GPU_framebuffer_restore();
+
+ glEnable(GL_SCISSOR_TEST);
+
+ /* This might be bandwidth limiting */
+ draw_ofs_to_screen(viewport);
+ }
+}
+
+static void GPU_viewport_buffers_free(GPUViewport *viewport)
+{
+ 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];
+ if (fb) {
+ GPU_framebuffer_free(fb);
+ fbl->framebuffers[i] = NULL;
+ }
+ }
+ for (i = MAX_TEXTURES - 1; i > -1; --i) {
+ GPUTexture *tex = txl->textures[i];
+ if (tex) {
+ GPU_texture_free(tex);
+ txl->textures[i] = NULL;
+ }
+ }
+}
+
+static void GPU_viewport_passes_free(GPUViewport *viewport)
+{
+ PassList *psl = (PassList *)viewport->psl;
+ int i;
+
+ for (i = MAX_PASSES - 1; i > -1; --i) {
+ struct DRWPass *pass = psl->passes[i];
+ if (pass) {
+ DRW_pass_free(pass);
+ MEM_freeN(pass);
+ psl->passes[i] = NULL;
+ }
+ }
+}
+
void GPU_viewport_free(GPUViewport *viewport)
{
GPU_viewport_debug_depth_free(viewport);
- MEM_freeN(viewport);
+ GPU_viewport_buffers_free(viewport);
+ GPU_viewport_passes_free(viewport);
+
+ MEM_freeN(viewport->fbl);
+ MEM_freeN(viewport->txl);
+ MEM_freeN(viewport->psl);
}
/****************** debug ********************/
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl
new file mode 100644
index 00000000000..f16fa21b342
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl
@@ -0,0 +1,16 @@
+
+/* Make to be used with dynamic batching so no Model Matrix needed */
+uniform mat4 ViewProjectionMatrix;
+
+layout(points) in;
+layout(line_strip, max_vertices = 2) out;
+
+void main()
+{
+ vec3 vert = gl_in[0].gl_Position.xyz;
+ gl_Position = ViewProjectionMatrix * vec4(vert.xyz, 1.0);
+ EmitVertex();
+ gl_Position = ViewProjectionMatrix * vec4(vert.xy, 0.0, 1.0);
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundline_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundline_vert.glsl
new file mode 100644
index 00000000000..60793bf56b6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_groundline_vert.glsl
@@ -0,0 +1,8 @@
+
+/* Does Nothing */
+in vec3 pos;
+
+void main()
+{
+ gl_Position = vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl
new file mode 100644
index 00000000000..be6b6014a19
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl
@@ -0,0 +1,11 @@
+
+/* Make to be used with dynamic batching so no Model Matrix needed */
+uniform mat4 ViewProjectionMatrix;
+
+in vec3 pos;
+
+void main()
+{
+ gl_Position = ViewProjectionMatrix * vec4(pos.xy, 0.0, 1.0);
+ gl_PointSize = 2.0;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_instance_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_instance_vert.glsl
new file mode 100644
index 00000000000..7eb321f2996
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_instance_vert.glsl
@@ -0,0 +1,10 @@
+
+uniform mat4 ViewProjectionMatrix;
+
+in vec3 pos;
+in mat4 InstanceModelMatrix;
+
+void main()
+{
+ gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos, 1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl
new file mode 100644
index 00000000000..dbc683ef42b
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl
@@ -0,0 +1,24 @@
+
+uniform mat4 ViewProjectionMatrix;
+uniform vec3 screen_vecs[2];
+uniform float size;
+uniform float pixel_size;
+
+in vec2 pos;
+in mat4 InstanceModelMatrix;
+
+#define lamp_pos InstanceModelMatrix[3].xyz
+
+float mul_project_m4_v3_zfac(in vec3 co)
+{
+ return (ViewProjectionMatrix[0][3] * co.x) +
+ (ViewProjectionMatrix[1][3] * co.y) +
+ (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatrix[3][3];
+}
+
+void main()
+{
+ float pix_size = mul_project_m4_v3_zfac(lamp_pos) * pixel_size;
+ vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y;
+ gl_Position = ViewProjectionMatrix * vec4(lamp_pos + screen_pos * size * pix_size, 1.0);
+}