2018-04-18 13:44:33 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright 2016, Blender Foundation.
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Blender Institute
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** \file workbench_materials.c
|
|
|
|
|
* \ingroup draw_engine
|
|
|
|
|
*/
|
2018-04-19 07:47:03 +02:00
|
|
|
|
2018-04-18 13:44:33 +02:00
|
|
|
#include "workbench_private.h"
|
|
|
|
|
#include "GPU_shader.h"
|
|
|
|
|
|
|
|
|
|
/* *********** STATIC *********** */
|
|
|
|
|
static struct {
|
|
|
|
|
struct GPUShader *depth_sh;
|
|
|
|
|
|
|
|
|
|
/* Solid flat mode */
|
|
|
|
|
struct GPUShader *solid_flat_sh;
|
2018-04-19 07:47:03 +02:00
|
|
|
|
2018-04-18 13:44:33 +02:00
|
|
|
/* Solid studio mode */
|
|
|
|
|
struct GPUShader *solid_studio_sh;
|
|
|
|
|
|
|
|
|
|
} e_data = {NULL};
|
|
|
|
|
|
|
|
|
|
/* Shaders */
|
|
|
|
|
extern char datatoc_solid_flat_frag_glsl[];
|
|
|
|
|
extern char datatoc_solid_studio_frag_glsl[];
|
|
|
|
|
extern char datatoc_workbench_vert_glsl[];
|
|
|
|
|
extern char datatoc_workbench_studio_vert_glsl[];
|
|
|
|
|
extern char datatoc_workbench_diffuse_lib_glsl[];
|
|
|
|
|
|
|
|
|
|
/* Functions */
|
2018-04-19 07:47:03 +02:00
|
|
|
static uint get_material_hash(const float color[3])
|
|
|
|
|
{
|
2018-04-18 13:44:33 +02:00
|
|
|
uint r = (uint)(color[0] * 512);
|
|
|
|
|
uint g = (uint)(color[1] * 512);
|
|
|
|
|
uint b = (uint)(color[2] * 512);
|
2018-04-19 07:47:03 +02:00
|
|
|
|
2018-04-18 15:16:21 +02:00
|
|
|
return r + g * 4096 + b * 4096 * 4096;
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-20 14:38:55 +02:00
|
|
|
static void get_material_solid_color(WORKBENCH_PrivateData *wpd, Object *ob, float *color)
|
2018-04-19 07:47:03 +02:00
|
|
|
{
|
2018-04-20 14:38:55 +02:00
|
|
|
if (wpd->drawtype_options & V3D_DRAWOPTION_RANDOMIZE) {
|
|
|
|
|
unsigned int obhash = BLI_ghashutil_strhash(ob->id.name);
|
|
|
|
|
cpack_to_rgb(obhash, &color[0], &color[1], &color[2]);
|
|
|
|
|
|
2018-04-21 20:42:27 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-04-20 14:38:55 +02:00
|
|
|
copy_v3_v3(color, ob->col);
|
|
|
|
|
}
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-19 07:47:03 +02:00
|
|
|
void workbench_materials_engine_init(void)
|
|
|
|
|
{
|
2018-04-18 13:44:33 +02:00
|
|
|
if (!e_data.depth_sh) {
|
|
|
|
|
/* Depth pass */
|
|
|
|
|
e_data.depth_sh = DRW_shader_create_3D_depth_only();
|
|
|
|
|
|
|
|
|
|
/* Solid flat */
|
|
|
|
|
e_data.solid_flat_sh = DRW_shader_create(datatoc_workbench_vert_glsl, NULL, datatoc_solid_flat_frag_glsl, "\n");
|
|
|
|
|
e_data.solid_studio_sh = DRW_shader_create(datatoc_workbench_studio_vert_glsl, NULL, datatoc_solid_studio_frag_glsl, datatoc_workbench_diffuse_lib_glsl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-19 10:41:24 +02:00
|
|
|
void workbench_materials_engine_free()
|
2018-04-19 07:47:03 +02:00
|
|
|
{
|
2018-04-18 13:44:33 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.solid_flat_sh);
|
|
|
|
|
DRW_SHADER_FREE_SAFE(e_data.solid_studio_sh);
|
2018-04-19 10:41:24 +02:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void workbench_materials_draw_scene_finish(WORKBENCH_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
WORKBENCH_StorageList *stl = vedata->stl;
|
|
|
|
|
WORKBENCH_PrivateData *wpd = stl->g_data;
|
|
|
|
|
|
|
|
|
|
BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-19 10:41:24 +02:00
|
|
|
|
2018-04-19 07:47:03 +02:00
|
|
|
void workbench_materials_cache_init(WORKBENCH_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
WORKBENCH_StorageList *stl = vedata->stl;
|
|
|
|
|
WORKBENCH_PassList *psl = vedata->psl;
|
|
|
|
|
WORKBENCH_PrivateData *wpd = stl->g_data;
|
|
|
|
|
|
2018-04-19 12:44:37 +02:00
|
|
|
const DRWContextState *DCS = DRW_context_state_get();
|
|
|
|
|
|
2018-04-18 13:44:33 +02:00
|
|
|
wpd->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
|
|
|
|
|
wpd->material_hash = BLI_ghash_ptr_new("Workbench material_hash");
|
2018-04-19 12:44:37 +02:00
|
|
|
|
|
|
|
|
View3D *v3d = DCS->v3d;
|
|
|
|
|
if (v3d) {
|
|
|
|
|
#if 0
|
|
|
|
|
/* TODO: switch implementation when OB_TEXTURE is implemented */
|
|
|
|
|
switch (v3d->drawtype) {
|
|
|
|
|
default:
|
|
|
|
|
case OB_SOLID:
|
2018-04-20 13:40:18 +02:00
|
|
|
wpd->drawtype_lighting = v3d->drawtype_lighting;
|
2018-04-19 12:44:37 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#else
|
2018-04-20 13:40:18 +02:00
|
|
|
wpd->drawtype_lighting = v3d->drawtype_lighting;
|
2018-04-20 14:38:55 +02:00
|
|
|
wpd->drawtype_options = v3d->drawtype_options;
|
2018-04-19 12:44:37 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
wpd->drawtype_lighting = V3D_LIGHTING_STUDIO;
|
2018-04-20 14:38:55 +02:00
|
|
|
wpd->drawtype_options = 0;
|
2018-04-19 12:44:37 +02:00
|
|
|
}
|
2018-04-18 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-19 12:44:37 +02:00
|
|
|
void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
2018-04-19 09:45:52 +02:00
|
|
|
{
|
|
|
|
|
WORKBENCH_StorageList *stl = vedata->stl;
|
|
|
|
|
WORKBENCH_PassList *psl = vedata->psl;
|
|
|
|
|
WORKBENCH_PrivateData *wpd = stl->g_data;
|
|
|
|
|
|
|
|
|
|
if (!DRW_object_is_renderable(ob))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
|
|
|
|
|
WORKBENCH_MaterialData *material;
|
|
|
|
|
if (geom) {
|
|
|
|
|
/* Depth */
|
|
|
|
|
DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
|
|
|
|
|
|
|
|
|
|
/* Solid */
|
2018-04-21 20:42:27 +02:00
|
|
|
GPUShader *shader = wpd->drawtype_lighting == V3D_LIGHTING_FLAT ? e_data.solid_flat_sh : e_data.solid_studio_sh;
|
2018-04-19 09:45:52 +02:00
|
|
|
|
2018-04-20 14:38:55 +02:00
|
|
|
float color[3];
|
|
|
|
|
get_material_solid_color(wpd, ob, color);
|
|
|
|
|
unsigned int hash = get_material_hash(color);
|
2018-04-19 09:45:52 +02:00
|
|
|
|
|
|
|
|
material = BLI_ghash_lookup(wpd->material_hash, SET_UINT_IN_POINTER(hash));
|
|
|
|
|
if (material == NULL) {
|
|
|
|
|
material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), "WORKBENCH_MaterialData");
|
|
|
|
|
material->shgrp = DRW_shgroup_create(shader, psl->solid_pass);
|
2018-04-19 10:41:24 +02:00
|
|
|
copy_v3_v3(material->color, color);
|
2018-04-19 09:45:52 +02:00
|
|
|
DRW_shgroup_uniform_vec3(material->shgrp, "color", material->color, 1);
|
|
|
|
|
BLI_ghash_insert(wpd->material_hash, SET_UINT_IN_POINTER(hash), material);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DRW_shgroup_call_add(material->shgrp, geom, ob->obmat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|