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:
authorPablo Dobarro <pablodp606@gmail.com>2019-06-22 19:30:34 +0300
committerPablo Dobarro <pablodp606@gmail.com>2019-06-22 19:30:34 +0300
commit8d17efaf7b71afa6cee252fa81b9e49016dbc118 (patch)
tree6d9a57c561bc8ffa8d0a9dfbdfcd1c06b0324f0e /source/blender/gpu
parent5b19ecdc6bfe875a952731d5d2a79bb0be2e9e7e (diff)
parentab9492648398ecd9265173356d50688ddb3c9aeb (diff)
Merge branch 'master' into sculpt-mode-features
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/GPU_framebuffer.h1
-rw-r--r--source/blender/gpu/GPU_matrix.h31
-rw-r--r--source/blender/gpu/GPU_texture.h8
-rw-r--r--source/blender/gpu/intern/gpu_draw.c84
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c26
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c79
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl5
7 files changed, 181 insertions, 53 deletions
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 3cc972fabfb..b919a3dd8f3 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -209,6 +209,7 @@ void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs,
struct GPUTexture **r_depth);
void GPU_clear_color(float red, float green, float blue, float alpha);
+void GPU_clear_depth(float depth);
void GPU_clear(eGPUFrameBufferBits flags);
#ifdef __cplusplus
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 6f7d25dafa7..61622c40ff0 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -96,21 +96,38 @@ void GPU_matrix_perspective_set(float fovy, float aspect, float near, float far)
/* 3D Projection between Window and World Space */
+struct GPUMatrixUnproject_Precalc {
+ float model_inverted[4][4];
+ float view[4];
+ bool is_persp;
+ /** Result of 'projmat_dimensions'. */
+ struct {
+ float xmin, xmax;
+ float ymin, ymax;
+ float zmin, zmax;
+ } dims;
+};
+
+bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *unproj_precalc,
+ const float model[4][4],
+ const float proj[4][4],
+ const int view[4]);
+
void GPU_matrix_project(const float world[3],
const float model[4][4],
const float proj[4][4],
const int view[4],
- float win[3]);
+ float r_win[3]);
+
bool GPU_matrix_unproject(const float win[3],
const float model[4][4],
const float proj[4][4],
const int view[4],
- float world[3]);
-void GPU_matrix_unproject_model_inverted(const float win[3],
- const float model_inverted[4][4],
- const float proj[4][4],
- const int view[4],
- float world[3]);
+ float r_world[3]);
+
+void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc *unproj_precalc,
+ const float win[3],
+ float r_world[3]);
/* 2D Projection Matrix */
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 3fb7dfc6331..d5e763987cb 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -33,6 +33,8 @@ extern "C" {
struct GPUVertBuf;
struct Image;
struct ImageUser;
+struct MovieClip;
+struct MovieClipUser;
struct PreviewImage;
struct rcti;
@@ -189,6 +191,12 @@ GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode);
GPUTexture *GPU_texture_from_blender(struct Image *ima, struct ImageUser *iuser, int textarget);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
+/* movie clip drawing */
+GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip,
+ struct MovieClipUser *cuser,
+ int textarget);
+void GPU_free_texture_movieclip(struct MovieClip *clip);
+
void GPU_texture_add_mipmap(GPUTexture *tex,
eGPUDataFormat gpu_data_format,
int miplvl,
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 7813ae68371..9a341631833 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -59,6 +59,7 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_movieclip.h"
#include "BKE_node.h"
#include "BKE_scene.h"
@@ -247,7 +248,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
* this allows us to use sRGB texture formats and preserves color values in
* zero alpha areas, and appears generally closer to what game engines that we
* want to be compatible with do. */
- const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true;
IMB_colormanagement_imbuf_to_byte_texture(
rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied);
}
@@ -256,14 +257,13 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
/* Float image is already in scene linear colorspace or non-color data by
* convention, no colorspace conversion needed. But we do require 4 channels
* currently. */
- const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
+ const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false;
if (ibuf->channels != 4 || !store_premultiplied) {
rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
if (rect_float == NULL) {
return bindcode;
}
-
IMB_colormanagement_imbuf_to_float_texture(
rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
}
@@ -291,6 +291,38 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
return bindcode;
}
+static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip,
+ MovieClipUser *cuser,
+ GLenum textarget)
+{
+ MovieClip_RuntimeGPUTexture *tex;
+ for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) {
+ if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
+ break;
+ }
+ }
+
+ if (tex == NULL) {
+ tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__);
+
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ tex->gputexture[i] = NULL;
+ }
+
+ memcpy(&tex->user, cuser, sizeof(MovieClipUser));
+ BLI_addtail(&clip->runtime.gputextures, tex);
+ }
+
+ if (textarget == GL_TEXTURE_2D) {
+ return &tex->gputexture[TEXTARGET_TEXTURE_2D];
+ }
+ else if (textarget == GL_TEXTURE_CUBE_MAP) {
+ return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP];
+ }
+
+ return NULL;
+}
+
static void gpu_texture_update_scaled(
uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h)
{
@@ -472,6 +504,52 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
return *tex;
}
+GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget)
+{
+ if (clip == NULL) {
+ return NULL;
+ }
+
+ GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ uint bindcode = 0;
+ ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
+ if (ibuf == NULL) {
+ *tex = GPU_texture_from_bindcode(textarget, bindcode);
+ return *tex;
+ }
+
+ bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget);
+ IMB_freeImBuf(ibuf);
+
+ *tex = GPU_texture_from_bindcode(textarget, bindcode);
+ return *tex;
+}
+
+void GPU_free_texture_movieclip(struct MovieClip *clip)
+{
+ /* number of gpu textures to keep around as cache
+ * We don't want to keep too many GPU textures for
+ * movie clips around, as they can be large.*/
+ const int MOVIECLIP_NUM_GPUTEXTURES = 1;
+
+ while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
+ MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures);
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ /* free glsl image binding */
+ if (tex->gputexture[i]) {
+ GPU_texture_free(tex->gputexture[i]);
+ tex->gputexture[i] = NULL;
+ }
+ }
+ MEM_freeN(tex);
+ }
+}
+
static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth)
{
size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 5950027a103..cd63355ff51 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -130,26 +130,29 @@ static void gpu_print_framebuffer_error(GLenum status, char err_out[256])
const char *format = "GPUFrameBuffer: framebuffer status %s\n";
const char *err = "unknown";
-#define format_status(X) \
+#define FORMAT_STATUS(X) \
case GL_FRAMEBUFFER_##X: \
err = "GL_FRAMEBUFFER_" #X; \
break;
switch (status) {
/* success */
- format_status(COMPLETE)
- /* errors shared by OpenGL desktop & ES */
- format_status(INCOMPLETE_ATTACHMENT) format_status(INCOMPLETE_MISSING_ATTACHMENT)
- format_status(UNSUPPORTED)
+ FORMAT_STATUS(COMPLETE);
+ /* errors shared by OpenGL desktop & ES */
+ FORMAT_STATUS(INCOMPLETE_ATTACHMENT);
+ FORMAT_STATUS(INCOMPLETE_MISSING_ATTACHMENT);
+ FORMAT_STATUS(UNSUPPORTED);
#if 0 /* for OpenGL ES only */
- format_status(INCOMPLETE_DIMENSIONS)
+ FORMAT_STATUS(INCOMPLETE_DIMENSIONS);
#else /* for desktop GL only */
- format_status(INCOMPLETE_DRAW_BUFFER) format_status(INCOMPLETE_READ_BUFFER)
- format_status(INCOMPLETE_MULTISAMPLE) format_status(UNDEFINED)
+ FORMAT_STATUS(INCOMPLETE_DRAW_BUFFER);
+ FORMAT_STATUS(INCOMPLETE_READ_BUFFER);
+ FORMAT_STATUS(INCOMPLETE_MULTISAMPLE);
+ FORMAT_STATUS(UNDEFINED);
#endif
}
-#undef format_status
+#undef FORMAT_STATUS
if (err_out) {
BLI_snprintf(err_out, 256, format, err);
@@ -1041,6 +1044,11 @@ void GPU_clear_color(float red, float green, float blue, float alpha)
glClearColor(red, green, blue, alpha);
}
+void GPU_clear_depth(float depth)
+{
+ glClearDepth(depth);
+}
+
void GPU_clear(eGPUFrameBufferBits flags)
{
glClear(convert_buffer_bits_to_gl(flags));
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index cc89da19705..858afdc534e 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -481,58 +481,73 @@ void GPU_matrix_project(const float world[3],
* But that solution loses much precision.
* Therefore, get the same result without inverting the matrix.
*/
-static void gpu_mul_invert_projmat_m4_unmapped_v3(const float projmat[4][4], float co[3])
+static void gpu_mul_invert_projmat_m4_unmapped_v3_with_precalc(
+ const struct GPUMatrixUnproject_Precalc *precalc, float co[3])
{
- float left, right, bottom, top, near, far;
- bool is_persp = projmat[3][3] == 0.0f;
+ /* 'precalc->dims' is the result of 'projmat_dimensions(proj, ...)'. */
+ co[0] = precalc->dims.xmin + co[0] * (precalc->dims.xmax - precalc->dims.xmin);
+ co[1] = precalc->dims.ymin + co[1] * (precalc->dims.ymax - precalc->dims.ymin);
- projmat_dimensions(projmat, &left, &right, &bottom, &top, &near, &far);
-
- co[0] = left + co[0] * (right - left);
- co[1] = bottom + co[1] * (top - bottom);
-
- if (is_persp) {
- co[2] = far * near / (far + co[2] * (near - far));
+ if (precalc->is_persp) {
+ co[2] = precalc->dims.zmax * precalc->dims.zmin /
+ (precalc->dims.zmax + co[2] * (precalc->dims.zmin - precalc->dims.zmax));
co[0] *= co[2];
co[1] *= co[2];
}
else {
- co[2] = near + co[2] * (far - near);
+ co[2] = precalc->dims.zmin + co[2] * (precalc->dims.zmax - precalc->dims.zmin);
}
co[2] *= -1;
}
-void GPU_matrix_unproject_model_inverted(const float win[3],
- const float model_inverted[4][4],
- const float proj[4][4],
- const int view[4],
- float world[3])
-{
- float in[3];
-
- copy_v3_v3(in, win);
-
- /* Map x and y from window coordinates */
- in[0] = (in[0] - view[0]) / view[2];
- in[1] = (in[1] - view[1]) / view[3];
+bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *precalc,
+ const float model[4][4],
+ const float proj[4][4],
+ const int view[4])
+{
+ precalc->is_persp = proj[3][3] == 0.0f;
+ projmat_dimensions(proj,
+ &precalc->dims.xmin,
+ &precalc->dims.xmax,
+ &precalc->dims.ymin,
+ &precalc->dims.ymax,
+ &precalc->dims.zmin,
+ &precalc->dims.zmax);
+ for (int i = 0; i < 4; i++) {
+ precalc->view[i] = (float)view[i];
+ }
+ if (!invert_m4_m4(precalc->model_inverted, model)) {
+ unit_m4(precalc->model_inverted);
+ return false;
+ }
+ return true;
+}
- gpu_mul_invert_projmat_m4_unmapped_v3(proj, in);
- mul_v3_m4v3(world, model_inverted, in);
+void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc *precalc,
+ const float win[3],
+ float r_world[3])
+{
+ float in[3] = {
+ (win[0] - precalc->view[0]) / precalc->view[2],
+ (win[1] - precalc->view[1]) / precalc->view[3],
+ win[2],
+ };
+ gpu_mul_invert_projmat_m4_unmapped_v3_with_precalc(precalc, in);
+ mul_v3_m4v3(r_world, precalc->model_inverted, in);
}
bool GPU_matrix_unproject(const float win[3],
const float model[4][4],
const float proj[4][4],
const int view[4],
- float world[3])
+ float r_world[3])
{
- float model_inverted[4][4];
-
- if (!invert_m4_m4(model_inverted, model)) {
- zero_v3(world);
+ struct GPUMatrixUnproject_Precalc precalc;
+ if (!GPU_matrix_unproject_precalc(&precalc, model, proj, view)) {
+ zero_v3(r_world);
return false;
}
- GPU_matrix_unproject_model_inverted(win, model_inverted, proj, view, world);
+ GPU_matrix_unproject_with_precalc(&precalc, win, r_world);
return true;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl
index 5c6b8f0a1a1..02bbe545436 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl
@@ -19,13 +19,14 @@ flat out vec4 finalColor;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
-
#ifdef SMOOTH_COLOR
bool is_select = (flag & VERT_UV_SELECT) != 0;
#else
bool is_select = (flag & EDGE_UV_SELECT) != 0;
#endif
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_Position.z = float(!is_select);
+
finalColor = (is_select) ? selectColor : edgeColor;
}