<div dir="ltr"><div>Hi Brecht,<br></div><div class="gmail_extra"><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
</span>That&#39;s kind of what I&#39;m proposing :).<br>
<br>
But the design is different than yours. The funky shader example is a<br>
use case specific shader interface.<br>
<br>
* funky_shader_new() would compile the shader with GPU_shader_create()<br>
* funky_material_params_finalize() would set uniforms with functions<br>
like GPU_shader_uniform_vector()<br>
<span class=""><br></span></blockquote><div>That&#39;s fine. Any design goes that doesn&#39;t requires us to re-query the uniform locations every time after binding a shader<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
<br>
&gt; LightParams *lp = interface-&gt;getLightParams();<br>
&gt;<br>
&gt; lp-&gt;light_pos = pos;<br>
<br>
</span>What I&#39;m missing here is the ability to reuse a set of shader<br>
parameters. Consider for example the current GLSL node materials, if<br>
you have multiple materials on an object then their shaders could<br>
share the same per object GPUShaderParameters.<br>
<br>
The other thing is that GPUShaderParams would be immutable once<br>
created, so that per object GPUShaderParameters could be uploaded to<br>
the GPU once and cached. With your interface the bind() call is<br>
required to re-upload the data every time? I would like the parameters<br>
to be validated and ready before that.<br></blockquote><div><br></div><div>Every time the relevant data changes. Light position was a bad example of that, let&#39;s say transform is a better example here. I don&#39;t think we need data to be immutable on the GPU, just cached.<br></div><div>Keep in mind that when rebinding a shader, we are required to rebind all the uniform state. This is not as bad with uniform buffer objects but for GL 2.1 it makes sense to have a way to bind all data.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=""><br>
&gt; GPUAttribute *p = interface-&gt;getPositionAttribute();<br>
&gt;<br>
&gt; GPU_bind_vertex_buffer(p, offset, stride, etc...);<br>
<br>
</span>I think we need a way to have both different types of meshes (cddm,<br>
subsurf, metaballs, ..) and different types of shaders (GLSL, solid<br>
lighting, matcaps, ..) working together.<br>
<br></blockquote><div>For different type of meshes, the ongoing derivedmesh refactor that I started this summer aims at that.<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
So we need a general mechanism, where for all types of shaders you can<br>
get the required attributes, for which I proposed using<br>
GPUShaderVertexAttribs. It&#39;s not really clear to me if in this example<br>
getPositionAttribute() is a function specific to one shader type or<br>
available for all shader types?<br>
<span class=""><br></span></blockquote><div><br></div><div>Yes GPUShaderVertexAttribs is perfect for that. The idea is that the shader requests vertex buffers with customdata, the derivedmesh fills those buffers (or sets the attribute to a reasonable constant value if they are missing)<br><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
&gt; /* bind shader */<br>
&gt; shader-&gt;bind();<br>
&gt;<br>
&gt; /* sets attributes appropriately and effectively */<br>
&gt; interface-&gt;bind();<br>
&gt;<br>
&gt; /* draw */<br>
&gt; GPUdraw(numeElements, drawType)<br>
<br>
</span>I&#39;m specifically trying to avoid binding and state, to avoid state<br>
accidentally leaking, or having to deal with verbose and error prone<br>
unbinding and unsetting of state. If there is only a small amount of<br>
state then it&#39;s not as bad, I just prefer to pass it explicitly to the<br>
draw function.<br>
<br></blockquote><div>Fair enough <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
I can see that with my proposal it&#39;s not as clear which parameters and<br>
attributes you need to pass. Having a data structure that has both a<br>
pointer to the GPUShader and a set of GPUShaderParams would be simpler<br>
to use. The funky shader example API could be like this:<br>
<br>
GPUShaderParams *funky_light_params(FunkyLight light[], int num_lights);<br>
GPUShaderInstance *funky_shader_instance(FunkMaterialParams *funky,<br>
GPUShaderParams *shared_light_params);<br>
<br>
And then you pass only that GPUShaderInstance* to the draw function.<br>
<br></blockquote><div><br></div><div>It&#39;s clearer, though again I don&#39;t know if we can really enforce parameters to be constant (as discussed above). This is where a more fine-grained approach is better, even though it&#39;s more error prone as you said.<br></div></div></div></div>