diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 5 | ||||
-rw-r--r-- | source/blender/gpu/GPU_draw.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 109 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 53 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 8 |
5 files changed, 132 insertions, 47 deletions
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 1729ac06f5a..745ca1ef2ac 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -162,8 +162,9 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], struct MFace *mface, struct MVert *mvert, int *face_indices, int totface); -void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert, - int *vert_indices, int totvert, const float *vmask); +void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MFace *mface, int *face_indices, int totface, + struct MVert *mvert, int *vert_indices, int totvert, + int (*face_vert_indices)[4], const float *vmask); GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid, unsigned int **grid_hidden, int gridsize); diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 467adbe10b8..7d829bd57bf 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -75,6 +75,8 @@ void GPU_end_object_materials(void); int GPU_enable_material(int nr, void *attribs); void GPU_disable_material(void); +void GPU_material_diffuse_get(int nr, float diff[4]); + void GPU_set_material_alpha_blend(int alphablend); int GPU_get_material_alpha_blend(void); @@ -119,7 +121,7 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap); /* Image updates and free * - these deal with images bound as opengl textures */ -void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h, int mipmap); +void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h); void GPU_update_images_framechange(void); int GPU_update_image_time(struct Image *ima, double time); int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, int compare, int mipmap, int ncd); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index c44a181841e..930573ec750 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -54,6 +54,7 @@ #include "DNA_userdef_types.h" #include "GPU_buffers.h" +#include "GPU_draw.h" typedef enum { GPU_BUFFER_VERTEX_STATE = 1, @@ -1280,6 +1281,8 @@ typedef struct { char pad[2]; unsigned char color[3]; + float accum_color[3]; + int tot_color; } VertexBufferFormat; struct GPU_Buffers { @@ -1327,24 +1330,24 @@ static void gpu_colors_disable(VBO_State vbo_state) static float gpu_color_from_mask(float mask) { - return (1.0f - mask) * 0.5f + 0.25f; + return 1.0f - mask; } -static void gpu_color_from_mask_copy(float mask, unsigned char out[3]) +static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3]) { - unsigned char color; - - color = gpu_color_from_mask(mask) * 255.0f; + float mask_color; + + mask_color = gpu_color_from_mask(mask) * 255.0f; - out[0] = color; - out[1] = color; - out[2] = color; + out[0] = diffuse_color[0] * mask_color; + out[1] = diffuse_color[1] * mask_color; + out[2] = diffuse_color[2] * mask_color; } -static void gpu_color_from_mask_set(float mask) +static void gpu_color_from_mask_set(float mask, float diffuse_color[4]) { float color = gpu_color_from_mask(mask); - glColor3f(color, color, color); + glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color); } static float gpu_color_from_mask_quad(const CCGKey *key, @@ -1360,29 +1363,32 @@ static float gpu_color_from_mask_quad(const CCGKey *key, static void gpu_color_from_mask_quad_copy(const CCGKey *key, CCGElem *a, CCGElem *b, CCGElem *c, CCGElem *d, + const float *diffuse_color, unsigned char out[3]) { - unsigned char color = + float mask_color = gpu_color_from_mask((*CCG_elem_mask(key, a) + *CCG_elem_mask(key, b) + *CCG_elem_mask(key, c) + *CCG_elem_mask(key, d)) * 0.25f) * 255.0f; - out[0] = color; - out[1] = color; - out[2] = color; + out[0] = diffuse_color[0] * mask_color; + out[1] = diffuse_color[1] * mask_color; + out[2] = diffuse_color[2] * mask_color; } static void gpu_color_from_mask_quad_set(const CCGKey *key, CCGElem *a, CCGElem *b, - CCGElem *c, CCGElem *d) + CCGElem *c, CCGElem *d, + float diffuse_color[4]) { float color = gpu_color_from_mask_quad(key, a, b, c, d); - glColor3f(color, color, color); + glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color); } -void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert, - int *vert_indices, int totvert, const float *vmask) +void GPU_update_mesh_buffers(GPU_Buffers *buffers, MFace *mface, int *face_indices, int totface, + MVert *mvert, int *vert_indices, int totvert, + int (*face_vert_indices)[4], const float *vmask) { VertexBufferFormat *vert_data; int i; @@ -1404,8 +1410,40 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert, copy_v3_v3(out->co, v->co); memcpy(out->no, v->no, sizeof(short) * 3); - gpu_color_from_mask_copy(vmask[vert_indices[i]], - out->color); + zero_v3(out->accum_color); + out->tot_color = 0; + } + +#define UPDATE_VERTEX(face, vertex, index, diffuse_color) \ + { \ + VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \ + add_v3_v3(out->accum_color, diffuse_color); \ + out->tot_color++; \ + } (void)0 + + for (i = 0; i < totface; ++i) { + MFace *f = mface + face_indices[i]; + float diffuse_color[4]; + + GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color); + + UPDATE_VERTEX(i, f->v1, 0, diffuse_color); + UPDATE_VERTEX(i, f->v2, 1, diffuse_color); + UPDATE_VERTEX(i, f->v3, 2, diffuse_color); + if (f->v4) + UPDATE_VERTEX(i, f->v4, 3, diffuse_color); + } +#undef UPDATE_VERTEX + + for (i = 0; i < totvert; ++i) { + VertexBufferFormat *out = vert_data + i; + if (out->tot_color) { + float diffuse_color[4]; + + mul_v3_v3fl(diffuse_color, out->accum_color, 1.0f / out->tot_color); + + gpu_color_from_mask_copy(vmask[vert_indices[i]], diffuse_color, out->color); + } } glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -1517,6 +1555,10 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, for (i = 0; i < totgrid; ++i) { VertexBufferFormat *vd = vert_data; CCGElem *grid = grids[grid_indices[i]]; + const DMFlagMat *flags = &grid_flag_mats[grid_indices[i]]; + float diffuse_color[4]; + + GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color); for (y = 0; y < key->grid_size; y++) { for (x = 0; x < key->grid_size; x++) { @@ -1524,11 +1566,9 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, copy_v3_v3(vd->co, CCG_elem_co(key, elem)); if (smooth) { - normal_float_to_short_v3(vd->no, - CCG_elem_no(key, elem)); + normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem)); - gpu_color_from_mask_copy(*CCG_elem_mask(key, elem), - vd->color); + gpu_color_from_mask_copy(*CCG_elem_mask(key, elem), diffuse_color, vd->color); } vd++; } @@ -1561,6 +1601,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, elems[1], elems[2], elems[3], + diffuse_color, vd->color); } } @@ -1769,6 +1810,9 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) { const MVert *mvert = buffers->mvert; int i, j; + float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f}; + + glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_color); gpu_colors_enable(VBO_DISABLED); @@ -1784,7 +1828,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) if (smooth) { for (j = 0; j < S; j++) { - gpu_color_from_mask_set(buffers->vmask[fv[j]]); + gpu_color_from_mask_set(buffers->vmask[fv[j]], diffuse_color); glNormal3sv(mvert[fv[j]].no); glVertex3fv(mvert[fv[j]].co); } @@ -1809,7 +1853,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth) fmask = (fmask + buffers->vmask[fv[3]]) * 0.25; else fmask /= 3.0f; - gpu_color_from_mask_set(fmask); + gpu_color_from_mask_set(fmask, diffuse_color); for (j = 0; j < S; j++) glVertex3fv(mvert[fv[j]].co); @@ -1825,6 +1869,9 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) { const CCGKey *key = &buffers->gridkey; int i, j, x, y, gridsize = buffers->gridkey.grid_size; + float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f}; + + glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_color); gpu_colors_enable(VBO_DISABLED); @@ -1853,7 +1900,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) if (smooth) { for (j = 0; j < 4; j++) { - gpu_color_from_mask_set(*CCG_elem_mask(key, e[j])); + gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]), diffuse_color); glNormal3fv(CCG_elem_no(key, e[j])); glVertex3fv(CCG_elem_co(key, e[j])); } @@ -1866,7 +1913,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) CCG_elem_co(key, e[2]), CCG_elem_co(key, e[3])); glNormal3fv(fno); - gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3]); + gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3], diffuse_color); for (j = 0; j < 4; j++) glVertex3fv(CCG_elem_co(key, e[j])); @@ -1883,10 +1930,10 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) CCGElem *a = CCG_grid_elem(key, grid, x, y); CCGElem *b = CCG_grid_elem(key, grid, x, y + 1); - gpu_color_from_mask_set(*CCG_elem_mask(key, a)); + gpu_color_from_mask_set(*CCG_elem_mask(key, a), diffuse_color); glNormal3fv(CCG_elem_no(key, a)); glVertex3fv(CCG_elem_co(key, a)); - gpu_color_from_mask_set(*CCG_elem_mask(key, b)); + gpu_color_from_mask_set(*CCG_elem_mask(key, b), diffuse_color); glNormal3fv(CCG_elem_no(key, b)); glVertex3fv(CCG_elem_co(key, b)); } @@ -1912,7 +1959,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth) CCG_elem_co(key, c)); glNormal3fv(fno); - gpu_color_from_mask_quad_set(key, a, b, c, d); + gpu_color_from_mask_quad_set(key, a, b, c, d, diffuse_color); } glVertex3fv(CCG_elem_co(key, a)); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 4314a784511..60e3c19a419 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -492,7 +492,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int } /* TODO unneeded when float images are correctly treated as linear always */ - if (!ncd && ibuf->profile == IB_PROFILE_LINEAR_RGB) + if (!ncd) do_color_management = TRUE; if (ibuf->rect==NULL) @@ -535,7 +535,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int if (do_color_management) { srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor"); IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float, - ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0, + ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, 0, ibuf->x, ibuf->y, ibuf->x, ibuf->x); /* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */ IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y); @@ -560,7 +560,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int if (do_color_management) { frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor"); IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float, - ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0, + ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, 0, ibuf->x, ibuf->y, ibuf->x, ibuf->x); /* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */ IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y); @@ -709,7 +709,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int */ int GPU_upload_dxt_texture(ImBuf *ibuf) { -#if WITH_DDS +#ifdef WITH_DDS GLint format = 0; int blocksize, height, width, i, size, offset = 0; @@ -878,13 +878,13 @@ void GPU_paint_set_mipmap(int mipmap) } } -void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap) +void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) { ImBuf *ibuf; ibuf = BKE_image_get_ibuf(ima, NULL); - if (ima->repbind || (GPU_get_mipmap() && mipmap) || !ima->bindcode || !ibuf || + if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || !ima->bindcode || !ibuf || (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) || (w == 0) || (h == 0)) { @@ -901,7 +901,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap) glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows); /* if color correction is needed, we must update the part that needs updating. */ - if (ibuf->rect_float && (!U.use_16bit_textures || (ibuf->profile == IB_PROFILE_LINEAR_RGB))) { + if (ibuf->rect_float) { float *buffer = MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf"); IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h); @@ -911,8 +911,14 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap) MEM_freeN(buffer); - if (ima->tpageflag & IMA_MIPMAP_COMPLETE) + /* we have already accounted for the case where GTS.gpu_mipmap is false + * so we will be using GPU mipmap generation here */ + if (GPU_get_mipmap()) { + glGenerateMipmapEXT(GL_TEXTURE_2D); + } + else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; + } return; } @@ -934,8 +940,13 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap) glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels); glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows); - if (ima->tpageflag & IMA_MIPMAP_COMPLETE) + /* see comment above as to why we are using gpu mipmap generation here */ + if (GPU_get_mipmap()) { + glGenerateMipmapEXT(GL_TEXTURE_2D); + } + else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; + } } } @@ -1197,7 +1208,12 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GPUMaterial *gpumat; GPUBlendMode alphablend; int a; - int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; + + /* OCIO_TODO: assume color management is always enabled. could be nice to support real display transform here, + * but that's not so important and could be done later + */ + int gamma = TRUE; + int new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* initialize state */ @@ -1221,7 +1237,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O * - object transparency off: for glsl we draw both in a single pass, and * for solid we don't use transparency at all. */ GMS.use_alpha_pass = (do_alpha_after != NULL); - GMS.is_alpha_pass = (v3d && v3d->transp); + GMS.is_alpha_pass = (v3d->transp != FALSE); if (GMS.use_alpha_pass) *do_alpha_after = FALSE; @@ -1424,6 +1440,21 @@ void GPU_disable_material(void) GPU_set_material_alpha_blend(GPU_BLEND_SOLID); } +void GPU_material_diffuse_get(int nr, float diff[4]) +{ + /* prevent index to use un-initialized array items */ + if (nr >= GMS.totmat) + nr = 0; + + /* no GPU_begin_object_materials, use default material */ + if (!GMS.matbuf) { + mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit); + } + else { + copy_v4_v4(diff, GMS.matbuf[nr].diff); + } +} + void GPU_end_object_materials(void) { GPU_disable_material(); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 61be4057843..dd92b561235 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -389,8 +389,12 @@ void gpu_material_add_node(GPUMaterial *material, GPUNode *node) int GPU_material_do_color_management(GPUMaterial *mat) { - return ((mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) && - !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT))); + /* OCIO_TODO: for now assume scene always does color management. probably could be + * improved in the future to support real display transform + * also probably we'll need to get rid ofgame engine's color management flag + */ + + return !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT)); } static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist) |