diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2019-06-22 19:30:34 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2019-06-22 19:30:34 +0300 |
commit | 8d17efaf7b71afa6cee252fa81b9e49016dbc118 (patch) | |
tree | 6d9a57c561bc8ffa8d0a9dfbdfcd1c06b0324f0e /source/blender/gpu | |
parent | 5b19ecdc6bfe875a952731d5d2a79bb0be2e9e7e (diff) | |
parent | ab9492648398ecd9265173356d50688ddb3c9aeb (diff) |
Merge branch 'master' into sculpt-mode-features
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_framebuffer.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_matrix.h | 31 | ||||
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 8 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 84 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_framebuffer.c | 26 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_matrix.c | 79 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl | 5 |
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; } |