Cycles: don't use glsl in textured draw mode, to keep things simpler and faster

there for now. Also add viewport color setting for materials for solid draw mode.
This commit is contained in:
Brecht Van Lommel 2011-10-12 15:48:26 +00:00
parent 9ec1114765
commit c3c44f8736
10 changed files with 45 additions and 146 deletions

@ -463,8 +463,7 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
return False
#return context.material and CyclesButtonsPanel.poll(context)
return context.material and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
@ -472,6 +471,9 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
mat = context.material
cmat = mat.cycles
layout.prop(mat, "diffuse_color", text="Viewport Color")
"""
split = layout.split()
col = split.column()
@ -479,6 +481,7 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col = split.column()
col.prop(cmat, "homogeneous_volume")
"""
class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
bl_label = ""

@ -2156,8 +2156,15 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
if(ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
if(v3d->drawtype == OB_MATERIAL || scene->gm.matmode == GAME_MAT_GLSL)
mask |= CD_MASK_ORCO;
if(scene_use_new_shading_nodes(scene)) {
/* todo: use orco in textured draw mode */
if(v3d->drawtype == OB_MATERIAL)
mask |= CD_MASK_ORCO;
}
else {
if(scene->gm.matmode == GAME_MAT_GLSL)
mask |= CD_MASK_ORCO;
}
}
return mask;

@ -121,13 +121,12 @@ int GPU_link(GPUMaterial *mat, const char *name, ...);
int GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...);
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
int GPU_material_drawtype(GPUMaterial *material);
void GPU_material_enable_alpha(GPUMaterial *material);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, int drawtype);
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma);
void GPU_material_free(struct Material *ma);
void GPU_materials_free(void);

@ -64,7 +64,7 @@
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BLI_threads.h"
#include "BLI_blenlib.h"
@ -941,7 +941,6 @@ static struct GPUMaterialState {
Material *gboundmat;
Object *gob;
Scene *gscene;
int gdrawtype;
int glay;
float (*gviewmat)[4];
float (*gviewinv)[4];
@ -955,15 +954,17 @@ static struct GPUMaterialState {
} GMS = {NULL};
/* fixed function material, alpha handed by caller */
static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob)
static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes)
{
if (bmat->mode & MA_SHLESS) {
if(new_shading_nodes || bmat->mode & MA_SHLESS) {
copy_v3_v3(smat->diff, &bmat->r);
smat->diff[3]= 1.0;
if(gamma) {
if(gamma)
linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
}
zero_v4(smat->spec);
smat->hard= 0;
}
else {
mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit);
@ -1004,6 +1005,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GPUBlendMode alphablend;
int a;
int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
int new_shading_nodes = scene_use_new_shading_nodes(scene);
/* initialize state */
memset(&GMS, 0, sizeof(GMS));
@ -1013,7 +1015,6 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.gob = ob;
GMS.gscene = scene;
GMS.gdrawtype = v3d->drawtype;
GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
GMS.glay= v3d->lay;
GMS.gviewmat= rv3d->viewmat;
@ -1036,14 +1037,14 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* no materials assigned? */
if(ob->totcol==0) {
gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob);
gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
if(glsl) {
GMS.gmatbuf[0]= &defmaterial;
GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.gdrawtype);
GPU_material_from_blender(GMS.gscene, &defmaterial);
}
GMS.alphablend[0]= GPU_BLEND_SOLID;
@ -1053,11 +1054,11 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
for(a=1; a<=ob->totcol; a++) {
/* find a suitable material */
ma= give_current_material(ob, a);
if(!glsl) ma= gpu_active_node_material(ma);
if(!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma);
if(ma==NULL) ma= &defmaterial;
/* create glsl material if requested */
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma, GMS.gdrawtype): NULL;
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
if(gpumat) {
/* do glsl only if creating it succeed, else fallback */
@ -1066,7 +1067,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
}
else {
/* fixed function opengl materials */
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob);
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
if(do_alpha_pass && GMS.alphapass)
@ -1127,7 +1128,7 @@ int GPU_enable_material(int nr, void *attribs)
/* unbind glsl material */
if(GMS.gboundmat) {
if(GMS.alphapass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.gdrawtype));
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
GMS.gboundmat= NULL;
}
@ -1145,7 +1146,7 @@ int GPU_enable_material(int nr, void *attribs)
/* bind glsl material and get attributes */
Material *mat = GMS.gmatbuf[nr];
gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.gdrawtype);
gpumat = GPU_material_from_blender(GMS.gscene, mat);
GPU_material_vertex_attributes(gpumat, gattribs);
GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT));
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col);
@ -1193,7 +1194,7 @@ void GPU_disable_material(void)
if(GMS.gboundmat) {
if(GMS.alphapass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.gdrawtype));
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
GMS.gboundmat= NULL;
}

