Revision: 44825
          http://brlcad.svn.sourceforge.net/brlcad/?rev=44825&view=rev
Author:   kunigami
Date:     2011-06-08 18:51:38 +0000 (Wed, 08 Jun 2011)

Log Message:
-----------
Added support for OSL closure color query. It's crashing though. Maybe due to a 
memory leak

Modified Paths:
--------------
    brlcad/trunk/src/liboptical/osl-renderer.cpp
    brlcad/trunk/src/liboptical/osl-renderer.h
    brlcad/trunk/src/liboptical/sh_osl.c

Modified: brlcad/trunk/src/liboptical/osl-renderer.cpp
===================================================================
--- brlcad/trunk/src/liboptical/osl-renderer.cpp        2011-06-08 18:45:15 UTC 
(rev 44824)
+++ brlcad/trunk/src/liboptical/osl-renderer.cpp        2011-06-08 18:51:38 UTC 
(rev 44825)
@@ -6,9 +6,8 @@
     
     InitShaders();
 
-    // create thread info
+
     ssi = (ShadingSystemImpl *)shadingsys;
-
     thread_info.handle = ssi->create_thread_info();
     thread_info.ctx = ssi->get_context(thread_info.handle);
 
@@ -22,24 +21,163 @@
     ShadingSystem::destroy(shadingsys);
 }
 
-Color3 OSLRenderer::QueryColor(){
-    return Color3(1.0f, 0.0f, 0.0f);
+Color3 OSLRenderer::QueryColor(RenderInfo *info){
+
+    fastf_t y = info->screen_y;
+
+    thread_info.Xi[0] = 0;
+    thread_info.Xi[1] = 0;
+    thread_info.Xi[2] = y*y*y;
+    
+    // execute shader
+    ShaderGlobals globals;
+    ClosureColor *closure = ExecuteShaders(globals, info);
+
+    // sample primitive from closure tree
+    Color3 weight;
+    const ClosurePrimitive *prim = SamplePrimitive(weight, closure, 
erand48(thread_info.Xi));
+
+    if(prim) {
+        if(prim->category() == OSL::ClosurePrimitive::BSDF) {
+            // sample BSDF closure
+            BSDFClosure *bsdf = (BSDFClosure*)prim;
+            Vec3 omega_in, zero(0.0f);
+            Color3 eval;
+            float pdf = 0.0;
+
+            bsdf->sample(globals.Ng, globals.I, zero, zero, 
erand48(thread_info.Xi), erand48(thread_info.Xi),
+                        omega_in, zero, zero, pdf, eval);
+           
+           printf("Weight: %.2lf %.2lf %.2lf -- pdf: %.2lf\n", weight[0], 
weight[1], weight[2], pdf);
+           if (pdf <= 1e-4){
+               printf("Error\n");
+               return Color3(0.0f);
+           }
+           return weight*eval/pdf;
+           /* Recursion FIXME
+            if(pdf != 0.0f) {
+                Ray new_ray(globals.P, omega_in);
+                Color3 r = (weight*eval/pdf)*radiance(thread_info, new_ray, 
depth+1);
+
+                return r;
+            }
+           */
+        }
+        else if(prim->category() == OSL::ClosurePrimitive::Emissive) {
+            // evaluate emissive closure
+            EmissiveClosure *emissive = (EmissiveClosure*)prim;
+            return weight*emissive->eval(globals.Ng, globals.I);
+        }
+        else if(prim->category() == OSL::ClosurePrimitive::Background) {
+            // background closure just returns weight
+            return weight;
+        }
+    }
+    return Color3(0.0f);
 }
 /* -----------------------------------------------
  * Private methods
  * ----------------------------------------------- */
+
 void OSLRenderer::InitShaders(){
 
     shadingsys->attribute("optimize", 2);
     shadingsys->attribute("lockgeom", 1);
     
     shadingsys->ShaderGroupBegin();
-    shadingsys->Shader("surface", "glass", NULL);
+    shadingsys->Shader("surface", "yellow", NULL);
     shadingsys->ShaderGroupEnd();
+
+    shaderstate = shadingsys->state();
     
     shadingsys->clear_state();
 }
+ClosureColor * OSLRenderer::ExecuteShaders(ShaderGlobals globals, RenderInfo 
*info){
+    
+    PointTtoVec3(info->P, globals.P);
+    PointTtoVec3(info->I, globals.I);
+    PointTtoVec3(info->N, globals.Ng);
+    globals.N = globals.Ng;    
+    
+    // u-v coordinates
+    globals.u = info->u;
+    globals.v = info->v;
 
+    // tangents
+    PointTtoVec3(info->dPdu, globals.dPdu);
+    PointTtoVec3(info->dPdv, globals.dPdv);
+
+    // other
+    globals.raytype |= ((info->depth == 0) & (1 << 1));
+    globals.surfacearea = info->surfacearea;
+    globals.backfacing = (globals.Ng.dot(globals.I) < 0.0f);
+    globals.Ci = NULL;
+
+    // execute shader
+    thread_info.ctx->execute(ShadUseSurface, *shaderstate, globals);
+
+    return globals.Ci;
+}
+
+const ClosurePrimitive * OSLRenderer::SamplePrimitive(Color3& weight, const 
ClosureColor *closure, float r){
+
+    if(closure) {
+        const ClosurePrimitive *prim = NULL;
+        float totw = 0.0f;
+       
+        SamplePrimitiveRecurse(prim, weight, closure, Color3(1.0f), totw, r);
+        weight *= totw;
+
+        return prim;
+    }
+    return NULL;
+}
+void OSLRenderer::SamplePrimitiveRecurse(const ClosurePrimitive*& r_prim, 
Color3& r_weight, const ClosureColor *closure,
+                                     const Color3& weight, float& totw, float& 
r){
+    if(closure->type == ClosureColor::COMPONENT) {
+        ClosureComponent *comp = (ClosureComponent*)closure;
+        ClosurePrimitive *prim = (ClosurePrimitive*)comp->data();
+        float p, w = fabsf(weight[0]) + fabsf(weight[1]) + fabsf(weight[2]);
+
+        if(w == 0.0f)
+            return;
+
+        totw += w;
+
+        if(!r_prim) {
+            // no primitive was found yet, so use this
+            r_prim = prim;
+            r_weight = weight/w;
+        }
+        else {
+            p = w/totw;
+
+            if(r < p) {
+                // pick other primitive
+                r_prim = prim;
+                r_weight = weight/w;
+
+                r = r/p;
+            }
+            else {
+                // keep existing primitive
+                r = (r + p)/(1.0f - p);
+            }
+        }
+    }
+    else if(closure->type == ClosureColor::MUL) {
+        ClosureMul *mul = (ClosureMul*)closure;
+
+        SamplePrimitiveRecurse(r_prim, r_weight, mul->closure, mul->weight * 
weight, totw, r);
+    }
+    else if(closure->type == ClosureColor::ADD) {
+        ClosureAdd *add = (ClosureAdd*)closure;
+
+        SamplePrimitiveRecurse(r_prim, r_weight, add->closureA, weight, totw, 
r);
+        SamplePrimitiveRecurse(r_prim, r_weight, add->closureB, weight, totw, 
r);
+    }
+}
+
 /* -----------------------------------------------
  * Wrapper methods
  * ----------------------------------------------- */
@@ -47,21 +185,15 @@
     OSLRenderer* oslr = new OSLRenderer();
     return oslr;
 }
