void SpriteTestApp::setup() { addAssetDirectory( getAssetPath("") / ".." / ".." / "shared_assets" ); mSpriteSheet = SpriteSheet::load( getAssetPath("sprite_sheet.json") ); auto sprites = mSpriteSheet->getSpriteNames(); for( const string &name : sprites ) { // hold for equivalent of 2 frames at 24fps mSpriteAnimation.addFrame( mSpriteSheet->getSpriteData(name), 2.0f / 24.0f ); } mSpriteAnimation.setFrameRate( 1.0f ); Vec2f left_center = Vec2f{ 0.25f, 0.5f } * Vec2f{ getWindowSize() }; mSpriteAnimation.getLocus().setLoc( left_center ); mSprite = mSpriteSheet->getSprite("wood_cracked"); mSprite.getLocus().setLoc( left_center + Vec2f{ 0, getWindowHeight() * 0.25f } ); mSprite.setLayer( 5 ); // mSimpleRenderer.add( &mSpriteAnimation ); mSimpleRenderer.add( &mSprite ); // mRenderer2dStrip.add( &mSprite ); mLastUpdate = getElapsedSeconds(); // sort by layer mSimpleRenderer.sort(); mRenderer2dStrip.sort(); }
// 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); }
void SimpleGraphicsPipeline::Run(State* state) { std::vector<Layer*>&& layers = state->GetLayers(); std::sort(layers.begin(), layers.end(), ZOrderLessThan); { for (auto& layer : layers) { std::vector<Entity*> entitiesToRender; auto&& entities = layer->GetEntities(); ICamera* camera = nullptr; for (Entity* entity : entities) { if (entity->IsActive()) { if (entity->IsVisible()) entitiesToRender.emplace_back(entity); if (CameraComponent* camC = entity->GetC<CameraComponent>()) { camera = camC->GetCamera(); } } } if (camera) { SimpleRenderer renderer; renderer.Render(entitiesToRender, camera); } } } }
SimpleSpriteRenderer::SimpleSpriteRenderer() { SimpleRenderer* render = SimpleEngine::Instance()->GetRenderer(); SimpleResourceManager* resources = SimpleEngine::Instance()->GetResourceManager(); //All the sprites use the same geometry _mesh = render->GetUnitaryQuad(); _shader = resources->GetProgram("VertexSprite"); _cam = SimpleEngine::Instance()->GetScene()->GetCamera(); _rectOffset = glm::vec2(0.0f); _rectSize = glm::vec2(1.0f); _snapToGrid = false; _snapSize = glm::vec2(1.0); }
void RendererTestApp::setup() { mRenderFunctions = { { "Batch 2d", [=](){ mRenderer2dStrip.update(); mRenderer2dStrip.render(); } }, { "VBO 2d", [=](){ mRenderer2dStripVbo.update(); mRenderer2dStripVbo.render(); } }, { "Simple", [=](){ mSimpleRenderer.render(); } }, { "Batch 2d (no updates)", [=](){ mRenderer2dStrip.render(); } }, { "VBO 2d (no updates)", [=](){ mRenderer2dStripVbo.render(); } }, }; mRenderFn = mRenderFunctions.begin(); gl::enableVerticalSync(); Rand r; for( auto &box : mBoxes ) { box.setColor( ColorA{ CM_HSV, r.nextFloat( 1.0f ), 0.9f, 0.9f, 1.0f } ); box.setPos( Vec2f{ r.nextFloat(getWindowWidth()), r.nextFloat(getWindowHeight()) } ); box.setRotation( r.nextFloat( M_PI * 2 ) ); mRenderer2dStrip.add( &box ); mSimpleRenderer.add( &box ); mRenderer2dStripVbo.add( &box ); } // We perform the cast since we know what type of things we stored in each renderer // A type-safe way could be to assign y to each objects layer and then sort by layer Vec2f center = getWindowCenter(); auto vortex_simple = [center]( const SimpleRenderer::Renderable *lhs, const SimpleRenderer::Renderable *rhs ) { return static_cast<const Box*>( lhs )->getPos().distance(center) < static_cast<const Box*>( rhs )->getPos().distance(center); }; auto vortex_triangle = [center]( const BatchRenderer2d::Renderable *lhs, const BatchRenderer2d::Renderable *rhs ) { return static_cast<const Box*>( lhs )->getPos().distance(center) < static_cast<const Box*>( rhs )->getPos().distance(center); }; mSimpleRenderer.sort( vortex_simple ); mRenderer2dStrip.sort( vortex_triangle ); mRenderer2dStripVbo.sort( vortex_triangle ); getWindow()->getSignalKeyUp().connect( [this](KeyEvent &event){ if( event.getCode() == KeyEvent::KEY_SPACE ){ swapRenderer(); } } ); getWindow()->getSignalTouchesEnded().connect( [this](TouchEvent &event){ swapRenderer(); } ); }
void SpriteTestApp::draw() { // clear out the window with black gl::clear( Color( 0, 0, 0 ) ); gl::disable( GL_TEXTURE_2D ); gl::drawLine( Vec2f{ getWindowWidth() / 2, 0 }, Vec2f{ getWindowWidth() / 2, getWindowHeight() } ); mSpriteSheet->enableAndBind(); mSimpleRenderer.render(); mSpriteAnimation.render(); gl::pushModelView(); gl::translate( Vec2f{ getWindowWidth() / 2, 0.0f } ); mRenderer2dStrip.render(); mSpriteAnimation.render(); gl::popModelView(); }
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; }