// Here we set up transformations. These are just examples, set up so // that our unit tests can transform among spaces in ways that we will // recognize as correct. The "shader" and "object" spaces are required // by OSL and the ShaderGlobals will need to have references to them. // For good measure, we also set up a "myspace" space, registering it // with the RendererServices. // static void setup_transformations (SimpleRenderer &rend, OSL::Matrix44 &Mshad, OSL::Matrix44 &Mobj) { Matrix44 M (1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); rend.camera_params (M, ustring("perspective"), 90.0f, 0.1f, 1000.0f, xres, yres); // Make a "shader" space that is translated one unit in x and rotated // 45deg about the z axis. Mshad.makeIdentity (); Mshad.translate (OSL::Vec3 (1.0, 0.0, 0.0)); Mshad.rotate (OSL::Vec3 (0.0, 0.0, M_PI_4)); // std::cout << "shader-to-common matrix: " << Mshad << "\n"; // Make an object space that is translated one unit in y and rotated // 90deg about the z axis. Mobj.makeIdentity (); Mobj.translate (OSL::Vec3 (0.0, 1.0, 0.0)); Mobj.rotate (OSL::Vec3 (0.0, 0.0, M_PI_2)); // std::cout << "object-to-common matrix: " << Mobj << "\n"; OSL::Matrix44 Mmyspace; Mmyspace.scale (OSL::Vec3 (1.0, 2.0, 1.0)); // std::cout << "myspace-to-common matrix: " << Mmyspace << "\n"; rend.name_transform ("myspace", Mmyspace); }
int main (int argc, const char *argv[]) { // Create a new shading system. Timer timer; SimpleRenderer rend; shadingsys = ShadingSystem::create (&rend, NULL, &errhandler); shadingsys->attribute("lockgeom", 1); shadingsys->ShaderGroupBegin (); getargs (argc, argv); if (debug || verbose) errhandler.verbosity (ErrorHandler::VERBOSE); for (size_t i = 0; i < connections.size(); i += 4) { if (i+3 < connections.size()) { std::cout << "Connect " << connections[i] << "." << connections[i+1] << " to " << connections[i+2] << "." << connections[i+3] << "\n"; shadingsys->ConnectShaders (connections[i].c_str(), connections[i+1].c_str(), connections[i+2].c_str(), connections[i+3].c_str()); } } shadingsys->ShaderGroupEnd (); // getargs called 'add_shader' for each shader mentioned on the command // line. So now we should have a valid shading state. ShadingAttribStateRef shaderstate = shadingsys->state (); // Set up shader globals and a little test grid of points to shade. ShaderGlobals shaderglobals; memset(&shaderglobals, 0, sizeof(ShaderGlobals)); // Make a shader space that is translated one unit in x and rotated // 45deg about the z axis. OSL::Matrix44 Mshad; Mshad.translate (OSL::Vec3 (1.0, 0.0, 0.0)); Mshad.rotate (OSL::Vec3 (0.0, 0.0, M_PI_4)); // std::cout << "shader-to-common matrix: " << Mshad << "\n"; OSL::TransformationPtr Mshadptr (&Mshad); shaderglobals.shader2common = Mshadptr; // Make an object space that is translated one unit in y and rotated // 90deg about the z axis. OSL::Matrix44 Mobj; Mobj.translate (OSL::Vec3 (0.0, 1.0, 0.0)); Mobj.rotate (OSL::Vec3 (0.0, 0.0, M_PI_2)); // std::cout << "object-to-common matrix: " << Mobj << "\n"; OSL::TransformationPtr Mobjptr (&Mobj); shaderglobals.object2common = Mobjptr; // Make a 'myspace that is non-uniformly scaled OSL::Matrix44 Mmyspace; Mmyspace.scale (OSL::Vec3 (1.0, 2.0, 1.0)); // std::cout << "myspace-to-common matrix: " << Mmyspace << "\n"; rend.name_transform ("myspace", Mmyspace); shaderglobals.dudx = 1.0f / xres; shaderglobals.dvdy = 1.0f / yres; shaderglobals.raytype = ((ShadingSystemImpl *)shadingsys)->raytype_bit (ustring(raytype)); double setuptime = timer (); double runtime = 0; std::vector<float> pixel; if (outputfiles.size() != 0) std::cout << "\n"; // grab this once since we will be shading several points ShadingSystemImpl *ssi = (ShadingSystemImpl *)shadingsys; void* thread_info = ssi->create_thread_info(); for (int iter = 0; iter < iters; ++iter) { for (int y = 0, n = 0; y < yres; ++y) { for (int x = 0; x < xres; ++x, ++n) { shaderglobals.u = (xres == 1) ? 0.5f : (float) x / (xres - 1); shaderglobals.v = (yres == 1) ? 0.5f : (float) y / (yres - 1); shaderglobals.P = Vec3 (shaderglobals.u, shaderglobals.v, 1.0f); shaderglobals.dPdx = Vec3 (shaderglobals.dudx, shaderglobals.dudy, 0.0f); shaderglobals.dPdy = Vec3 (shaderglobals.dvdx, shaderglobals.dvdy, 0.0f); shaderglobals.N = Vec3 (0, 0, 1); shaderglobals.Ng = Vec3 (0, 0, 1); shaderglobals.dPdu = Vec3 (1.0f, 0.0f, 0.0f); shaderglobals.dPdv = Vec3 (0.0f, 1.0f, 0.0f); shaderglobals.surfacearea = 1; // Request a shading context, bind it, execute the shaders. // FIXME -- this will eventually be replaced with a public // ShadingSystem call that encapsulates it. ShadingContext *ctx = ssi->get_context (thread_info); timer.reset (); timer.start (); // run shader for this point ctx->execute (ShadUseSurface, *shaderstate, shaderglobals); runtime += timer (); if (iter == (iters - 1)) { // extract any output vars into images (on last iteration only) for (size_t i = 0; i < outputfiles.size(); ++i) { Symbol *sym = ctx->symbol (ShadUseSurface, ustring(outputvars[i])); if (! sym) { if (n == 0) { std::cout << "Output " << outputvars[i] << " not found, skipping.\n"; outputimgs.push_back(0); // invalid image } continue; } if (n == 0) std::cout << "Output " << outputvars[i] << " to " << outputfiles[i]<< "\n"; TypeDesc t = sym->typespec().simpletype(); TypeDesc tbase = TypeDesc ((TypeDesc::BASETYPE)t.basetype); TypeDesc outtypebase = tbase; if (dataformatname == "uint8") outtypebase = TypeDesc::UINT8; else if (dataformatname == "half") outtypebase = TypeDesc::HALF; else if (dataformatname == "float") outtypebase = TypeDesc::FLOAT; int nchans = t.numelements() * t.aggregate; pixel.resize (nchans); if (n == 0) { OIIO::ImageSpec spec (xres, yres, nchans, outtypebase); OIIO::ImageBuf* img = new OIIO::ImageBuf(outputfiles[i], spec); #if OPENIMAGEIO_VERSION >= 900 /* 0.9.0 */ OIIO::ImageBufAlgo::zero (*img); #else img->zero (); #endif outputimgs.push_back(img); } OIIO::convert_types (tbase, ctx->symbol_data (*sym, 0), TypeDesc::FLOAT, &pixel[0], nchans); outputimgs[i]->setpixel (x, y, &pixel[0]); } } ssi->release_context (ctx, thread_info); } } } ssi->destroy_thread_info(thread_info); if (outputfiles.size() == 0) std::cout << "\n"; // write any images to disk for (size_t i = 0; i < outputimgs.size(); ++i) { if (outputimgs[i]) { outputimgs[i]->save(); delete outputimgs[i]; } } if (debug || stats) { std::cout << "\n"; std::cout << "Setup: " << Strutil::timeintervalformat (setuptime,2) << "\n"; std::cout << "Run : " << Strutil::timeintervalformat (runtime,2) << "\n"; std::cout << "\n"; std::cout << shadingsys->getstats (5) << "\n"; } ShadingSystem::destroy (shadingsys); return EXIT_SUCCESS; }