@ -80,7 +80,6 @@ typedef enum DynMatProperty {
struct GPUMaterial {
Scene *scene;
Material *ma;
int drawtype;
/* for creating the material */
ListBase nodes;
@ -354,11 +353,6 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
material->outlink= link;
}
int GPU_material_drawtype(GPUMaterial *material)
{
return material->drawtype;
}
void GPU_material_enable_alpha(GPUMaterial *material)
{
material->alpha= 1;
@ -1413,27 +1407,19 @@ static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
return shr.combined;
}
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, int drawtype)
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
{
GPUMaterial *mat;
GPUNodeLink *outlink;
LinkData *link;
/* find an existing glsl shader that is already compiled */
for(link=ma->gpumaterial.first; link; link=link->next) {
mat= (GPUMaterial*)link->data;
if(mat->scene == scene && mat->drawtype == drawtype)
for(link=ma->gpumaterial.first; link; link=link->next)
if(((GPUMaterial*)link->data)->scene == scene)
return link->data;
}
/* in texture draw mode, we need an active texture node */
if(drawtype == OB_TEXTURE && (!ma->use_nodes || !nodeGetActiveTexture(ma->nodetree)))
return NULL;
/* allocate material */
mat = GPU_material_construct_begin(ma);
mat->scene = scene;
mat->drawtype = drawtype;
if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
/* create nodes */
@ -1443,12 +1429,15 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, int drawtype)
/* create material */
outlink = GPU_blender_material(mat, ma);
GPU_material_output_link(mat, outlink);
}
if(!scene_use_new_shading_nodes(scene)) {
if(gpu_do_color_management(mat))
if(mat->outlink)
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
}
GPU_material_construct_end(mat);
/* note that even if building the shader fails in some way, we still keep
@ -1730,7 +1719,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
if(!GPU_glsl_support())
return NULL;
mat = GPU_material_from_blender(scene, ma, OB_TEXTURE);
mat = GPU_material_from_blender(scene, ma);
pass = (mat)? mat->pass: NULL;
if(pass && pass->fragmentcode && pass->vertexcode) {

@ -123,14 +123,10 @@ bNodeTreeType ntreeType_Shader = {
void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
{
bNodeTreeExec *exec;
bNode *tex_node = NULL;
if(GPU_material_drawtype(mat) == OB_TEXTURE)
tex_node= nodeGetActiveTexture(ntree);
exec = ntreeShaderBeginExecTree(ntree, 1);
ntreeExecGPUNodes(exec, tex_node, mat, 1);
ntreeExecGPUNodes(exec, mat, 1);
ntreeShaderEndExecTree(exec, 1);
}

@ -267,29 +267,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
return NULL;
}
static void ntreeGPUOutputLink(GPUMaterial *mat, bNode *node, bNodeStack *nsout[MAX_SOCKET])
{
bNodeSocket *sock;
int i;
/* link the first socket output as the material output, for viewing
individual textures in texture draw mode */
for(sock=node->outputs.first, i=0; sock; sock=sock->next, i++) {
if(nsout[i]->data) {
GPUNodeLink *result= nsout[i]->data;
/* for shader sockets, we can output the color directly, for others we
apply diffuse shading so we don't have flat colors */
if(sock->type != SOCK_SHADER)
GPU_link(mat, "node_bsdf_diffuse", result, GPU_builtin(GPU_VIEW_NORMAL), &result);
GPU_material_output_link(mat, result);
break;
}
}
}
void ntreeExecGPUNodes(bNodeTreeExec *exec, bNode *tex_node, GPUMaterial *mat, int do_outputs)
void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs)
{
bNodeExec *nodeexec;
bNode *node;
@ -319,90 +297,16 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, bNode *tex_node, GPUMaterial *mat, i
node_get_stack(node, stack, nsin, nsout);
gpu_stack_from_data_list(gpuin, &node->inputs, nsin);
gpu_stack_from_data_list(gpuout, &node->outputs, nsout);
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) {
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
data_from_gpu_stack_list(&node->outputs, nsout, gpuout);
/* for textured draw, output active node */
if(node == tex_node)
ntreeGPUOutputLink(mat, node, nsout);
}
}
else if(node->typeinfo->gpuextfunc) {
node_get_stack(node, stack, nsin, nsout);
gpu_stack_from_data_list(gpuin, &node->inputs, nsin);
gpu_stack_from_data_list(gpuout, &node->outputs, nsout);
if(node->typeinfo->gpuextfunc(mat, node, nodeexec->data, gpuin, gpuout)) {
if(node->typeinfo->gpuextfunc(mat, node, nodeexec->data, gpuin, gpuout))
data_from_gpu_stack_list(&node->outputs, nsout, gpuout);
/* for textured draw, output active node */
if(node == tex_node)
ntreeGPUOutputLink(mat, node, nsout);
}
}
}
}
#if 0
if((ntree->init & NTREE_EXEC_INIT)==0)
ntreeBeginExecTree(ntree);
stack= ntree->stack;
for(node= ntree->nodes.first; node; node= node->next) {
if(node->typeinfo->gpufunc) {
node_get_stack(node, stack, nsin, nsout, NULL);
gpu_from_node_stack(&node->inputs, nsin, gpuin);
gpu_from_node_stack(&node->outputs, nsout, gpuout);
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) {
data_from_gpu_stack(&node->outputs, nsout, gpuout);
/* for textured draw, output active node */
if(node == tex_node)
ntreeGPUOutputLink(mat, node, nsout);
}
}
else if(node->type==NODE_GROUP && node->id) {
node_get_stack(node, stack, nsin, nsout, NULL);
gpu_node_group_execute(stack, mat, node, nsin);
}
bNode *node, *tex_node;
bNodeStack *stack;
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
if(GPU_material_drawtype(mat) == OB_TEXTURE)
tex_node= nodeGetActiveTexture(ntree);
else
tex_node= NULL;
if((ntree->init & NTREE_EXEC_INIT)==0)
ntreeBeginExecTree(ntree);
stack= ntree->stack;
for(node= ntree->nodes.first; node; node= node->next) {
if(node->typeinfo->gpufunc) {
node_get_stack(node, stack, nsin, nsout, NULL);
gpu_from_node_stack(&node->inputs, nsin, gpuin);
gpu_from_node_stack(&node->outputs, nsout, gpuout);
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) {
data_from_gpu_stack(&node->outputs, nsout, gpuout);
/* for textured draw, output active node */
if(node == tex_node)
ntreeGPUOutputLink(mat, node, nsout);
}
}
else if(node->type==NODE_GROUP && node->id) {
node_get_stack(node, stack, nsin, nsout, NULL);
gpu_node_group_execute(stack, mat, node, nsin);
}
#endif
}

@ -131,6 +131,6 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns);
void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, struct bNodeStack *ns);
void node_data_from_gpu_stack(struct bNodeStack *ns, struct GPUNodeStack *gs);
void ntreeExecGPUNodes(struct bNodeTreeExec *exec, struct bNode *tex_node, struct GPUMaterial *mat, int do_outputs);
void ntreeExecGPUNodes(struct bNodeTreeExec *exec, struct GPUMaterial *mat, int do_outputs);
#endif

@ -41,7 +41,7 @@ BL_BlenderShader::~BL_BlenderShader()
void BL_BlenderShader::ReloadMaterial()
{
mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat, OB_RENDER) : NULL;
mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
}
void BL_BlenderShader::SetProg(bool enable, double time)

@ -887,7 +887,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
Material* blmat = current_polymat->GetBlenderMaterial();
Scene* blscene = current_polymat->GetBlenderScene();
if (!wireframe && blscene && blmat)
GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat, OB_RENDER), &current_gpu_attribs);
GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
else
memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
// DM draw can mess up blending mode, restore at the end