Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_codegen.c
| Context not available. | |||||
| else if (input->ima || input->prv) | else if (input->ima || input->prv) | ||||
| return 1; | return 1; | ||||
| else | else | ||||
| return input->tex != NULL; | return (input->tex != NULL || input->texptr != NULL); | ||||
| } | } | ||||
| const char *GPU_builtin_name(GPUBuiltin builtin) | const char *GPU_builtin_name(GPUBuiltin builtin) | ||||
| Context not available. | |||||
| return "unfparticlevel"; | return "unfparticlevel"; | ||||
| else if (builtin == GPU_PARTICLE_ANG_VELOCITY) | else if (builtin == GPU_PARTICLE_ANG_VELOCITY) | ||||
| return "unfparticleangvel"; | return "unfparticleangvel"; | ||||
| else if (builtin == GPU_INSTANCING_MATRIX) | |||||
| return "varinstmat"; | |||||
| else if (builtin == GPU_INSTANCING_INVERSE_MATRIX) | |||||
| return "varinstinvmat"; | |||||
| else if (builtin == GPU_INSTANCING_LOC_TO_VIEW_MATRIX) | |||||
| return "varinstlocaltoviewmat"; | |||||
| else if (builtin == GPU_INSTANCING_INVERSE_LOC_TO_VIEW_MATRIX) | |||||
| return "varinstinvlocaltoviewmat"; | |||||
| else if (builtin == GPU_INSTANCING_COLOR) | |||||
| return "varinstcolor"; | |||||
| else if (builtin == GPU_INSTANCING_COLOR_ATTRIB) | |||||
| return "ininstcolor"; | |||||
| else if (builtin == GPU_INSTANCING_MATRIX_ATTRIB) | |||||
| return "ininstmatrix"; | |||||
| else if (builtin == GPU_INSTANCING_POSITION_ATTRIB) | |||||
| return "ininstposition"; | |||||
| else | else | ||||
| return ""; | return ""; | ||||
| } | } | ||||
| Context not available. | |||||
| /* input is user created texture, check tex pointer */ | /* input is user created texture, check tex pointer */ | ||||
| codegen_set_texid(bindhash, input, &texid, input->tex); | codegen_set_texid(bindhash, input, &texid, input->tex); | ||||
| } | } | ||||
| else if (input->texptr) { | |||||
| /* input is user created texture, check tex pointer */ | |||||
| codegen_set_texid(bindhash, input, &texid, input->texptr); | |||||
| } | |||||
| /* make sure this pixel is defined exactly once */ | /* make sure this pixel is defined exactly once */ | ||||
| if (input->source == GPU_SOURCE_TEX_PIXEL) { | if (input->source == GPU_SOURCE_TEX_PIXEL) { | ||||
| Context not available. | |||||
| return code; | return code; | ||||
| } | } | ||||
| static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) | static char *code_generate_vertex(ListBase *nodes, const GPUMatType type, bool use_instancing) | ||||
| { | { | ||||
| DynStr *ds = BLI_dynstr_new(); | DynStr *ds = BLI_dynstr_new(); | ||||
| GPUNode *node; | GPUNode *node; | ||||
| Context not available. | |||||
| #ifdef WITH_OPENSUBDIV | #ifdef WITH_OPENSUBDIV | ||||
| BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); | BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); | ||||
| #endif | #endif | ||||
| BLI_dynstr_appendf( | if (use_instancing) { | ||||
| ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n", | BLI_dynstr_appendf( | ||||
| input->attribid, input->attribid); | ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * (att%d.xyz * %s));\n", | ||||
| input->attribid, input->attribid, GPU_builtin_name(GPU_INSTANCING_MATRIX_ATTRIB)); | |||||
| } | |||||
| else { | |||||
| BLI_dynstr_appendf( | |||||
| ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n", | |||||
| input->attribid, input->attribid); | |||||
| } | |||||
| BLI_dynstr_appendf( | BLI_dynstr_appendf( | ||||
| ds, "\tvar%d.w = att%d.w;\n", | ds, "\tvar%d.w = att%d.w;\n", | ||||
| input->attribid, input->attribid); | input->attribid, input->attribid); | ||||
| Context not available. | |||||
| continue; | continue; | ||||
| } | } | ||||
| if (input->ima || input->tex || input->prv) | if (input->ima || input->tex || input->prv || input->texptr) { | ||||
| BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid); | BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid); | ||||
| } | |||||
| else | else | ||||
| BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id); | BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id); | ||||
| /* pass non-dynamic uniforms to opengl */ | /* pass non-dynamic uniforms to opengl */ | ||||
| extract = 0; | extract = 0; | ||||
| if (input->ima || input->tex || input->prv) { | if (input->ima || input->tex || input->prv || input->texptr) { | ||||
| if (input->bindtex) | if (input->bindtex) | ||||
| extract = 1; | extract = 1; | ||||
| } | } | ||||
| Context not available. | |||||
| GPU_texture_bind(input->tex, input->texid); | GPU_texture_bind(input->tex, input->texid); | ||||
| GPU_shader_uniform_texture(shader, input->shaderloc, input->tex); | GPU_shader_uniform_texture(shader, input->shaderloc, input->tex); | ||||
| } | } | ||||
| else if (input->texptr && *input->texptr && input->bindtex) { | |||||
| GPU_texture_bind(*input->texptr, input->texid); | |||||
| GPU_shader_uniform_texture(shader, input->shaderloc, *input->texptr); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| /* pass dynamic inputs to opengl, others were removed */ | /* pass dynamic inputs to opengl, others were removed */ | ||||
| for (input = inputs->first; input; input = input->next) { | for (input = inputs->first; input; input = input->next) { | ||||
| if (!(input->ima || input->tex || input->prv)) { | if (!(input->ima || input->tex || input->prv || input->texptr)) { | ||||
| if (input->dynamictype == GPU_DYNAMIC_MAT_HARD) { | GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1, | ||||
| // The hardness is actually a short pointer, so we convert it here | input->dynamicvec); | ||||
| float val = (float)(*(short *)input->dynamicvec); | |||||
| GPU_shader_uniform_vector(shader, input->shaderloc, 1, 1, &val); | |||||
| } | |||||
| else { | |||||
| GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1, | |||||
| input->dynamicvec); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| for (input = inputs->first; input; input = input->next) { | for (input = inputs->first; input; input = input->next) { | ||||
| if (input->tex && input->bindtex) | if (input->tex && input->bindtex) | ||||
| GPU_texture_unbind(input->tex); | GPU_texture_unbind(input->tex); | ||||
| if (input->texptr && *input->texptr && input->bindtex) { | |||||
| GPU_texture_unbind(*input->texptr); | |||||
| } | |||||
| if (input->ima || input->prv) | if (input->ima || input->prv) | ||||
| input->tex = NULL; | input->tex = NULL; | ||||
| Context not available. | |||||
| input->dynamicdata = link->ptr2; | input->dynamicdata = link->ptr2; | ||||
| MEM_freeN(link); | MEM_freeN(link); | ||||
| } | } | ||||
| else if (link->dynamictexptr) { | |||||
| /* dynamic texture, GPUTexture is updated/deleted externally */ | |||||
| input->type = type; | |||||
| input->source = GPU_SOURCE_TEX; | |||||
| input->texptr = link->dynamictexptr; | |||||
| input->textarget = GL_TEXTURE_2D; | |||||
| input->textype = type; | |||||
| input->dynamictex = true; | |||||
| input->dynamicdata = link->ptr2; | |||||
| MEM_freeN(link); | |||||
| } | |||||
| else if (link->texture) { | else if (link->texture) { | ||||
| /* small texture created on the fly, like for colorbands */ | /* small texture created on the fly, like for colorbands */ | ||||
| input->type = GPU_VEC4; | input->type = GPU_VEC4; | ||||
| Context not available. | |||||
| return link; | return link; | ||||
| } | } | ||||
| GPUNodeLink *GPU_select_uniform(float *num, GPUDynamicType dynamictype, void *data, Material *material) | |||||
| { | |||||
| bool dynamic = false; | |||||
| if (GPU_DYNAMIC_GROUP_FROM_TYPE(dynamictype) == GPU_DYNAMIC_GROUP_MAT) { | |||||
| dynamic = !(material->constflag & MA_CONSTANT_MATERIAL); | |||||
| } | |||||
| else if (GPU_DYNAMIC_GROUP_FROM_TYPE(dynamictype) == GPU_DYNAMIC_GROUP_LAMP) { | |||||
| dynamic = !(material->constflag & MA_CONSTANT_LAMP); | |||||
| } | |||||
| else if (GPU_DYNAMIC_GROUP_FROM_TYPE(dynamictype) == GPU_DYNAMIC_GROUP_TEX) { | |||||
| dynamic = !(material->constflag & MA_CONSTANT_TEXTURE); | |||||
| } | |||||
| else if (GPU_DYNAMIC_GROUP_FROM_TYPE(dynamictype) == GPU_DYNAMIC_GROUP_TEX_UV) { | |||||
| dynamic = !(material->constflag & MA_CONSTANT_TEXTURE_UV); | |||||
| } | |||||
| else if (GPU_DYNAMIC_GROUP_FROM_TYPE(dynamictype) == GPU_DYNAMIC_GROUP_WORLD) { | |||||
| dynamic = !(material->constflag & MA_CONSTANT_WORLD); | |||||
| } | |||||
| else if (GPU_DYNAMIC_GROUP_FROM_TYPE(dynamictype) == GPU_DYNAMIC_GROUP_MIST) { | |||||
| dynamic = !(material->constflag & MA_CONSTANT_MIST); | |||||
| } | |||||
| if (dynamic) { | |||||
| return GPU_dynamic_uniform(num, dynamictype, data); | |||||
| } | |||||
| else { | |||||
| return GPU_uniform(num); | |||||
| } | |||||
| } | |||||
| GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data) | GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data) | ||||
| { | { | ||||
| GPUNodeLink *link = GPU_node_link_create(); | GPUNodeLink *link = GPU_node_link_create(); | ||||
| Context not available. | |||||
| return link; | return link; | ||||
| } | } | ||||
| GPUNodeLink *GPU_dynamic_texture_ptr(GPUTexture **tex, GPUDynamicType dynamictype, void *data) | |||||
| { | |||||
| GPUNodeLink *link = GPU_node_link_create(); | |||||
| link->dynamic = true; | |||||
| link->dynamictexptr = tex; | |||||
| link->dynamictype = dynamictype; | |||||
| link->ptr2 = data; | |||||
| return link; | |||||
| } | |||||
| GPUNodeLink *GPU_builtin(GPUBuiltin builtin) | GPUNodeLink *GPU_builtin(GPUBuiltin builtin) | ||||
| { | { | ||||
| GPUNodeLink *link = GPU_node_link_create(); | GPUNodeLink *link = GPU_node_link_create(); | ||||
| Context not available. | |||||
| GPUVertexAttribs *attribs, int *builtins, | GPUVertexAttribs *attribs, int *builtins, | ||||
| const GPUMatType type, const char *UNUSED(name), | const GPUMatType type, const char *UNUSED(name), | ||||
| const bool use_opensubdiv, | const bool use_opensubdiv, | ||||
| const bool use_instancing, | |||||
| const bool use_new_shading) | const bool use_new_shading) | ||||
| { | { | ||||
| GPUShader *shader; | GPUShader *shader; | ||||
| Context not available. | |||||
| /* generate code and compile with opengl */ | /* generate code and compile with opengl */ | ||||
| fragmentcode = code_generate_fragment(nodes, outlink->output); | fragmentcode = code_generate_fragment(nodes, outlink->output); | ||||
| vertexcode = code_generate_vertex(nodes, type); | vertexcode = code_generate_vertex(nodes, type, use_instancing); | ||||
| geometrycode = code_generate_geometry(nodes, use_opensubdiv); | geometrycode = code_generate_geometry(nodes, use_opensubdiv); | ||||
| int flags = GPU_SHADER_FLAGS_NONE; | int flags = GPU_SHADER_FLAGS_NONE; | ||||
| Context not available. | |||||
| if (use_new_shading) { | if (use_new_shading) { | ||||
| flags |= GPU_SHADER_FLAGS_NEW_SHADING; | flags |= GPU_SHADER_FLAGS_NEW_SHADING; | ||||
| } | } | ||||
| if (use_instancing) { | |||||
| flags |= GPU_SHADER_FLAGS_SPECIAL_INSTANCING; | |||||
| } | |||||
| shader = GPU_shader_create_ex(vertexcode, | shader = GPU_shader_create_ex(vertexcode, | ||||
| fragmentcode, | fragmentcode, | ||||
| geometrycode, | geometrycode, | ||||
| Context not available. | |||||