diff options
Diffstat (limited to 'source/blender/draw/intern')
25 files changed, 770 insertions, 228 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index ab6ea53261f..956bddfb357 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -197,6 +197,17 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } while (0) /* Shaders */ + +#ifndef __GPU_MATERIAL_H__ +/* FIXME: Meh avoid including all GPUMaterial. */ +typedef void (*GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat, + int options, + const char **vert_code, + const char **geom_code, + const char **frag_lib, + const char **defines); +#endif + struct GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, @@ -236,7 +247,8 @@ struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred); + bool deferred, + GPUMaterialEvalCallbackFn callback); struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, struct Material *ma, struct bNodeTree *ntree, @@ -247,7 +259,8 @@ struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred); + bool deferred, + GPUMaterialEvalCallbackFn callback); void DRW_shader_free(struct GPUShader *shader); #define DRW_SHADER_FREE_SAFE(shader) \ do { \ diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 20e346375a7..46b7a88b2a6 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -361,8 +361,8 @@ GPUBatch *DRW_cache_fullscreen_quad_get(void) if (!SHC.drw_fullscreen_quad) { /* Use a triangle instead of a real quad */ /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */ - float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}}; - float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}}; + const float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}}; + const float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}}; /* Position Only 2D format */ static GPUVertFormat format = {0}; @@ -400,7 +400,7 @@ GPUBatch *DRW_cache_quad_get(void) int v = 0; int flag = VCLASS_EMPTY_SCALED; - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; for (int a = 0; a < 4; a++) { GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a][0], p[a][1], 0.0f}, flag}); } @@ -421,7 +421,7 @@ GPUBatch *DRW_cache_quad_wires_get(void) int v = 0; int flag = VCLASS_EMPTY_SCALED; - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; for (int a = 0; a < 5; a++) { GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a % 4][0], p[a % 4][1], 0.0f}, flag}); } @@ -1650,7 +1650,7 @@ GPUBatch *DRW_cache_light_area_square_lines_get(void) int flag = VCLASS_LIGHT_AREA_SHAPE; for (int a = 0; a < 4; a++) { for (int b = 0; b < 2; b++) { - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; float x = p[(a + b) % 4][0]; float y = p[(a + b) % 4][1]; GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x * 0.5f, y * 0.5f, 0.0f}, flag}); @@ -2426,7 +2426,7 @@ static float x_axis_name[4][2] = { {-0.9f * S_X, 1.0f * S_Y}, {1.0f * S_X, -1.0f * S_Y}, }; -#define X_LEN (sizeof(x_axis_name) / (sizeof(float) * 2)) +#define X_LEN (sizeof(x_axis_name) / (sizeof(float[2]))) #undef S_X #undef S_Y @@ -2440,7 +2440,7 @@ static float y_axis_name[6][2] = { {0.0f * S_X, -0.1f * S_Y}, {0.0f * S_X, -1.0f * S_Y}, }; -#define Y_LEN (sizeof(y_axis_name) / (sizeof(float) * 2)) +#define Y_LEN (sizeof(y_axis_name) / (sizeof(float[2]))) #undef S_X #undef S_Y @@ -2458,7 +2458,7 @@ static float z_axis_name[10][2] = { {-1.00f * S_X, -1.00f * S_Y}, {1.00f * S_X, -1.00f * S_Y}, }; -#define Z_LEN (sizeof(z_axis_name) / (sizeof(float) * 2)) +#define Z_LEN (sizeof(z_axis_name) / (sizeof(float[2]))) #undef S_X #undef S_Y @@ -2485,7 +2485,7 @@ static float axis_marker[8][2] = { {-S_X, 0.f} #endif }; -#define MARKER_LEN (sizeof(axis_marker) / (sizeof(float) * 2)) +#define MARKER_LEN (sizeof(axis_marker) / (sizeof(float[2]))) #define MARKER_FILL_LAYER 6 #undef S_X #undef S_Y @@ -2659,7 +2659,7 @@ GPUBatch *DRW_cache_camera_frame_get(void) GPU_vertbuf_data_alloc(vbo, v_len); int v = 0; - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; /* Frame */ for (int a = 0; a < 4; a++) { for (int b = 0; b < 2; b++) { @@ -2740,7 +2740,7 @@ GPUBatch *DRW_cache_camera_tria_wire_get(void) GPU_vertbuf_data_alloc(vbo, v_len); int v = 0; - float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}}; + const float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}}; for (int a = 0; a < 3; a++) { for (int b = 0; b < 2; b++) { float x = p[(a + b) % 3][0]; @@ -2909,9 +2909,8 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob) @@ -2947,9 +2946,8 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface(mesh_eval); } - else { - return DRW_curve_batch_cache_get_triangles_with_normals(cu); - } + + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob) @@ -2961,11 +2959,10 @@ GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - /* TODO */ - UNUSED_VARS(cu); - return NULL; - } + + /* TODO */ + UNUSED_VARS(cu); + return NULL; } GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) @@ -2977,9 +2974,8 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wireframes_face(cu); - } + + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold) @@ -2990,9 +2986,8 @@ GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold); } - else { - return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); - } + + return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); } /* Return list of batches */ @@ -3007,9 +3002,8 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob, if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len); } - else { - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); - } + + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3061,12 +3055,11 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob) if (!has_surface) { return NULL; } - else if (mesh_eval != NULL) { + if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_text_surface_get(Object *ob) @@ -3080,9 +3073,8 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface(mesh_eval); } - else { - return DRW_curve_batch_cache_get_triangles_with_normals(cu); - } + + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold) @@ -3096,9 +3088,8 @@ GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold); } - else { - return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); - } + + return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); } GPUBatch *DRW_cache_text_loose_edges_get(Object *ob) @@ -3112,9 +3103,8 @@ GPUBatch *DRW_cache_text_loose_edges_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) @@ -3128,9 +3118,8 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wireframes_face(cu); - } + + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob, @@ -3146,9 +3135,8 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob, if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len); } - else { - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); - } + + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3166,9 +3154,8 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface(mesh_eval); } - else { - return DRW_curve_batch_cache_get_triangles_with_normals(cu); - } + + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob) @@ -3180,9 +3167,8 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) @@ -3194,9 +3180,8 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wireframes_face(cu); - } + + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold) @@ -3207,9 +3192,8 @@ GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold); } - else { - return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); - } + + return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); } GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob) @@ -3221,11 +3205,10 @@ GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - /* TODO */ - UNUSED_VARS(cu); - return NULL; - } + + /* TODO */ + UNUSED_VARS(cu); + return NULL; } /* Return list of batches */ @@ -3240,9 +3223,8 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob, if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len); } - else { - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); - } + + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3434,8 +3416,8 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines) const int vert_len = segments + 8; const int index_len = vert_len + 5; - uchar red[3] = {255, 0, 0}; - uchar white[3] = {255, 255, 255}; + const uchar red[3] = {255, 0, 0}; + const uchar white[3] = {255, 255, 255}; static GPUVertFormat format = {0}; static struct { diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index 63efc82f87e..934b47d583e 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -474,10 +474,9 @@ BLI_INLINE const float *bm_vert_co_get(const MeshRenderData *mr, const BMVert *e if (vert_coords != NULL) { return vert_coords[BM_elem_index_get(eve)]; } - else { - UNUSED_VARS(mr); - return eve->co; - } + + UNUSED_VARS(mr); + return eve->co; } BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *eve) @@ -486,10 +485,9 @@ BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *e if (vert_normals != NULL) { return vert_normals[BM_elem_index_get(eve)]; } - else { - UNUSED_VARS(mr); - return eve->no; - } + + UNUSED_VARS(mr); + return eve->no; } BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *efa) @@ -498,10 +496,9 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e if (poly_normals != NULL) { return poly_normals[BM_elem_index_get(efa)]; } - else { - UNUSED_VARS(mr); - return efa->no; - } + + UNUSED_VARS(mr); + return efa->no; } /** \} */ @@ -2937,7 +2934,7 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig if ((wstate->defgroup_active < 0) && (wstate->defgroup_len > 0)) { return -2.0f; } - else if (dvert == NULL) { + if (dvert == NULL) { return (wstate->alert_mode != OB_DRAW_GROUPUSER_NONE) ? -1.0f : 0.0f; } @@ -3614,12 +3611,14 @@ static void compute_normalize_edge_vectors(float auv[2][2], normalize_v3(av[1]); } -static short v2_to_short_angle(float v[2]) +static short v2_to_short_angle(const float v[2]) { return atan2f(v[1], v[0]) * (float)M_1_PI * SHRT_MAX; } -static void edituv_get_stretch_angle(float auv[2][2], float av[2][3], UVStretchAngle *r_stretch) +static void edituv_get_stretch_angle(float auv[2][2], + const float av[2][3], + UVStretchAngle *r_stretch) { /* Send UV's to the shader and let it compute the aspect corrected angle. */ r_stretch->uv_angles[0] = v2_to_short_angle(auv[0]); @@ -4295,7 +4294,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) /* non-manifold edge, yet... */ continue; } - else if (*pval != NULL) { + if (*pval != NULL) { const float *f1_no = mr->poly_normals[mp_index]; const float *f2_no = *pval; angle = angle_normalized_v3v3(f1_no, f2_no); diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index e09f78aa51f..fb88945c5aa 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -444,7 +444,7 @@ static void displist_surf_fnors_ensure(const DispList *dl, float (**fnors)[3]) int u_len = dl->nr - ((dl->flag & DL_CYCL_U) ? 0 : 1); int v_len = dl->parts - ((dl->flag & DL_CYCL_V) ? 0 : 1); const float(*verts)[3] = (float(*)[3])dl->verts; - float(*nor_flat)[3] = MEM_mallocN(sizeof(float) * 3 * u_len * v_len, __func__); + float(*nor_flat)[3] = MEM_mallocN(sizeof(float[3]) * u_len * v_len, __func__); *fnors = nor_flat; SURFACE_QUAD_ITER_BEGIN (dl) { diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c index e8355c1d8da..0ab14574fa6 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.c +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c @@ -135,9 +135,8 @@ static GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra) gpencil_batch_cache_clear(cache); return gpencil_batch_cache_init(ob, cfra); } - else { - return cache; - } + + return cache; } void DRW_gpencil_batch_cache_dirty_tag(bGPdata *gpd) diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c index 66a67d6b8fe..0f80b5159a7 100644 --- a/source/blender/draw/intern/draw_cache_impl_lattice.c +++ b/source/blender/draw/intern/draw_cache_impl_lattice.c @@ -83,10 +83,9 @@ static int lattice_render_verts_len_get(Lattice *lt) if ((lt->flag & LT_OUTSIDE) == 0) { return vert_len_calc(u, v, w); } - else { - /* TODO remove internal coords */ - return vert_len_calc(u, v, w); - } + + /* TODO remove internal coords */ + return vert_len_calc(u, v, w); } static int lattice_render_edges_len_get(Lattice *lt) @@ -102,10 +101,9 @@ static int lattice_render_edges_len_get(Lattice *lt) if ((lt->flag & LT_OUTSIDE) == 0) { return edge_len_calc(u, v, w); } - else { - /* TODO remove internal coords */ - return edge_len_calc(u, v, w); - } + + /* TODO remove internal coords */ + return edge_len_calc(u, v, w); } /* ---------------------------------------------------------------------- */ @@ -252,12 +250,11 @@ static bool lattice_batch_cache_valid(Lattice *lt) if (cache->is_dirty) { return false; } - else { - if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) || - (cache->dims.w_len != lt->pntsw) || - ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) { - return false; - } + + if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) || + (cache->dims.w_len != lt->pntsw) || + ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) { + return false; } return true; diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 361c66eca6e..d6faeb16583 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -803,9 +803,8 @@ GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me) if (cache->no_loose_wire) { return NULL; } - else { - return DRW_batch_request(&cache->batch.loose_edges); - } + + return DRW_batch_request(&cache->batch.loose_edges); } GPUBatch *DRW_mesh_batch_cache_get_surface_weights(Mesh *me) diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 331a1f80bec..3ecdbff1e96 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -128,9 +128,8 @@ static bool particle_batch_cache_valid(ParticleSystem *psys) if (cache->is_dirty == false) { return true; } - else { - return false; - } + + return false; return true; } @@ -647,14 +646,13 @@ static float particle_key_weight(const ParticleData *particle, int strand, float if (t == 1.0) { return hkeys[part->totkey - 1].weight; } - else { - float interp = t / edit_key_seg_t; - int index = (int)interp; - interp -= floorf(interp); /* Time between 2 edit key */ - float s1 = hkeys[index].weight; - float s2 = hkeys[index + 1].weight; - return s1 + interp * (s2 - s1); - } + + float interp = t / edit_key_seg_t; + int index = (int)interp; + interp -= floorf(interp); /* Time between 2 edit key */ + float s1 = hkeys[index].weight; + float s2 = hkeys[index + 1].weight; + return s1 + interp * (s2 - s1); } static int particle_batch_cache_fill_segments_edit( diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c index 17902f27513..06cedb9f72c 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c @@ -158,6 +158,7 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache * const bool has_radius = pointcloud->radius != NULL; static GPUVertFormat format = {0}; + static GPUVertFormat format_no_radius = {0}; static uint pos; if (format.attr_len == 0) { /* initialize vertex format */ @@ -167,11 +168,11 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache * * If the vertex shader has more components than the array provides, the extras are given * values from the vector (0, 0, 0, 1) for the missing XYZW components. */ - int comp_len = has_radius ? 4 : 3; - pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, comp_len, GPU_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(&format_no_radius, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } - cache->pos = GPU_vertbuf_create_with_format(&format); + cache->pos = GPU_vertbuf_create_with_format(has_radius ? &format : &format_no_radius); GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint); if (has_radius) { diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h index bb3a908c6c5..06d6f1afc31 100644 --- a/source/blender/draw/intern/draw_cache_inline.h +++ b/source/blender/draw/intern/draw_cache_inline.h @@ -48,7 +48,7 @@ BLI_INLINE GPUBatch *DRW_batch_request(GPUBatch **batch) { /* XXX TODO(fclem): We are writing to batch cache here. Need to make this thread safe. */ if (*batch == NULL) { - *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch"); + *batch = GPU_batch_calloc(1); } return *batch; } diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 095e928aa74..f0d73d5bb84 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -455,11 +455,11 @@ bool DRW_object_is_flat(Object *ob, int *r_axis) *r_axis = 0; return true; } - else if (dim[1] == 0.0f) { + if (dim[1] == 0.0f) { *r_axis = 1; return true; } - else if (dim[2] == 0.0f) { + if (dim[2] == 0.0f) { *r_axis = 2; return true; } @@ -489,7 +489,7 @@ static void DRW_evaluate_weight_to_color(const float weight, float result[4]) * increasing widens yellow/cyan vs red/green/blue. * Gamma 1.0 produces the original 2.79 color ramp. */ const float gamma = 1.5f; - float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)}; + const float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)}; hsv_to_rgb_v(hsv, result); diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index d7bb9b78e09..6060dce47ac 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -26,8 +26,10 @@ struct DRWPass; struct DRWShadingGroup; struct GPUMaterial; struct ModifierData; +struct FluidModifierData; struct Object; struct ParticleSystem; +struct RegionView3D; struct ViewLayer; #define UBO_FIRST_COLOR colorWire @@ -158,14 +160,14 @@ void DRW_globals_update(void); void DRW_globals_free(void); struct DRWView *DRW_view_create_with_zoffset(const struct DRWView *parent_view, - const RegionView3D *rv3d, + const struct RegionView3D *rv3d, float offset); int DRW_object_wire_theme_get(struct Object *ob, struct ViewLayer *view_layer, float **r_color); float *DRW_color_background_blend_get(int theme_id); -bool DRW_object_is_flat(Object *ob, int *r_axis); -bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis); +bool DRW_object_is_flat(struct Object *ob, int *r_axis); +bool DRW_object_axis_orthogonal_to_view(struct Object *ob, int axis); /* draw_hair.c */ @@ -187,6 +189,16 @@ void DRW_hair_init(void); void DRW_hair_update(void); void DRW_hair_free(void); +/* draw_fluid.c */ + +/* Fluid simulation. */ +void DRW_smoke_ensure(struct FluidModifierData *fmd, int highres); +void DRW_smoke_ensure_coba_field(struct FluidModifierData *fmd); +void DRW_smoke_ensure_velocity(struct FluidModifierData *fmd); + +void DRW_smoke_free(struct FluidModifierData *fmd); +void DRW_smoke_free_velocity(struct FluidModifierData *fmd); + /* draw_common.c */ struct DRW_Global { /** If needed, contains all global/Theme colors diff --git a/source/blender/draw/intern/draw_fluid.c b/source/blender/draw/intern/draw_fluid.c new file mode 100644 index 00000000000..fea379126d2 --- /dev/null +++ b/source/blender/draw/intern/draw_fluid.c @@ -0,0 +1,419 @@ +/* + * 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. + */ + +/** \file + * \ingroup gpu + * + * GPU fluid drawing functions. + */ + +#include <string.h> + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_fluid_types.h" +#include "DNA_modifier_types.h" + +#include "MEM_guardedalloc.h" + +#include "BKE_colorband.h" + +#include "GPU_texture.h" + +#include "draw_common.h" /* Own include. */ + +#ifdef WITH_FLUID +# include "manta_fluid_API.h" +#endif + +/* -------------------------------------------------------------------- */ +/** \name Private API + * \{ */ + +#ifdef WITH_FLUID + +enum { + TFUNC_FLAME_SPECTRUM = 0, + TFUNC_COLOR_RAMP = 1, +}; + +# define TFUNC_WIDTH 256 + +static void create_flame_spectrum_texture(float *data) +{ +# define FIRE_THRESH 7 +# define MAX_FIRE_ALPHA 0.06f +# define FULL_ON_FIRE 100 + + float *spec_pixels = (float *)MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), + "spec_pixels"); + + blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000); + + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + for (int k = 0; k < TFUNC_WIDTH; k++) { + int index = (j * TFUNC_WIDTH * 16 + i * TFUNC_WIDTH + k) * 4; + if (k >= FIRE_THRESH) { + spec_pixels[index] = (data[k * 4]); + spec_pixels[index + 1] = (data[k * 4 + 1]); + spec_pixels[index + 2] = (data[k * 4 + 2]); + spec_pixels[index + 3] = MAX_FIRE_ALPHA * + ((k > FULL_ON_FIRE) ? + 1.0f : + (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); + } + else { + zero_v4(&spec_pixels[index]); + } + } + } + } + + memcpy(data, spec_pixels, sizeof(float) * 4 * TFUNC_WIDTH); + + MEM_freeN(spec_pixels); + +# undef FIRE_THRESH +# undef MAX_FIRE_ALPHA +# undef FULL_ON_FIRE +} + +static void create_color_ramp(const struct ColorBand *coba, float *data) +{ + for (int i = 0; i < TFUNC_WIDTH; i++) { + BKE_colorband_evaluate(coba, (float)i / TFUNC_WIDTH, &data[i * 4]); + straight_to_premul_v4(&data[i * 4]); + } +} + +static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba) +{ + float *data = (float *)MEM_mallocN(sizeof(float[4]) * TFUNC_WIDTH, __func__); + + switch (type) { + case TFUNC_FLAME_SPECTRUM: + create_flame_spectrum_texture(data); + break; + case TFUNC_COLOR_RAMP: + create_color_ramp(coba, data); + break; + } + + GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_SRGB8_A8, data, NULL); + + MEM_freeN(data); + + return tex; +} + +static void swizzle_texture_channel_single(GPUTexture *tex) +{ + /* Swizzle texture channels so that we get useful RGBA values when sampling + * a texture with fewer channels, e.g. when using density as color. */ + GPU_texture_bind(tex, 0); + GPU_texture_swizzle_set(tex, "rrr1"); + GPU_texture_unbind(tex); +} + +static GPUTexture *create_field_texture(FluidDomainSettings *fds) +{ + float *field = NULL; + + switch (fds->coba_field) { + case FLUID_DOMAIN_FIELD_DENSITY: + field = manta_smoke_get_density(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_HEAT: + field = manta_smoke_get_heat(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_FUEL: + field = manta_smoke_get_fuel(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_REACT: + field = manta_smoke_get_react(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_FLAME: + field = manta_smoke_get_flame(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_VELOCITY_X: + field = manta_get_velocity_x(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_VELOCITY_Y: + field = manta_get_velocity_y(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_VELOCITY_Z: + field = manta_get_velocity_z(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_COLOR_R: + field = manta_smoke_get_color_r(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_COLOR_G: + field = manta_smoke_get_color_g(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_COLOR_B: + field = manta_smoke_get_color_b(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_FORCE_X: + field = manta_get_force_x(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_FORCE_Y: + field = manta_get_force_y(fds->fluid); + break; + case FLUID_DOMAIN_FIELD_FORCE_Z: + field = manta_get_force_z(fds->fluid); + break; + default: + return NULL; + } + + GPUTexture *tex = GPU_texture_create_nD( + UNPACK3(fds->res), 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + + swizzle_texture_channel_single(tex); + return tex; +} + +static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres) +{ + int *dim = (highres) ? fds->res_noise : fds->res; + + float *data; + if (highres) { + data = manta_noise_get_density(fds->fluid); + } + else { + data = manta_smoke_get_density(fds->fluid); + } + + GPUTexture *tex = GPU_texture_create_nD( + UNPACK3(dim), 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + + swizzle_texture_channel_single(tex); + + return tex; +} + +static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres) +{ + const bool has_color = (highres) ? manta_noise_has_colors(fds->fluid) : + manta_smoke_has_colors(fds->fluid); + + if (!has_color) { + return NULL; + } + + int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells; + int *dim = (highres) ? fds->res_noise : fds->res; + float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); + + if (data == NULL) { + return NULL; + } + + if (highres) { + manta_noise_get_rgba(fds->fluid, data, 0); + } + else { + manta_smoke_get_rgba(fds->fluid, data, 0); + } + + GPUTexture *tex = GPU_texture_create_nD( + dim[0], dim[1], dim[2], 3, data, GPU_RGBA8, GPU_DATA_FLOAT, 0, true, NULL); + + MEM_freeN(data); + + return tex; +} + +static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres) +{ + float *source = NULL; + const bool has_fuel = (highres) ? manta_noise_has_fuel(fds->fluid) : + manta_smoke_has_fuel(fds->fluid); + int *dim = (highres) ? fds->res_noise : fds->res; + + if (!has_fuel) { + return NULL; + } + + if (highres) { + source = manta_noise_get_flame(fds->fluid); + } + else { + source = manta_smoke_get_flame(fds->fluid); + } + + GPUTexture *tex = GPU_texture_create_nD( + dim[0], dim[1], dim[2], 3, source, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + + swizzle_texture_channel_single(tex); + + return tex; +} + +#endif /* WITH_FLUID */ + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Public API + * \{ */ + +void DRW_smoke_free(FluidModifierData *fmd) +{ + if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { + if (fmd->domain->tex_density) { + GPU_texture_free(fmd->domain->tex_density); + fmd->domain->tex_density = NULL; + } + + if (fmd->domain->tex_color) { + GPU_texture_free(fmd->domain->tex_color); + fmd->domain->tex_color = NULL; + } + + if (fmd->domain->tex_shadow) { + GPU_texture_free(fmd->domain->tex_shadow); + fmd->domain->tex_shadow = NULL; + } + + if (fmd->domain->tex_flame) { + GPU_texture_free(fmd->domain->tex_flame); + fmd->domain->tex_flame = NULL; + } + + if (fmd->domain->tex_flame_coba) { + GPU_texture_free(fmd->domain->tex_flame_coba); + fmd->domain->tex_flame_coba = NULL; + } + + if (fmd->domain->tex_coba) { + GPU_texture_free(fmd->domain->tex_coba); + fmd->domain->tex_coba = NULL; + } + + if (fmd->domain->tex_field) { + GPU_texture_free(fmd->domain->tex_field); + fmd->domain->tex_field = NULL; + } + } +} + +void DRW_smoke_ensure_coba_field(FluidModifierData *fmd) +{ +#ifndef WITH_FLUID + UNUSED_VARS(fmd); +#else + if (fmd->type & MOD_FLUID_TYPE_DOMAIN) { + FluidDomainSettings *fds = fmd->domain; + + if (!fds->tex_field) { + fds->tex_field = create_field_texture(fds); + } + if (!fds->tex_coba) { + fds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, fds->coba); + } + } +#endif +} + +void DRW_smoke_ensure(FluidModifierData *fmd, int highres) +{ +#ifndef WITH_FLUID + UNUSED_VARS(fmd, highres); +#else + if (fmd->type & MOD_FLUID_TYPE_DOMAIN) { + FluidDomainSettings *fds = fmd->domain; + + if (!fds->tex_density) { + fds->tex_density = create_density_texture(fds, highres); + } + if (!fds->tex_color) { + fds->tex_color = create_color_texture(fds, highres); + } + if (!fds->tex_flame) { + fds->tex_flame = create_flame_texture(fds, highres); + } + if (!fds->tex_flame_coba && fds->tex_flame) { + fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); + } + if (!fds->tex_shadow) { + fds->tex_shadow = GPU_texture_create_nD(UNPACK3(fds->res), + 3, + manta_smoke_get_shadow(fds->fluid), + GPU_R8, + GPU_DATA_FLOAT, + 0, + true, + NULL); + } + } +#endif /* WITH_FLUID */ +} + +void DRW_smoke_ensure_velocity(FluidModifierData *fmd) +{ +#ifndef WITH_FLUID + UNUSED_VARS(fmd); +#else + if (fmd->type & MOD_FLUID_TYPE_DOMAIN) { + FluidDomainSettings *fds = fmd->domain; + + const float *vel_x = manta_get_velocity_x(fds->fluid); + const float *vel_y = manta_get_velocity_y(fds->fluid); + const float *vel_z = manta_get_velocity_z(fds->fluid); + + if (ELEM(NULL, vel_x, vel_y, vel_z)) { + return; + } + + if (!fds->tex_velocity_x) { + fds->tex_velocity_x = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_x, NULL); + fds->tex_velocity_y = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_y, NULL); + fds->tex_velocity_z = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_z, NULL); + } + } +#endif /* WITH_FLUID */ +} + +/* TODO Unify with the other DRW_smoke_free. */ +void DRW_smoke_free_velocity(FluidModifierData *fmd) +{ + if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { + if (fmd->domain->tex_velocity_x) { + GPU_texture_free(fmd->domain->tex_velocity_x); + } + + if (fmd->domain->tex_velocity_y) { + GPU_texture_free(fmd->domain->tex_velocity_y); + } + + if (fmd->domain->tex_velocity_z) { + GPU_texture_free(fmd->domain->tex_velocity_z); + } + + fmd->domain->tex_velocity_x = NULL; + fmd->domain->tex_velocity_y = NULL; + fmd->domain->tex_velocity_z = NULL; + } +} + +/** \} */ diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c index cbdcbbf9090..1992b1d291e 100644 --- a/source/blender/draw/intern/draw_hair.c +++ b/source/blender/draw/intern/draw_hair.c @@ -114,7 +114,7 @@ void DRW_hair_init(void) g_dummy_vbo = GPU_vertbuf_create_with_format(&format); - float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_vertbuf_data_alloc(g_dummy_vbo, 1); GPU_vertbuf_attr_fill(g_dummy_vbo, dummy_id, vert); /* Create vbo immediately to bind to texture buffer. */ @@ -330,7 +330,7 @@ void DRW_hair_update(void) GPU_ATTACHMENT_TEXTURE(tex), }); - float *data = MEM_mallocN(sizeof(float) * 4 * width * height, "tf fallback buffer"); + float *data = MEM_mallocN(sizeof(float[4]) * width * height, "tf fallback buffer"); GPU_framebuffer_bind(fb); while (g_tf_calls != NULL) { @@ -347,8 +347,8 @@ void DRW_hair_update(void) /* Upload back to VBO. */ GPU_vertbuf_use(pr_call->vbo); glBufferSubData(GL_ARRAY_BUFFER, - sizeof(float) * 4 * g_tf_id_offset, - sizeof(float) * 4 * max_read_px_len, + sizeof(float[4]) * g_tf_id_offset, + sizeof(float[4]) * max_read_px_len, data); g_tf_id_offset += max_read_px_len; diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index 45c201501b3..5005f38c558 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -92,8 +92,9 @@ static void instance_batch_free(GPUBatch *geom, void *UNUSED(user_data)) BLI_memblock *memblock = data_list->pool_instancing; BLI_memblock_iter iter; BLI_memblock_iternew(memblock, &iter); - GPUBatch *batch; - while ((batch = (GPUBatch *)BLI_memblock_iterstep(&iter))) { + GPUBatch **batch_ptr; + while ((batch_ptr = (GPUBatch **)BLI_memblock_iterstep(&iter))) { + GPUBatch *batch = *batch_ptr; /* Only check verts[0] that's enough. */ if (batch->verts[0] == geom->verts[0]) { GPU_batch_clear(batch); @@ -142,7 +143,12 @@ GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist, /* Only call with one of them. */ BLI_assert((instancer != NULL) != (buf != NULL)); - GPUBatch *batch = BLI_memblock_alloc(idatalist->pool_instancing); + GPUBatch **batch_ptr = BLI_memblock_alloc(idatalist->pool_instancing); + if (*batch_ptr == NULL) { + *batch_ptr = GPU_batch_calloc(1); + } + + GPUBatch *batch = *batch_ptr; bool instancer_compat = buf ? ((batch->inst[0] == buf) && (buf->vbo_id != 0)) : ((batch->inst[0] == instancer->inst[0]) && (batch->inst[1] == instancer->inst[1])); @@ -173,7 +179,12 @@ GPUBatch *DRW_temp_batch_request(DRWInstanceDataList *idatalist, GPUVertBuf *buf, GPUPrimType prim_type) { - GPUBatch *batch = BLI_memblock_alloc(idatalist->pool_batching); + GPUBatch **batch_ptr = BLI_memblock_alloc(idatalist->pool_instancing); + if (*batch_ptr == NULL) { + *batch_ptr = GPU_batch_calloc(1); + } + + GPUBatch *batch = *batch_ptr; bool is_compatible = (batch->verts[0] == buf) && (buf->vbo_id != 0) && (batch->gl_prim_type == convert_prim_type_to_gl(prim_type)); if (!is_compatible) { @@ -189,6 +200,11 @@ static void temp_buffer_handle_free(DRWTempBufferHandle *handle) GPU_vertbuf_clear(&handle->buf); } +static void temp_batch_free(GPUBatch **batch) +{ + GPU_BATCH_DISCARD_SAFE(*batch); +} + void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) { /* Resize down buffers in use and send data to GPU. */ @@ -207,10 +223,11 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) } } /* Finish pending instancing batches. */ - GPUBatch *batch; + GPUBatch **batch_ptr; BLI_memblock_iternew(idatalist->pool_instancing, &iter); - while ((batch = BLI_memblock_iterstep(&iter))) { - if (batch->phase == GPU_BATCH_READY_TO_BUILD) { + while ((batch_ptr = BLI_memblock_iterstep(&iter))) { + GPUBatch *batch = *batch_ptr; + if (batch && batch->phase == GPU_BATCH_READY_TO_BUILD) { GPUVertBuf *inst_buf = batch->inst[0]; /* HACK see DRW_temp_batch_instance_request. */ GPUBatch *inst_batch = (void *)batch->inst[1]; @@ -228,8 +245,8 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) } /* Resize pools and free unused. */ BLI_memblock_clear(idatalist->pool_buffers, (MemblockValFreeFP)temp_buffer_handle_free); - BLI_memblock_clear(idatalist->pool_instancing, (MemblockValFreeFP)GPU_batch_clear); - BLI_memblock_clear(idatalist->pool_batching, (MemblockValFreeFP)GPU_batch_clear); + BLI_memblock_clear(idatalist->pool_instancing, (MemblockValFreeFP)temp_batch_free); + BLI_memblock_clear(idatalist->pool_batching, (MemblockValFreeFP)temp_batch_free); } /** \} */ @@ -300,8 +317,8 @@ DRWInstanceDataList *DRW_instance_data_list_create(void) { DRWInstanceDataList *idatalist = MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList"); - idatalist->pool_batching = BLI_memblock_create(sizeof(GPUBatch)); - idatalist->pool_instancing = BLI_memblock_create(sizeof(GPUBatch)); + idatalist->pool_batching = BLI_memblock_create(sizeof(GPUBatch *)); + idatalist->pool_instancing = BLI_memblock_create(sizeof(GPUBatch *)); idatalist->pool_buffers = BLI_memblock_create(sizeof(DRWTempBufferHandle)); BLI_addtail(&g_idatalists, idatalist); @@ -324,8 +341,8 @@ void DRW_instance_data_list_free(DRWInstanceDataList *idatalist) } BLI_memblock_destroy(idatalist->pool_buffers, (MemblockValFreeFP)temp_buffer_handle_free); - BLI_memblock_destroy(idatalist->pool_instancing, (MemblockValFreeFP)GPU_batch_clear); - BLI_memblock_destroy(idatalist->pool_batching, (MemblockValFreeFP)GPU_batch_clear); + BLI_memblock_destroy(idatalist->pool_instancing, (MemblockValFreeFP)temp_batch_free); + BLI_memblock_destroy(idatalist->pool_batching, (MemblockValFreeFP)temp_batch_free); BLI_remlink(&g_idatalists, idatalist); } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2beab021cfb..4a5e07476a9 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -792,9 +792,8 @@ DrawDataList *DRW_drawdatalist_from_id(ID *id) IdDdtTemplate *idt = (IdDdtTemplate *)id; return &idt->drawdata; } - else { - return NULL; - } + + return NULL; } DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type) @@ -2031,7 +2030,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, } } - int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; + const int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; struct GPUViewport *viewport = GPU_viewport_create(); GPU_viewport_size_set(viewport, viewport_size); @@ -2723,7 +2722,7 @@ void DRW_engines_free(void) void DRW_render_context_enable(Render *render) { if (G.background && DST.gl_context == NULL) { - WM_init_opengl(G_MAIN); + WM_init_opengl(); } if (GPU_use_main_context_workaround()) { @@ -2854,7 +2853,7 @@ void DRW_opengl_context_disable_ex(bool restore) void DRW_opengl_context_enable(void) { if (G.background && DST.gl_context == NULL) { - WM_init_opengl(G_MAIN); + WM_init_opengl(); } DRW_opengl_context_enable_ex(true); } diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 9d8050504ab..c12b4a96488 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -582,7 +582,7 @@ uint32_t DRW_object_resource_id_get(Object *UNUSED(ob)) /* Handle not yet allocated. Return next handle. */ handle = DST.resource_handle; } - return handle & ~(1 << 31); + return handle & ~(1u << 31); } static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup, @@ -594,28 +594,26 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup, DRWResourceHandle handle = 0; return handle; } - else { - return drw_resource_handle_new(obmat, NULL); - } + + return drw_resource_handle_new(obmat, NULL); + } + + if (DST.ob_handle == 0) { + DST.ob_handle = drw_resource_handle_new(obmat, ob); + DST.ob_state_obinfo_init = false; } - else { - if (DST.ob_handle == 0) { - DST.ob_handle = drw_resource_handle_new(obmat, ob); - DST.ob_state_obinfo_init = false; - } - if (shgroup->objectinfo) { - if (!DST.ob_state_obinfo_init) { - DST.ob_state_obinfo_init = true; - DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos, - &DST.ob_handle); + if (shgroup->objectinfo) { + if (!DST.ob_state_obinfo_init) { + DST.ob_state_obinfo_init = true; + DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos, + &DST.ob_handle); - drw_call_obinfos_init(ob_infos, ob); - } + drw_call_obinfos_init(ob_infos, ob); } - - return DST.ob_handle; } + + return DST.ob_handle; } static void command_type_set(uint64_t *command_type_bits, int index, eDRWCommandType type) @@ -1292,13 +1290,10 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass } static void drw_shgroup_material_texture(DRWShadingGroup *grp, - GPUMaterialTexture *tex, + GPUTexture *gputex, const char *name, - eGPUSamplerState state, - int textarget) + eGPUSamplerState state) { - GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget); - DRW_shgroup_uniform_texture_ex(grp, name, gputex, state); GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images); @@ -1314,15 +1309,16 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial LISTBASE_FOREACH (GPUMaterialTexture *, tex, &textures) { if (tex->ima) { /* Image */ + GPUTexture *gputex; if (tex->tiled_mapping_name[0]) { - drw_shgroup_material_texture( - grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D_ARRAY); - drw_shgroup_material_texture( - grp, tex, tex->tiled_mapping_name, tex->sampler_state, GL_TEXTURE_1D_ARRAY); + gputex = BKE_image_get_gpu_tiles(tex->ima, tex->iuser, NULL); + drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state); + gputex = BKE_image_get_gpu_tilemap(tex->ima, tex->iuser, NULL); + drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state); } else { - drw_shgroup_material_texture( - grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D); + gputex = BKE_image_get_gpu_texture(tex->ima, tex->iuser, NULL); + drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state); } } else if (tex->colorband) { @@ -1870,7 +1866,7 @@ void DRW_view_clip_planes_set(DRWView *view, float (*planes)[4], int plane_len) BLI_assert(plane_len <= MAX_CLIP_PLANES); view->clip_planes_len = plane_len; if (plane_len > 0) { - memcpy(view->storage.clipplanes, planes, sizeof(float) * 4 * plane_len); + memcpy(view->storage.clipplanes, planes, sizeof(float[4]) * plane_len); } } @@ -1906,9 +1902,8 @@ float DRW_view_near_distance_get(const DRWView *view) if (DRW_view_is_persp_get(view)) { return -projmat[3][2] / (projmat[2][2] - 1.0f); } - else { - return -(projmat[3][2] + 1.0f) / projmat[2][2]; - } + + return -(projmat[3][2] + 1.0f) / projmat[2][2]; } float DRW_view_far_distance_get(const DRWView *view) @@ -1919,9 +1914,8 @@ float DRW_view_far_distance_get(const DRWView *view) if (DRW_view_is_persp_get(view)) { return -projmat[3][2] / (projmat[2][2] + 1.0f); } - else { - return -(projmat[3][2] - 1.0f) / projmat[2][2]; - } + + return -(projmat[3][2] - 1.0f) / projmat[2][2]; } void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse) @@ -2028,18 +2022,16 @@ static int pass_shgroup_dist_sort(const void *a, const void *b) if (shgrp_a->z_sorting.distance < shgrp_b->z_sorting.distance) { return 1; } - else if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) { + if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) { return -1; } - else { - /* If distances are the same, keep original order. */ - if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) { - return -1; - } - else { - return 0; - } + + /* If distances are the same, keep original order. */ + if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) { + return -1; } + + return 0; } /* ------------------ Shading group sorting --------------------- */ diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index b6f51ada5a1..e3860b1bfb2 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -446,6 +446,7 @@ void DRW_state_reset(void) DRW_state_reset_ex(DRW_STATE_DEFAULT); GPU_texture_unbind_all(); + GPU_uniformbuffer_unbind_all(); /* Should stay constant during the whole rendering. */ GPU_point_size(5); @@ -517,7 +518,7 @@ static bool draw_culling_box_test(const float (*frustum_planes)[4], const BoundB * Go to next plane. */ break; } - else if (v == 7) { + if (v == 7) { /* 8 points behind this plane. */ return false; } @@ -591,7 +592,7 @@ void DRW_culling_frustum_corners_get(const DRWView *view, BoundBox *corners) void DRW_culling_frustum_planes_get(const DRWView *view, float planes[6][4]) { view = view ? view : DST.view_default; - memcpy(planes, view->frustum_planes, sizeof(float) * 6 * 4); + memcpy(planes, view->frustum_planes, sizeof(float[6][4])); } static void draw_compute_culling(DRWView *view) @@ -669,8 +670,7 @@ BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom) DST.batch = geom; - GPU_batch_program_set_no_use( - geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader)); + GPU_batch_set_shader_no_bind(geom, shgroup->shader); geom->program_in_use = true; /* XXX hacking #GPUBatch */ @@ -773,10 +773,11 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup) DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes, &shgroup->pass_handle); - printf("Pass : %s, Shader : %s, Block : %s\n", + printf("Pass : %s, Shader : %s, Block : %s, Binding %d\n", parent_pass->name, shgroup->shader->name, - blockname); + blockname, + binding); } } # endif @@ -994,9 +995,8 @@ static void draw_call_single_do(DRWShadingGroup *shgroup, draw_select_buffer(shgroup, state, batch, &handle); return; } - else { - GPU_select_load_id(state->select_id); - } + + GPU_select_load_id(state->select_id); } draw_geometry_execute(shgroup, @@ -1106,6 +1106,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) /* Unbinding can be costly. Skip in normal condition. */ if (G.debug & G_DEBUG_GPU) { GPU_texture_unbind_all(); + GPU_uniformbuffer_unbind_all(); } } GPU_shader_bind(shgroup->shader); diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 34069438e47..1c260721efb 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -447,7 +447,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred) + bool deferred, + GPUMaterialEvalCallbackFn callback) { GPUMaterial *mat = NULL; if (DRW_state_is_image_render() || !deferred) { @@ -467,7 +468,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, geom, frag_lib, defines, - wo->id.name); + wo->id.name, + callback); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { @@ -487,7 +489,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred) + bool deferred, + GPUMaterialEvalCallbackFn callback) { GPUMaterial *mat = NULL; if (DRW_state_is_image_render() || !deferred) { @@ -507,7 +510,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, geom, frag_lib, defines, - ma->id.name); + ma->id.name, + callback); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c index 84c8d0f861f..ee5561e1e38 100644 --- a/source/blender/draw/intern/draw_select_buffer.c +++ b/source/blender/draw/intern/draw_select_buffer.c @@ -395,7 +395,7 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph, int center_x = width / 2; int center_y = height / 2; - /* Manhatten distance in keeping with other screen-based selection. */ + /* Manhattan distance in keeping with other screen-based selection. */ *dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y)); /* Indices start at 1 here. */ diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 3c470f802ec..1458ff5341c 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -88,7 +88,7 @@ static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, Vie /* no exception met? then don't draw cursor! */ return false; } - else if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) { + if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) { /* grease pencil hide always in some modes */ return false; } @@ -184,8 +184,7 @@ void DRW_draw_cursor(void) GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); - GPU_batch_program_set( - cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); + GPU_batch_set_shader(cursor_batch, shader); GPU_batch_draw(cursor_batch); diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index ffff631e34b..8684d82f228 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -95,7 +95,7 @@ void hair_get_interp_attrs( * For final drawing, the vertex index and the number of vertex per segment */ -#ifndef HAIR_PHASE_SUBDIV +#if !defined(HAIR_PHASE_SUBDIV) && defined(GPU_VERTEX_SHADER) int hair_get_strand_id(void) { return gl_VertexID / (hairStrandsRes * hairThicknessRes); @@ -206,4 +206,24 @@ vec3 hair_get_strand_pos(void) return texelFetch(hairPointBuffer, id).point_position; } +vec2 hair_get_barycentric(void) +{ + /* To match cycles without breaking into individual segment we encode if we need to invert + * the first component into the second component. We invert if the barycentricTexCo.y + * is NOT 0.0 or 1.0. */ + int id = hair_get_base_id(); + return vec2(float((id % 2) == 1), float(((id % 4) % 3) > 0)); +} + #endif + +/* To be fed the result of hair_get_barycentric from vertex shader. */ +vec2 hair_resolve_barycentric(vec2 vert_barycentric) +{ + if (fract(vert_barycentric.y) != 0.0) { + return vec2(vert_barycentric.x, 0.0); + } + else { + return vec2(1.0 - vert_barycentric.x, 0.0); + } +} diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl index e337376d7c4..643d7e7d942 100644 --- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl @@ -116,4 +116,4 @@ vec3 normal_decode(vec2 enc, vec3 view) return n; } -/** \} */
\ No newline at end of file +/** \} */ diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl index 36b67f2bd60..625e8bb1ff8 100644 --- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl +++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl @@ -36,4 +36,4 @@ vec3 pointcloud_get_pos(void) vec3 outpos, outnor; pointcloud_get_pos_and_nor(outpos, outnor); return outpos; -}
\ No newline at end of file +} diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index c77537bbe48..73c112fe3fb 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -22,6 +22,16 @@ layout(std140) uniform viewBlock vec4 CameraTexCoFactors; }; +#define ViewNear (ViewVecs[0].w) +#define ViewFar (ViewVecs[1].w) + +#define cameraForward ViewMatrixInverse[2].xyz +#define cameraPos ViewMatrixInverse[3].xyz +#define cameraVec \ + ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) +#define viewCameraVec \ + ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) + #ifdef world_clip_planes_calc_clip_distance # undef world_clip_planes_calc_clip_distance # define world_clip_planes_calc_clip_distance(p) \ @@ -104,10 +114,13 @@ uniform int resourceId; /* Use this to declare and pass the value if * the fragment shader uses the resource_id. */ -# define RESOURCE_ID_VARYING flat out int resourceIDFrag; -# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom; -# define PASS_RESOURCE_ID resourceIDFrag = resource_id; -# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id; +# ifdef USE_GEOMETRY_SHADER +# define RESOURCE_ID_VARYING flat out int resourceIDGeom; +# define PASS_RESOURCE_ID resourceIDGeom = resource_id; +# else +# define RESOURCE_ID_VARYING flat out int resourceIDFrag; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id; +# endif #endif /* If used in a fragment / geometry shader, we pass @@ -118,7 +131,7 @@ uniform int resourceId; flat in int resourceIDGeom[]; # define resource_id resourceIDGeom -# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i]; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id[0]; #endif #ifdef GPU_FRAGMENT_SHADER @@ -171,9 +184,12 @@ uniform mat4 ModelMatrixInverse; * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. * ViewMatrix * transpose(ModelMatrixInverse) **/ -#define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) -#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) -#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) +#define NormalMatrix transpose(mat3(ModelMatrixInverse)) +#define NormalMatrixInverse transpose(mat3(ModelMatrix)) + +#define normal_object_to_view(n) (mat3(ViewMatrix) * (NormalMatrix * n)) +#define normal_object_to_world(n) (NormalMatrix * n) +#define normal_world_to_object(n) (NormalMatrixInverse * n) #define normal_world_to_view(n) (mat3(ViewMatrix) * n) #define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n) @@ -199,3 +215,78 @@ uniform mat4 ModelMatrixInverse; #define DRW_BASE_FROM_DUPLI (1 << 2) #define DRW_BASE_FROM_SET (1 << 3) #define DRW_BASE_ACTIVE (1 << 4) + +/* ---- Opengl Depth conversion ---- */ + +float linear_depth(bool is_persp, float z, float zf, float zn) +{ + if (is_persp) { + return (zn * zf) / (z * (zn - zf) + zf); + } + else { + return (z * 2.0 - 1.0) * zf; + } +} + +float buffer_depth(bool is_persp, float z, float zf, float zn) +{ + if (is_persp) { + return (zf * (zn - z)) / (z * (zn - zf)); + } + else { + return (z / (zf * 2.0)) + 0.5; + } +} + +float get_view_z_from_depth(float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); + } + else { + return ViewVecs[0].z + depth * ViewVecs[1].z; + } +} + +float get_depth_from_view_z(float z) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; + return d * 0.5 + 0.5; + } + else { + return (z - ViewVecs[0].z) / ViewVecs[1].z; + } +} + +vec2 get_uvs_from_view(vec3 view) +{ + vec4 ndc = ProjectionMatrix * vec4(view, 1.0); + return (ndc.xy / ndc.w) * 0.5 + 0.5; +} + +vec3 get_view_space_from_depth(vec2 uvcoords, float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + return vec3(ViewVecs[0].xy + uvcoords * ViewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); + } + else { + return ViewVecs[0].xyz + vec3(uvcoords, depth) * ViewVecs[1].xyz; + } +} + +vec3 get_world_space_from_depth(vec2 uvcoords, float depth) +{ + return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; +} + +vec3 get_view_vector_from_screen_uv(vec2 uv) +{ + if (ProjectionMatrix[3][3] == 0.0) { + return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0)); + } + else { + return vec3(0.0, 0.0, 1.0); + } +} |