1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 Also see acknowledgements in Readme.html 9 10 You may use this sample code for anything you like, it is not covered by the 11 same license as the rest of the engine. 12 ----------------------------------------------------------------------------- 13 */ 14 #include "SdkSample.h" 15 #include "SamplePlugin.h" 16 17 using namespace Ogre; 18 using namespace OgreBites; 19 20 static SamplePlugin* sp; 21 static Sample* s; 22 23 class _OgreSampleClassExport Sample_AtomicCounters : public SdkSample 24 { 25 Entity* mOgreEnt; 26 27 TexturePtr mImage; 28 HardwarePixelBufferSharedPtr mPixelBuffer; 29 30 //HardwareCounterBufferSharedPtr mBuffer; 31 32 public: 33 Sample_AtomicCounters()34 Sample_AtomicCounters() 35 { 36 mInfo["Title"] = "Atomic Counters"; 37 mInfo["Description"] = "An example of using atomic counters to visualise GPU rasterization order"; 38 mInfo["Thumbnail"] = "thumb_atomicc.png"; 39 mInfo["Category"] = "Unsorted"; 40 } 41 testCapabilities(const RenderSystemCapabilities * caps)42 void testCapabilities(const RenderSystemCapabilities* caps) 43 { 44 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 45 "Sample currently under construction. Try again soon!", 46 "Sample_Compute::testCapabilities"); 47 48 if (!caps->hasCapability(RSC_ATOMIC_COUNTERS)) 49 { 50 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your render system / hardware does not support atomic counters, " 51 "so you cannot run this sample. Sorry!", 52 "Sample_Compute::testCapabilities"); 53 } 54 else if (!caps->hasCapability(RSC_COMPUTE_PROGRAM)) 55 { 56 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your render system / hardware does not support compute programs, " 57 "so you cannot run this sample. Sorry!", 58 "Sample_Compute::testCapabilities"); 59 } 60 else if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) 61 { 62 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your render system / hardware does not support tesselation programs, " 63 "so you cannot run this sample. Sorry!", 64 "Sample_Compute::testCapabilities"); 65 } 66 else if (!caps->hasCapability(RSC_GEOMETRY_PROGRAM)) 67 { 68 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your render system / hardware does not support geometry programs, " 69 "so you cannot run this sample. Sorry!", 70 "Sample_Compute::testCapabilities"); 71 } 72 } 73 74 // Just override the mandatory create scene method setupContent(void)75 void setupContent(void) 76 { 77 mCameraNode->setPosition(0, 0, -40); 78 mCamera->lookAt(0,0,0); 79 // mCamera->setNearClipDistance(0.1); 80 // mCamera->setFarClipDistance(100); 81 82 mOgreEnt = mSceneMgr->createEntity("PlainHead", "ogrehead.mesh"); 83 mOgreEnt->setMaterialName("AtomicCounters"); 84 //mOgreEnt->setMaterialName("BaseWhiteNoLighting"); 85 SceneNode* ogre = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 86 ogre->setPosition(50, -50, 140); 87 ogre->setDirection(0,0,1); 88 ogre->attachObject(mOgreEnt); 89 90 //////////////////////////////// 91 // Image Load/Store 92 //////////////////////////////// 93 94 mImage = TextureManager::getSingleton().createManual( 95 "ImageData", // Name of texture 96 "General", // Name of resource group in which the texture should be created 97 TEX_TYPE_2D, // Texture type 98 256, 256, 1, // Width, Height, Depth 99 0, // Number of mipmaps 100 PF_X8R8G8B8 // Pixel format //TODO support formats from GL3+ 101 //TU_DYNAMIC // usage 102 ); 103 104 mImage->createShaderAccessPoint(0); 105 106 mPixelBuffer = mImage->getBuffer(0,0); 107 108 // Lock the buffer so we can write to it. 109 mPixelBuffer->lock(HardwareBuffer::HBL_DISCARD); 110 const PixelBox &pb = mPixelBuffer->getCurrentLock(); 111 112 // Update the contents of pb here 113 // Image data starts at pb.data and has format pb.format 114 // Here we assume data.format is PF_X8R8G8B8 so we can address pixels as uint32. 115 uint *data = reinterpret_cast<uint*>(pb.data); 116 size_t height = pb.getHeight(); 117 size_t width = pb.getWidth(); 118 size_t pitch = pb.rowPitch; // Skip between rows of image 119 for (size_t y = 0; y < height; ++y) 120 { 121 for(size_t x = 0; x < width; ++x) 122 { 123 // 0xXXRRGGBB -> fill the buffer with yellow pixels 124 // data[pitch * y + x] = 0x00FFFF00; 125 data[pitch * y + x] = 0x0087CEEB; 126 } 127 } 128 129 // Unlock the buffer again (frees it for use by the GPU) 130 mPixelBuffer->unlock(); 131 } 132 cleanupContent()133 void cleanupContent() 134 { 135 // Read image load/store data. 136 // mPixelBuffer->lock(HardwareBuffer::HBL_READ_ONLY); 137 // const PixelBox &pb = mPixelBuffer->getCurrentLock(); 138 // uint *data = static_cast<uint*>(pb.data); 139 // size_t height = pb.getHeight(); 140 // size_t width = pb.getWidth(); 141 // size_t pitch = pb.rowPitch; // Skip between rows of image 142 // printf("Buffer values.\n"); 143 // for (size_t y = 0; y < height; ++y) 144 // { 145 // for(size_t x = 0; x < width; ++x) 146 // { 147 // std::cout << " " << std::hex << data[pitch * y + x]; 148 // } 149 // std::cout << std::endl; 150 // } 151 // std::cout << std::hex << data[0]; 152 // std::cout << " " << data[1] << std::endl; 153 // mPixelBuffer->unlock(); 154 155 //MeshManager::getSingleton().remove(mTetrahedraMesh->getName()); 156 } 157 frameRenderingQueued(const FrameEvent & evt)158 bool frameRenderingQueued(const FrameEvent& evt) 159 { 160 Real seconds = (Real)(Root::getSingleton().getTimer()->getMilliseconds()) / 1000.0; 161 Pass* renderPass = mOgreEnt->getSubEntity(0)->getMaterial()->getTechnique(0)->getPass(0); 162 if (renderPass->hasFragmentProgram()) 163 { 164 Ogre::GpuProgramParametersSharedPtr pParams = renderPass->getFragmentProgramParameters(); 165 if ( pParams.isNull() ) 166 { 167 //printf("SAD PANDA!"); 168 } 169 else 170 { 171 if ( pParams->_findNamedConstantDefinition( "ColourMe[0]" ) ) 172 { 173 Vector4 constParam = Ogre::Vector4(0.5, 0.1, 0.0, 1.0); 174 renderPass->getFragmentProgramParameters()->setNamedConstant("ColourMe[0]", constParam); 175 176 Vector4 timeParam = Ogre::Vector4( 177 Ogre::Math::Sin(seconds)*0.5, 0.0, Ogre::Math::Cos(seconds)*0.5, 0.0); 178 renderPass->getFragmentProgramParameters()->setNamedConstant("ColourMe[1]", timeParam); 179 } 180 const Ogre::GpuConstantDefinition* atom_counter_def; 181 if ( (atom_counter_def = &pParams->getConstantDefinition("atom_counter")) ) 182 { 183 //TODO lock buffer, retrieve counter value similar to compute above 184 //const uint* counter = pParams->getUnsignedIntPointer(atom_counter_def->physicalIndex); 185 //const uint* counter2 = ; 186 //std::cout << "FOUND THE ATOMS: " << *counter << " " << std::endl; //<< *counter2 << std::endl; 187 } 188 } 189 } 190 191 // renderPass->getFragmentProgramParameters()->getConstantDefinition("atom_counter").getValue(); 192 return SdkSample::frameRenderingQueued(evt); 193 } 194 }; 195