-void oslrenderer_query_color(OSLRenderer *oslr, point_t *q){
-    Color3 c = oslr->QueryColor();
-    (*q)[0] = c[0];
-    (*q)[1] = c[1];
-    (*q)[2] = c[2];
+void oslrenderer_query_color(OSLRenderer *oslr, RenderInfo *info){
+    Color3 pc = oslr->QueryColor(info);
+    info->pc[0] = pc[0];
+    info->pc[1] = pc[1];
+    info->pc[2] = pc[2];
 }
 void oslrenderer_free(OSLRenderer **osl){
     delete (*osl);
     *osl = NULL;
 }
 
-int Renderer2(point_t *p){
-  (*p)[0] = 0.0;
-  (*p)[1] = 1.0;
-  (*p)[2] = 0.0;
-  return 1;
-}
 

Modified: brlcad/trunk/src/liboptical/osl-renderer.h
===================================================================
--- brlcad/trunk/src/liboptical/osl-renderer.h  2011-06-08 18:45:15 UTC (rev 
44824)
+++ brlcad/trunk/src/liboptical/osl-renderer.h  2011-06-08 18:51:38 UTC (rev 
44825)
@@ -4,6 +4,27 @@
 #include <stdio.h>
 #include "vmath.h"
 
+/* Shared struct by which the C shader and the C++ render system may 
+   exchange information
+ */
+struct RenderInfo {
+    
+    /* -- input -- */
+    fastf_t screen_x;     /* Coordinates of the screen (if applicable) */
+    fastf_t screen_y; 
+    point_t P;            /* Query point */
+    point_t N;            /* Object normal */
+    point_t I;            /* Incident ray direction */
+    fastf_t u, v;         /* uv coordinates */
+    point_t dPdu, dPdv;   /* uv tangents */
+    int depth;            /* How many times the ray hit an object */
+    fastf_t surfacearea;  /* FIXME */
+    int isbackfacing;     /* FIXME */
+   
+    /* -- output -- */
+    point_t pc; /* Color of the point (or multiplier) */
+};
+
 #ifdef __cplusplus
 
 #include "render_svc.h"
@@ -23,23 +44,42 @@
    These information are hidden from the calling C code */
 class OSLRenderer {
 
-    SimpleRenderer rend;
     ErrorHandler errhandler;
+    ShaderGlobals globals;
     ShadingSystem *shadingsys;
     ShadingSystemImpl *ssi;
+    SimpleRenderer rend;
     ThreadInfo thread_info;
+    ShadingAttribStateRef shaderstate;
 
-    /* Load OSL shaders */
-    /* FIXME: Add support for any osl shader */
+    /* Convert a point_t to Vec3  */
+    void PointTtoVec3(point_t p, Vec3 &v){
+       v[0] = p[0]; v[1] = p[1]; v[2] = p[2];
+    }
+    /* Convert a Vec3 to floatf_t[3] */
+    void Vec3toPointT(Vec3 &v, point_t p){
+       p[0] = v[0]; p[1] = v[1]; p[2] = v[2];
+    }
+
+    /* Load OSL shaders 
+       FIXME: Add support for any osl shader */
     void InitShaders();
-
+    /* Build the closure tree */
+    ClosureColor *ExecuteShaders(ShaderGlobals globals, RenderInfo *info);
+    /* Sample a primitive from the shaders group */
+    const ClosurePrimitive* SamplePrimitive(Color3& weight, const ClosureColor 
*closure, float r);
+    /* Helper function for SamplePrimitive */
+    void SamplePrimitiveRecurse(const ClosurePrimitive*& r_prim, Color3& 
r_weight, const ClosureColor *closure,
+                               const Color3& weight, float& totw, float& r);
+    
+    
  public:
     
     OSLRenderer();
     ~OSLRenderer();
 
     /* Query a color */
-    Color3 QueryColor();
+    Color3 QueryColor(RenderInfo *info);
 
 };
 
@@ -49,6 +89,10 @@
 struct OSLRenderer
 OSLRenderer;
 
+typedef 
+struct RenderInfo
+RenderInfo;
+
 #endif
 
 
@@ -60,7 +104,7 @@
     OSLRenderer * oslrenderer_init();
 
     /* Wrapper for OSLRenderer::QueryColor */
-    void oslrenderer_query_color(OSLRenderer *oslr, point_t *q);
+    void oslrenderer_query_color(OSLRenderer *oslr, RenderInfo *info);
 
     /* Wrapper for OSLRenderer destructor */
     void oslrenderer_free(OSLRenderer **osl);

Modified: brlcad/trunk/src/liboptical/sh_osl.c
===================================================================
--- brlcad/trunk/src/liboptical/sh_osl.c        2011-06-08 18:45:15 UTC (rev 
44824)
+++ brlcad/trunk/src/liboptical/sh_osl.c        2011-06-08 18:51:38 UTC (rev 
44825)
@@ -266,6 +266,7 @@
     register struct osl_specific *osl_sp =
        (struct osl_specific *)dp;
     point_t pt;
+    RenderInfo info;
 
     VSETALL(pt, 0);
 
@@ -289,10 +290,26 @@
      V3ARGS(pt));
      }
     */
-    oslrenderer_query_color(oslr, pt);
-    VMOVE(swp->sw_color, pt);
+
+    /* Fill in all necessary information for the OSL renderer */
+    VMOVE(info.P, swp->sw_hit.hit_point);
+    VMOVE(info.N, swp->sw_hit.hit_normal);
+    VMOVE(info.I, ap->a_inv_dir);
+    info.u = swp->sw_uv.uv_u;
+    info.v = swp->sw_uv.uv_v;
+    info.screen_x = ap->a_x;
+    info.screen_y = ap->a_y;
+
+    /* FIXME */
+    VSETALL(info.dPdu, 0.0f);
+    VSETALL(info.dPdv, 0.0f);
+    info.depth = 0;
+    info.isbackfacing = 0;
+    info.surfacearea = 1.0f;
     
-
+    oslrenderer_query_color(oslr, &info);
+    VMOVE(swp->sw_color, info.pc);
+    
     /* OSL perform shading operations here */
 
     /* shader must perform transmission/reflection calculations


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to