/** Export the data to a string, used for editor Copy&Paste. */ void FColorVertexBuffer::ExportText(FString &ValueStr) const { // the following code only works if there is data and this method should only be called if there is data check(NumVertices); ValueStr += FString::Printf(TEXT("ColorVertexData(%i)=("), NumVertices); // 9 characters per color (ARGB in hex plus comma) ValueStr.Reserve(ValueStr.Len() + NumVertices * 9); for(uint32 i = 0; i < NumVertices; ++i) { uint32 Raw = VertexColor(i).DWColor(); // does not handle endianess // order: ARGB TCHAR ColorString[10]; // does not use FString::Printf for performance reasons FCString::Sprintf(ColorString, TEXT("%.8x,"), Raw); ValueStr += ColorString; } // replace , by ) ValueStr[ValueStr.Len() - 1] = ')'; }
void RLines::initOpenGL() { {//Setup initial vertex positions std::vector<float> VertexPos(3 * _N * 2, 0.0); for (size_t i(0); i < _N; ++i) { VertexPos[6*i+0] = i * 1.0f / _N; VertexPos[6*i+1] = i * 1.0f / _N; VertexPos[6*i+2] = i * 1.0f / _N; VertexPos[6*i+3] = i * 1.0f / _N; VertexPos[6*i+4] = (i + 0.5f) * 1.0f / _N; VertexPos[6*i+5] = i * 1.0f / _N; } setGLPositions(VertexPos); } { std::vector<cl_uchar4> VertexColor(_N * 2); for (size_t icol = 0; icol < _N * 2; ++icol) { VertexColor[icol].s[0] = 255; VertexColor[icol].s[1] = 255; VertexColor[icol].s[2] = 255; VertexColor[icol].s[3] = 255; } setGLColors(VertexColor); } {//Setup initial element data std::vector<int> ElementData(2 * _N, 0); for (size_t i(0); i < _N; ++i) { ElementData[2 * i + 0] = 2 * i + 0; ElementData[2 * i + 1] = 2 * i + 1; } setGLElements(ElementData); } }
//------------------------------------------------------------------------------------------------------ Rect3D::Rect3D(const vector3f& ulb, const vector3f& drf, const Color& color) { m_pVertexArray = NEW VertexColor[COUNT_OF_VERTEX]; m_pVertexArray[0] = VertexColor( vector4f(ulb.m_x, ulb.m_y, drf.m_z), color ) ; m_pVertexArray[1] = VertexColor( vector4f(drf.m_x, ulb.m_y, drf.m_z), color ) ; m_pVertexArray[2] = VertexColor( vector4f(drf.m_x, drf.m_y, drf.m_z), color ) ; m_pVertexArray[3] = VertexColor( vector4f(ulb.m_x, drf.m_y, drf.m_z), color ) ; m_pVertexArray[4] = VertexColor( vector4f(ulb.m_x, ulb.m_y, ulb.m_z), color ) ; m_pVertexArray[5] = VertexColor( vector4f(drf.m_x, ulb.m_y, ulb.m_z), color ) ; m_pVertexArray[6] = VertexColor( vector4f(drf.m_x, drf.m_y, ulb.m_z), color ) ; m_pVertexArray[7] = VertexColor( vector4f(ulb.m_x, drf.m_y, ulb.m_z), color ) ; static ushort Indies[COUNT_OF_INDIES]={ 0,1, 1,2, 2,3, 3,0, 0,4, 1,5, 2,6, 3,7, 4,5, 5,6, 6,7, 7,4}; m_pRendBuffer = NEW RendBuffer( Device::RM_LINES ); m_pVertexBuffer = NEW VertexBuffer( Device::MU_DYNAMIC ); m_pIndicesBuffer = NEW IndicesBuffer( Device::MU_STATIC ); m_pRendBuffer->SetVertexBuffer( m_pVertexBuffer ); m_pRendBuffer->SetIndicesBuffer( m_pIndicesBuffer ); m_pVertexBuffer->FlushVertexBuffer( COUNT_OF_VERTEX, m_pVertexArray ); m_pIndicesBuffer->FlushIndiesBuffer( COUNT_OF_INDIES, &Indies[0] ); }
void RSurface::init(const std::shared_ptr<magnet::thread::TaskQueue>& systemQueue) { RTriangles::init(systemQueue); {//Setup initial vertex positions std::vector<float> VertexPos(3 * _N * _N, 0.0); Vector axis1step = _axis1 / (_N-1), axis2step = _axis2 / (_N-1); for (size_t i = 0; i < _N; ++i) for (size_t j = 0; j < _N; ++j) { Vector pos = i * axis1step + j * axis2step + _origin; VertexPos[0 + 3 * (i + _N * j)] = pos[0]; VertexPos[1 + 3 * (i + _N * j)] = pos[1]; VertexPos[2 + 3 * (i + _N * j)] = pos[2]; } setGLPositions(VertexPos); } {//Setup inital normal vectors std::vector<float> VertexNormals(3 * _N * _N, 0.0); Vector normal = _axis3 / _axis3.nrm(); for (size_t i = 0; i < _N; ++i) for (size_t j = 0; j < _N; ++j) { VertexNormals[0 + 3 * (i + _N * j)] = normal[0]; VertexNormals[1 + 3 * (i + _N * j)] = normal[1]; VertexNormals[2 + 3 * (i + _N * j)] = normal[2]; } setGLNormals(VertexNormals); } {//Setup initial Colors std::vector<GLubyte> VertexColor(_N * _N * 4); for (size_t i = 0; i < _N; ++i) for (size_t j = 0; j < _N; ++j) { VertexColor[(i + _N * j) * 4 + 0] = 255; VertexColor[(i + _N * j) * 4 + 1] = 255; VertexColor[(i + _N * j) * 4 + 2] = 255; VertexColor[(i + _N * j) * 4 + 3] = 255; } setGLColors(VertexColor); } {//Setup initial element data std::vector<GLuint> ElementData(3*2*(_N-1)*(_N-1), 0.0); for (size_t i = 0; i < _N - 1; i++) for (size_t j = 0; j < _N - 1; j++) { ElementData[6 * (i + (_N - 1) * j) + 0] = i + _N * j; ElementData[6 * (i + (_N - 1) * j) + 1] = i + _N * (j + 1); ElementData[6 * (i + (_N - 1) * j) + 2] = i + 1 + _N * (j + 1); ElementData[6 * (i + (_N - 1) * j) + 3] = i + _N * j; ElementData[6 * (i + (_N - 1) * j) + 4] = i + 1 + _N * (j + 1); ElementData[6 * (i + (_N - 1) * j) + 5] = i + 1 + _N * j; } setGLElements(ElementData); } }
void RTSpheres::init(const std::tr1::shared_ptr<magnet::thread::TaskQueue>& systemQueue) { RTriangles::init(systemQueue); magnet::GL::Context& context = magnet::GL::Context::getContext(); //Build the sort functor now so we can grab the padding sortFunctor.build(context.getCLCommandQueue(), context.getCLContext()); //We must pad the sort data out to a multiple of sortFunctor.padding() cl_uint padding = std::max(sortFunctor.padding(), size_t(1024)); cl_uint paddedN = ((_N + padding - 1) / padding) * padding; { _spherePositions = cl::Buffer(context.getCLContext(), CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY, sizeof(cl_float4) * _N); _sortKeys = cl::Buffer(context.getCLContext(), CL_MEM_READ_WRITE, sizeof(cl_float) * paddedN); _sortData = cl::Buffer(context.getCLContext(), CL_MEM_READ_WRITE, sizeof(cl_uint) * paddedN); _sphereColors = cl::Buffer(context.getCLContext(), CL_MEM_READ_ONLY, sizeof(cl_uchar4) * paddedN); cl_float4* Pos = (cl_float4*)context.getCLCommandQueue().enqueueMapBuffer(_spherePositions, true, CL_MAP_WRITE, 0, _N * sizeof(cl_float4)); const float density = 0.1; cl_float particleDiam = std::pow(1 * density / _N, float(1.0 / 3.0)); //Generates positions on a simple cubic lattice for (size_t partID(0); partID < _N; ++partID) { Pos[partID].x = ((1.0 * rand()) / RAND_MAX) - 0.5; Pos[partID].y = ((1.0 * rand()) / RAND_MAX) - 0.5; Pos[partID].z = ((1.0 * rand()) / RAND_MAX) - 0.5; Pos[partID].w = particleDiam * 0.5; } //Start copying this data to the graphics card context.getCLCommandQueue().enqueueUnmapMemObject(_spherePositions, (void*)Pos); } {//Setup initial vertex positions size_t nVertice = 0; for (std::vector<SphereDetails>::const_iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) nVertice += iPtr->_type.getVertexCount() * iPtr->_nSpheres; std::vector<float> VertexPos(3 * nVertice, 0.0); setGLPositions(VertexPos); } {//Setup inital normal vectors size_t nNormals = 0; for (std::vector<SphereDetails>::const_iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) nNormals += iPtr->_type.getVertexCount() * iPtr->_nSpheres; std::vector<float> VertexNormals(3 * nNormals, 0.0); nNormals = 0; for (std::vector<SphereDetails>::const_iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) { for (size_t i = 0; i < iPtr->_nSpheres; ++i) for (int j = 0; j < 3 * iPtr->_type.getVertexCount(); ++j) VertexNormals[nNormals + 3 * iPtr->_type.getVertexCount() * i + j] = iPtr->_type.getVertices()[j]; nNormals += 3 * iPtr->_nSpheres * iPtr->_type.getVertexCount(); } setGLNormals(VertexNormals); } {//Setup initial Colors size_t nColors = 0; for (std::vector<SphereDetails>::const_iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) nColors += iPtr->_type.getVertexCount() * iPtr->_nSpheres; std::vector<GLubyte> VertexColor(nColors * 4); for (size_t icol = 0; icol < nColors; ++icol) { VertexColor[icol * 4 + 0] = 255; VertexColor[icol * 4 + 1] = 255; VertexColor[icol * 4 + 2] = 255; VertexColor[icol * 4 + 3] = 255; } setGLColors(VertexColor); } {//Setup initial element data size_t nElements = 0; for (std::vector<SphereDetails>::const_iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) nElements += 3 * iPtr->_type.getFaceCount() * iPtr->_nSpheres; std::vector<GLuint> ElementData(nElements, 0.0); nElements = 0; size_t nSphereVertices = 0; for (std::vector<SphereDetails>::const_iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) { for (size_t i = 0; i < iPtr->_nSpheres; ++i) for (int j = 0; j < 3 * iPtr->_type.getFaceCount(); ++j) ElementData[nElements + 3 * iPtr->_type.getFaceCount() * i + j] = i * iPtr->_type.getVertexCount() + iPtr->_type.getFaces()[j] + nSphereVertices; nSphereVertices += iPtr->_type.getVertexCount() * iPtr->_nSpheres; nElements += 3 * iPtr->_type.getFaceCount() * iPtr->_nSpheres; } setGLElements(ElementData); } std::stringstream fullSource; //It is ideal if the workgroup size divides by 3(coords), 64 //(warp/wave) AND the number of vertices per particle (not so important) //An Icosahedron, of order 0 (12), fits exactly into //3x32x2=192=12x16 _workgroupsize = 2*32*3; _globalsize = _workgroupsize * (std::min((_N +_workgroupsize-1) / _workgroupsize, _workgroupsize*(9216 / _workgroupsize))); fullSource << "#define WORKGROUP_SIZE " << _workgroupsize << "\n"; fullSource << sphereKernelSource; //Need to make the c_str() point to a valid data area, so copy the string std::string finalSource = fullSource.str(); cl::Program::Sources kernelSource; kernelSource.push_back(std::pair<const char*, ::size_t> (finalSource.c_str(), finalSource.size())); _program = cl::Program(context.getCLCommandQueue().getInfo<CL_QUEUE_CONTEXT>(), kernelSource); std::string buildOptions; cl::Device clDevice = context.getCLCommandQueue().getInfo<CL_QUEUE_DEVICE>(); try { _program.build(std::vector<cl::Device>(1, clDevice), buildOptions.c_str()); } catch(cl::Error& err) { std::string msg = _program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(context.getCLDevice()); std::cout << "Compilation failed for device " << context.getCLDevice().getInfo<CL_DEVICE_NAME>() << "\nBuild Log:" << msg; throw; } _renderKernel = cl::Kernel(_program, "SphereRenderKernel"); _sortDataKernel = cl::Kernel(_program, "GenerateData"); _colorKernel = cl::Kernel(_program, "SphereColorKernel"); _pickingKernel = cl::Kernel(_program, "SpherePickingKernel"); _sortDataKernelFunc = _sortDataKernel.bind(context.getCLCommandQueue(), cl::NDRange(paddedN), cl::NDRange(256)); _renderKernelFunc = _renderKernel.bind(context.getCLCommandQueue(), cl::NDRange(_globalsize), cl::NDRange(_workgroupsize)); _pickingKernelFunc = _pickingKernel.bind(context.getCLCommandQueue(), cl::NDRange(_globalsize), cl::NDRange(_workgroupsize)); for (std::vector<SphereDetails>::iterator iPtr = _renderDetailLevels.begin(); iPtr != _renderDetailLevels.end(); ++iPtr) iPtr->setupCLBuffers(context); }
/** * Initializes the buffer with the given vertices, used to convert legacy layouts. * @param InVertices - The vertices to initialize the buffer with. */ void FColorVertexBuffer::Init(const TArray<FStaticMeshBuildVertex>& InVertices) { // First, make sure that there is at least one non-default vertex color in the original data. const int32 InVertexCount = InVertices.Num(); bool bAllColorsAreOpaqueWhite = true; bool bAllColorsAreEqual = true; if( InVertexCount > 0 ) { const FColor FirstColor = InVertices[ 0 ].Color; for( int32 CurVertexIndex = 0; CurVertexIndex < InVertexCount; ++CurVertexIndex ) { const FColor CurColor = InVertices[ CurVertexIndex ].Color; if( CurColor.R != 255 || CurColor.G != 255 || CurColor.B != 255 || CurColor.A != 255 ) { bAllColorsAreOpaqueWhite = false; } if( CurColor.R != FirstColor.R || CurColor.G != FirstColor.G || CurColor.B != FirstColor.B || CurColor.A != FirstColor.A ) { bAllColorsAreEqual = false; } if( !bAllColorsAreEqual && !bAllColorsAreOpaqueWhite ) { break; } } } if( bAllColorsAreOpaqueWhite ) { // Ensure no vertex data is allocated. CleanUp(); // Clear the vertex count and stride. Stride = 0; NumVertices = 0; } else { NumVertices = InVertexCount; // Allocate the vertex data storage type. AllocateData(); // Allocate the vertex data buffer. VertexData->ResizeBuffer(NumVertices); Data = VertexData->GetDataPointer(); // Copy the vertices into the buffer. for(int32 VertexIndex = 0;VertexIndex < InVertices.Num();VertexIndex++) { const FStaticMeshBuildVertex& SourceVertex = InVertices[VertexIndex]; const uint32 DestVertexIndex = VertexIndex; VertexColor(DestVertexIndex) = SourceVertex.Color; } } }