Esempio n. 1
0
void Stroke::draw(Renderer_ptr renderer, uint64_t time) {
    _shader->setWidth(_width);
    _shader->setColor(_color);
    _shader->setStartLength(0.0);
    _shader->setEndLength(_pathLength);

    _shader->bind();

    // TODO: make this async, instead of tesselating at render-time.
    if (_dirty) {
        // TODO: need better LOD calculation.
        int vertexCount = static_cast<int>(_pathLength);
        if (vertexCount % 2 == 1) vertexCount++;
        int triangleCount = (vertexCount - 2) * 2;

        std::unique_ptr<Vertex[]> vertices(new Vertex[vertexCount]);

        // TODO: this should be a static Arc function;
        tesselate(vertices.get(), vertexCount, _path);

        unique_ptr<grfx::Buffer> vertexBuffer(new grfx::GpuBuffer(renderer, GL_ARRAY_BUFFER));
        vertexBuffer->load(std::move(vertices), vertexCount * sizeof(Vertex), GL_STATIC_DRAW);

        _mesh.reset(new StrokeMesh());
        _mesh->setBuffers(std::move(vertexBuffer),
                          Stroke::indexBuffer(renderer, triangleCount),
                          0, triangleCount);
        _dirty = false;
    }
    _mesh->draw(renderer);
}
Esempio n. 2
0
int main()
{
	vpp::ContextSettings settings = { /* ... */ };
	
	auto window = initWindow();
	auto context = vpp::Win32Context(settings, hinstance, window);

	vpp::VertexBufferLayout vbLayout({vpp::VertexBufferLayout::Point3fColor3f});
	vpp::DescriptorSetLayout dsLayout(context.device(), {vk::DescriptorType::UniformBuffer});

	vpp::GraphicsPipeline::CreateInfo createInfo;
	createInfo.renderPass = context.swapChain().vkRenderPass();
	createInfo.vertexBufferLayouts = vblayout;
	createInfo.descriptorSetLayouts = dsLayout;
	createInfo.shaderProgram = vpp::ShaderProgram({
			{vk::ShaderStageFlags::Vertex, "vert.sprv"}, 
			{vk::ShaderStageFlags::Fragment, "frag.sprv"}
		});

	vpp::GraphicsPipeline pipeline(context.device(), createInfo);

	//buffer, descriptors
	vpp::Buffer vertexBuffer(context.device(), vertices);
	vpp::Buffer uniformBuffer(context.device(), someTransformMatrix);

	vpp::DescriptorSet descriptorSet(dsLayout);
	static_cast<vpp::BufferDescriptor>(descriptorSet[0]).write(uniformBuffer); //#1
	descriptorSet.writeBuffers(0, {uniformBuffer}) //#2; 

	//later
	pipeline.drawCommands(commandBuffer, {vertexBuffer}, {descriptorSet});
}
Esempio n. 3
0
//----------------------------------------------------------------------
bool FontManager::Initialise(const glm::ivec2& screenResolution)
{
  this->screenResolution = screenResolution;

  if (!effect.Load("assets\\effects\\fonteffect.glsl", "RenderFont"))
  {
    LOG("did not load font rendering effect\n");
    return false;
  }
  // Since the screen resolution does not change at runtime, set this now...
  effect.ScreenSize->Set(glm::vec2(screenResolution));
  effect.GlyphTexture->Set(GlyphTextureSlot);

  sampler = boost::make_shared<Sampler2D>();
  sampler->SetMagFilter(GL_LINEAR);
  sampler->SetMinFilter(GL_LINEAR);
  sampler->SetWrapS(GL_CLAMP_TO_EDGE);
  sampler->SetWrapT(GL_CLAMP_TO_EDGE);

  VertexLayout vertexLayout;
  vertexLayout.AddAttribute(vertexAttribute);

  // Initialise vertex buffers for dynamic update...
  for (size_t i = 0; i < bufferCount; ++i)
  {
    boost::shared_ptr<VertexBuffer> vertexBuffer(new VertexBuffer());
    vertexBuffer->Initialise(vertexLayout, VerticesInBuffer, GL_DYNAMIC_DRAW);
    geometry[i].Initialise(vertexBuffer);
  }

  return true;
}
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void FirstTriangle::onInitialization()
{
	// Call the base implementation
	IApplicationRenderer::onInitialization();

	// Get and check the renderer instance
	Renderer::IRendererPtr renderer(getRenderer());
	if (nullptr != renderer)
	{
		// Begin debug event
		RENDERER_BEGIN_DEBUG_EVENT_FUNCTION(renderer)

		// Decide which shader language should be used (for example "GLSL", "HLSL" or "Cg")
		Renderer::IShaderLanguagePtr shaderLanguage(renderer->getShaderLanguage());
		if (nullptr != shaderLanguage)
		{
			{ // Create the program
				// Get the shader source code (outsourced to keep an overview)
				const char *vertexShaderSourceCode = nullptr;
				const char *fragmentShaderSourceCode = nullptr;
				#include "FirstTriangle_Cg.h"
				#include "FirstTriangle_GLSL_110.h"
				#include "FirstTriangle_GLSL_ES2.h"
				#include "FirstTriangle_HLSL_D3D9_D3D10_D3D11.h"
				#include "FirstTriangle_Null.h"

				// Create the vertex shader
				Renderer::IVertexShader *vertexShader = shaderLanguage->createVertexShader(vertexShaderSourceCode);
				RENDERER_SET_RESOURCE_DEBUG_NAME(vertexShader, "Triangle VS")

				// Create the fragment shader
				Renderer::IFragmentShader *fragmentShader = shaderLanguage->createFragmentShader(fragmentShaderSourceCode);
				RENDERER_SET_RESOURCE_DEBUG_NAME(fragmentShader, "Triangle FS")

				// Create the program
				mProgram = shaderLanguage->createProgram(vertexShader, fragmentShader);
				RENDERER_SET_RESOURCE_DEBUG_NAME(mProgram, "Triangle program")
			}

			// Is there a valid program?
			if (nullptr != mProgram)
			{
				// Create the vertex buffer object (VBO)
				// -> Clip space vertex positions, left/bottom is (-1,-1) and right/top is (1,1)
				static const float VERTEX_POSITION[] =
				{					// Vertex ID	Triangle on screen
					 0.0f, 1.0f,	// 0				0
					 1.0f, 0.0f,	// 1			   .   .
					-0.5f, 0.0f		// 2			  2.......1
				};
				Renderer::IVertexBufferPtr vertexBuffer(renderer->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));
				RENDERER_SET_RESOURCE_DEBUG_NAME(vertexBuffer, "Triangle VBO")

				// Create vertex array object (VAO)
				// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
				// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
				// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
				//    reference of the used vertex buffer objects (VBO). If the reference counter of a
				//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
				const Renderer::VertexArrayAttribute vertexArray[] =
				{
					{ // Attribute 0
						// Data destination
						Renderer::VertexArrayFormat::FLOAT_2,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
						"Position",								// name[64] (char)
						"POSITION",								// semantic[64] (char)
						0,										// semanticIndex (unsigned int)
						// Data source
						vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
						0,										// offset (unsigned int)
						sizeof(float) * 2,						// stride (unsigned int)
						// Data source, instancing part
						0										// instancesPerElement (unsigned int)
					}
				};
				mVertexArray = mProgram->createVertexArray(sizeof(vertexArray) / sizeof(Renderer::VertexArrayAttribute), vertexArray);
				RENDERER_SET_RESOURCE_DEBUG_NAME(mVertexArray, "Triangle VAO")
			}
		}
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void FirstGeometryShader::onInitialization()
{
	// Call the base implementation
	IApplicationRenderer::onInitialization();

	// Get and check the renderer instance
	// -> Geometry shaders supported?
	Renderer::IRendererPtr renderer(getRenderer());
	if (nullptr != renderer && renderer->getCapabilities().maximumNumberOfGsOutputVertices)
	{
		// Begin debug event
		RENDERER_BEGIN_DEBUG_EVENT_FUNCTION(renderer)

		// Decide which shader language should be used (for example "GLSL", "HLSL" or "Cg")
		Renderer::IShaderLanguagePtr shaderLanguage(renderer->getShaderLanguage());
		if (nullptr != shaderLanguage)
		{
			{ // Create the program
				// Get the shader source code (outsourced to keep an overview)
				const char *vertexShaderSourceCode = nullptr;
				const char *geometryShaderSourceCode = nullptr;
				const char *fragmentShaderSourceCode = nullptr;
				#include "FirstGeometryShader_GLSL_330.h"
				#include "FirstGeometryShader_HLSL_D3D10_D3D11.h"
				#include "FirstGeometryShader_Null.h"

				// Create the program
				mProgram = shaderLanguage->createProgram(
					shaderLanguage->createVertexShader(vertexShaderSourceCode),
					shaderLanguage->createGeometryShader(geometryShaderSourceCode, Renderer::GsInputPrimitiveTopology::POINTS, Renderer::GsOutputPrimitiveTopology::TRIANGLE_STRIP, 3),
					shaderLanguage->createFragmentShader(fragmentShaderSourceCode));
			}

			// TODO(co) Attribute less rendering (aka "drawing without data") possible with OpenGL? For me it appears not to work, I see nothing and also get no error...
			// -> Tested with: "Radeon HD 6970M", driver "catalyst_12-7_beta_windows7_20120629.exe"
			// -> According to http://renderingpipeline.com/2012/03/are-vertex-shaders-obsolete/ it should work
			// -> Apparently there are currently some issues when using this approach: http://www.opengl.org/discussion_boards/showthread.php/177372-Rendering-simple-shapes-without-passing-vertices
			if (nullptr != mProgram && 0 == strcmp(renderer->getName(), "OpenGL"))
			{
				// Create the vertex buffer object (VBO)
				static const float VERTEX_POSITION[] =
				{			// Vertex ID
					42.0f	// 0
				};
				Renderer::IVertexBufferPtr vertexBuffer(renderer->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));

				// Create vertex array object (VAO)
				// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
				// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
				// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
				//    reference of the used vertex buffer objects (VBO). If the reference counter of a
				//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
				const Renderer::VertexArrayAttribute vertexArray[] =
				{
					{ // Attribute 0
						// Data destination
						Renderer::VertexArrayFormat::FLOAT_1,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
						"Position",								// name[64] (char)
						"POSITION",								// semantic[64] (char)
						0,										// semanticIndex (unsigned int)
						// Data source
						vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
						0,										// offset (unsigned int)
						sizeof(float),							// stride (unsigned int)
						// Data source, instancing part
						0										// instancesPerElement (unsigned int)
					}
				};
				mVertexArray = mProgram->createVertexArray(sizeof(vertexArray) / sizeof(Renderer::VertexArrayAttribute), vertexArray);
			}
		}

		// End debug event
		RENDERER_END_DEBUG_EVENT(renderer)
	}
Esempio n. 6
0
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void Fxaa::onInitialization()
{
	// Call the base implementation
	IApplicationRenderer::onInitialization();

	// Get and check the renderer instance
	Renderer::IRendererPtr renderer(getRenderer());
	if (nullptr != renderer)
	{
		// Begin debug event
		RENDERER_BEGIN_DEBUG_EVENT_FUNCTION(renderer)

		// Create the framebuffer object (FBO) instance by using the current window size
		recreateFramebuffer();

		{ // Create sampler state
		  // -> Our texture does not have any mipmaps, set "Renderer::SamplerState::maxLOD" to zero
		  //    in order to ensure a correct behaviour across the difference graphics APIs
		  // -> When not doing this you usually have no issues when using OpenGL, OpenGL ES 2, Direct 10,
		  //    Direct3D 11 or Direct3D 9 with the "ps_2_0"-profile, but when using Direct3D 9 with the
		  //    "ps_3_0"-profile you might get into trouble due to another internal graphics API behaviour
			Renderer::SamplerState samplerState = Renderer::ISamplerState::getDefaultSamplerState();
			samplerState.maxLOD = 0.0f;	// We don't use mipmaps
			mSamplerState = renderer->createSamplerState(samplerState);
		}

		{ // Depth stencil state
		  // -> By default depth test is enabled
		  // -> In this simple example we don't need depth test, so, disable it so we don't need to care about the depth buffer

			// Create depth stencil state
			Renderer::DepthStencilState depthStencilState = Renderer::IDepthStencilState::getDefaultDepthStencilState();
			depthStencilState.depthEnable = false;
			mDepthStencilState = renderer->createDepthStencilState(depthStencilState);

			// Set the depth stencil state directly within this initialization phase, we don't change it later on
			renderer->omSetDepthStencilState(mDepthStencilState);
		}

		// Decide which shader language should be used (for example "GLSL", "HLSL" or "Cg")
		Renderer::IShaderLanguagePtr shaderLanguage(renderer->getShaderLanguage());
		if (nullptr != shaderLanguage)
		{
			{ // Create the program for scene rendering
				// Get the shader source code (outsourced to keep an overview)
				const char *vertexShaderSourceCode = nullptr;
				const char *fragmentShaderSourceCode = nullptr;
				#include "Fxaa_SceneRendering_Cg.h"
				#include "Fxaa_SceneRendering_GLSL_120.h"
				#include "Fxaa_SceneRendering_GLSL_ES2.h"
				#include "Fxaa_SceneRendering_HLSL_D3D9_D3D10_D3D11.h"
				#include "Fxaa_SceneRendering_Null.h"

				// Create the program for scene rendering
				mProgramSceneRendering = shaderLanguage->createProgram(shaderLanguage->createVertexShader(vertexShaderSourceCode), shaderLanguage->createFragmentShader(fragmentShaderSourceCode));
			}

			// Is there a valid program for scene rendering?
			if (nullptr != mProgramSceneRendering)
			{
				// Create the vertex buffer object (VBO)
				// -> Clip space vertex positions, left/bottom is (-1,-1) and right/top is (1,1)
				static const float VERTEX_POSITION[] =
				{					// Vertex ID	Triangle on screen
					 0.0f, 1.0f,	// 0				0
					 1.0f, 0.0f,	// 1			   .   .
					-0.5f, 0.0f		// 2			  2.......1
				};
				Renderer::IVertexBufferPtr vertexBuffer(renderer->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));

				// Create vertex array object (VAO)
				// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
				// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
				// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
				//    reference of the used vertex buffer objects (VBO). If the reference counter of a
				//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
				const Renderer::VertexArrayAttribute vertexArray[] =
				{
					{ // Attribute 0
						// Data destination
						Renderer::VertexArrayFormat::FLOAT_2,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
						"Position",								// name[64] (char)
						"POSITION",								// semantic[64] (char)
						0,										// semanticIndex (unsigned int)
						// Data source
						vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
						0,										// offset (unsigned int)
						sizeof(float) * 2,						// stride (unsigned int)
						// Data source, instancing part
						0										// instancesPerElement (unsigned int)
					}
				};
				mVertexArraySceneRendering = mProgramSceneRendering->createVertexArray(sizeof(vertexArray) / sizeof(Renderer::VertexArrayAttribute), vertexArray);
			}

			// Create the post-processing program instance by using the current window size
			recreatePostProcessingProgram();

			// Is there a valid program for post-processing?
			if (nullptr != mProgramPostProcessing)
			{
				// Create the vertex buffer object (VBO)
				// -> Clip space vertex positions, left/bottom is (-1,-1) and right/top is (1,1)
				static const float VERTEX_POSITION[] =
				{					// Vertex ID	Triangle strip on screen
					-1.0f, -1.0f,	// 0			  1.......3
					-1.0f,  1.0f,	// 1			  .	  .   .
					 1.0f, -1.0f,	// 2			  0.......2
					 1.0f,  1.0f	// 3
				};
				Renderer::IVertexBufferPtr vertexBuffer(renderer->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));

				// Create vertex array object (VAO)
				// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
				// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
				// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
				//    reference of the used vertex buffer objects (VBO). If the reference counter of a
				//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
				const Renderer::VertexArrayAttribute vertexArray[] =
				{
					{ // Attribute 0
						// Data destination
						Renderer::VertexArrayFormat::FLOAT_2,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
						"Position",								// name[64] (char)
						"POSITION",								// semantic[64] (char)
						0,										// semanticIndex (unsigned int)
						// Data source
						vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
						0,										// offset (unsigned int)
						sizeof(float) * 2,						// stride (unsigned int)
						// Data source, instancing part
						0										// instancesPerElement (unsigned int)
					}
				};
				mVertexArrayPostProcessing = mProgramSceneRendering->createVertexArray(sizeof(vertexArray) / sizeof(Renderer::VertexArrayAttribute), vertexArray);
			}
		}

		// End debug event
		RENDERER_END_DEBUG_EVENT(renderer)
	}
Esempio n. 7
0
void
loadMeshes( CalCoreModel* calCoreModel,
            MeshesVector& meshes )
    throw (std::runtime_error)
{
    const int maxVertices = Constants::MAX_VERTEX_PER_MODEL;
    const int maxFaces    = Constants::MAX_VERTEX_PER_MODEL * 3;

    std::auto_ptr< CalHardwareModel > calHardwareModel( new CalHardwareModel( calCoreModel ) );
    
    osg::ref_ptr< VertexBuffer >      vertexBuffer( new VertexBuffer( maxVertices ) );
    osg::ref_ptr< WeightBuffer >      weightBuffer( new WeightBuffer( maxVertices ) );
    osg::ref_ptr< MatrixIndexBuffer > matrixIndexBuffer( new MatrixIndexBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      normalBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      tangentBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      binormalBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< TexCoordBuffer >    texCoordBuffer( new TexCoordBuffer( maxVertices ) );
    std::vector< CalIndex >           indexBuffer( maxFaces*3 );

    std::vector< float > floatMatrixIndexBuffer( maxVertices*4 );

    calHardwareModel->setVertexBuffer((char*)vertexBuffer->getDataPointer(),
                                      3*sizeof(float));
#ifdef OSG_CAL_BYTE_BUFFERS
    std::vector< float > floatNormalBuffer( getVertexCount()*3 );
    calHardwareModel->setNormalBuffer((char*)&floatNormalBuffer.begin(),
                                      3*sizeof(float));
#else
    calHardwareModel->setNormalBuffer((char*)normalBuffer->getDataPointer(),
                                      3*sizeof(float));
#endif
    calHardwareModel->setWeightBuffer((char*)weightBuffer->getDataPointer(),
                                      4*sizeof(float));
    calHardwareModel->setMatrixIndexBuffer((char*)&floatMatrixIndexBuffer.front(),
                                           4*sizeof(float));
    calHardwareModel->setTextureCoordNum( 1 );
    calHardwareModel->setTextureCoordBuffer(0, // texture stage #
                                            (char*)texCoordBuffer->getDataPointer(),
                                            2*sizeof(float));
    calHardwareModel->setIndexBuffer( &indexBuffer.front() );
    // calHardwareModel->setCoreMeshIds(_activeMeshes);
    // if ids not set all meshes will be used at load() time

    //std::cout << "calHardwareModel->load" << std::endl;
    calHardwareModel->load( 0, 0, Constants::MAX_BONES_PER_MESH );
    //std::cout << "calHardwareModel->load ok" << std::endl;

    int vertexCount = calHardwareModel->getTotalVertexCount();
//    int faceCount   = calHardwareModel->getTotalFaceCount();

//    std::cout << "vertexCount = " << vertexCount << "; faceCount = " << faceCount << std::endl;
    
    GLubyte* matrixIndexBufferData = (GLubyte*) matrixIndexBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*4; i++ )
    {
        matrixIndexBufferData[i] = static_cast< GLubyte >( floatMatrixIndexBuffer[i] );
    }

#ifdef OSG_CAL_BYTE_BUFFERS
    GLbyte* normals = (GLbyte*) normalBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*3; i++ )
    {
        normals[i]  = static_cast< GLbyte >( floatNormalBuffer[i]*127.0 );
    }
#endif

    // invert UVs for OpenGL (textures are inverted otherwise - for example, see abdulla/klinok)
    GLfloat* texCoordBufferData = (GLfloat*) texCoordBuffer->getDataPointer();

    for ( float* tcy = texCoordBufferData + 1;
          tcy < texCoordBufferData + 2*vertexCount;
          tcy += 2 )
    {
        *tcy = 1.0f - *tcy;
    }

    // -- And now create meshes data --
    int unriggedBoneIndex = calCoreModel->getCoreSkeleton()->getVectorCoreBone().size();
    // we add empty bone in ModelData to handle unrigged vertices;
    
    for( int hardwareMeshId = 0; hardwareMeshId < calHardwareModel->getHardwareMeshCount(); hardwareMeshId++ )
    {
        calHardwareModel->selectHardwareMesh(hardwareMeshId);
        int faceCount = calHardwareModel->getFaceCount();

        if ( faceCount == 0 )
        {
            continue; // we ignore empty meshes
        }
        
        CalHardwareModel::CalHardwareMesh* hardwareMesh =
            &calHardwareModel->getVectorHardwareMesh()[ hardwareMeshId ];

        osg::ref_ptr< MeshData > m( new MeshData );
        
        m->name = calCoreModel->getCoreMesh( hardwareMesh->meshId )->getName();
        m->coreMaterial = hardwareMesh->pCoreMaterial;
        if ( m->coreMaterial == NULL )
        {
            CalCoreMesh*    coreMesh    = calCoreModel->getCoreMesh( hardwareMesh->meshId );
            CalCoreSubmesh* coreSubmesh = coreMesh->getCoreSubmesh( hardwareMesh->submeshId );
            // hardwareMesh->pCoreMaterial =
            //   coreModel->getCoreMaterial( coreSubmesh->getCoreMaterialThreadId() );
            char buf[ 1024 ];
            snprintf( buf, 1024,
                      "pCoreMaterial == NULL for mesh '%s' (mesh material id = %d), verify your mesh file data",
                      m->name.c_str(),
                      coreSubmesh->getCoreMaterialThreadId() );
            throw std::runtime_error( buf );
        }

        // -- Create index buffer --
        int indexesCount = faceCount * 3;
        int startIndex = calHardwareModel->getStartIndex();

        if ( indexesCount <= 0x100 )
        {
            m->indexBuffer = new osg::DrawElementsUByte( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLubyte* data = (GLubyte*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLubyte)*i++;
            }
        }
        else if ( indexesCount <= 0x10000 )
        {
            m->indexBuffer = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLushort* data = (GLushort*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLushort)*i++;
            }
        }
        else
        {
            m->indexBuffer = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLuint* data = (GLuint*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLuint)*i++;
            }
        }

        // -- Create other buffers --
        int vertexCount = calHardwareModel->getVertexCount();
        int baseVertexIndex = calHardwareModel->getBaseVertexIndex();

#define SUB_BUFFER( _type, _name )                                  \
        new _type( _name->begin() + baseVertexIndex,                \
                   _name->begin() + baseVertexIndex + vertexCount )
        
        m->vertexBuffer = SUB_BUFFER( VertexBuffer, vertexBuffer );
        m->weightBuffer = SUB_BUFFER( WeightBuffer, weightBuffer );
        m->matrixIndexBuffer = SUB_BUFFER( MatrixIndexBuffer, matrixIndexBuffer );
        m->normalBuffer = SUB_BUFFER( NormalBuffer, normalBuffer );
        m->texCoordBuffer = SUB_BUFFER( TexCoordBuffer, texCoordBuffer );

        // -- Parameters and buffers setup --
        m->boundingBox = calculateBoundingBox( m->vertexBuffer.get() );

        m->bonesIndices = hardwareMesh->m_vectorBonesIndices;

        checkRigidness( m.get(), unriggedBoneIndex );
        checkForEmptyTexCoord( m.get() );
        generateTangentAndHandednessBuffer( m.get(), &indexBuffer[ startIndex ] );

        meshes.push_back( m.get() );
    }
}
//------------------------------------------------------------------------------
static void
createVtrMesh(Shape * shape, int maxlevel) {

    Stopwatch s;
    s.Start();

    // create Vtr mesh (topology)
    OpenSubdiv::Sdc::Type       sdctype = GetSdcType(*shape);
    OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape);

    OpenSubdiv::Far::TopologyRefiner * refiner =
        OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape);

    OpenSubdiv::Far::PatchTables * patchTables = 0;

    if (g_Adaptive) {

        refiner->RefineAdaptive(maxlevel, /*fullTopology*/true);

        patchTables = OpenSubdiv::Far::PatchTablesFactory::Create(*refiner);

        g_numPatches = patchTables->GetNumPatches();
    } else {
        refiner->RefineUniform(maxlevel, /*fullTopology*/true);
    }
    s.Stop();

    // create vertex primvar data buffer
    std::vector<Vertex> vertexBuffer(refiner->GetNumVerticesTotal());
    Vertex * verts = &vertexBuffer[0];

    //printf("Vtr time: %f ms (topology)\n", float(s.GetElapsed())*1000.0f);

    // copy coarse vertices positions
    int ncoarseverts = shape->GetNumVertices();
    for (int i=0; i<ncoarseverts; ++i) {
        float * ptr = &shape->verts[i*3];
        verts[i].SetPosition(ptr[0], ptr[1], ptr[2]);
    }

//#define no_stencils
#ifdef no_stencils
    {
        s.Start();
        // populate buffer with Vtr interpolated vertex data
        refiner->Interpolate(verts, verts + ncoarseverts);
        s.Stop();
        //printf("          %f ms (interpolate)\n", float(s.GetElapsed())*1000.0f);
        //printf("          %f ms (total)\n", float(s.GetTotalElapsed())*1000.0f);
    }
#else
    {
        OpenSubdiv::Far::StencilTablesFactory::Options options;
        options.generateOffsets=true;
        options.generateAllLevels=true;
        options.sortBySize=false;

        OpenSubdiv::Far::StencilTables const * stencilTables =
            OpenSubdiv::Far::StencilTablesFactory::Create(*refiner, options);

        stencilTables->UpdateValues(verts, verts + ncoarseverts);
    }
#endif

    if (g_VtrDrawVertIDs) {
        createVertNumbers(*refiner, vertexBuffer);
    }

    if (g_VtrDrawFaceIDs) {
        createFaceNumbers(*refiner, vertexBuffer);
    }

    if (g_VtrDrawPtexIDs and patchTables) {
        createPtexNumbers(*patchTables, vertexBuffer);
    }

    if (g_Adaptive and patchTables) {
        createPatchNumbers(*patchTables, vertexBuffer);
    }

    createEdgeNumbers(*refiner, vertexBuffer, g_VtrDrawEdgeIDs!=0, g_VtrDrawEdgeSharpness!=0);

    GLMesh::Options options;
    options.vertColorMode=g_Adaptive ? GLMesh::VERTCOLOR_BY_LEVEL : GLMesh::VERTCOLOR_BY_SHARPNESS;
    options.edgeColorMode=g_Adaptive ? GLMesh::EDGECOLOR_BY_PATCHTYPE : GLMesh::EDGECOLOR_BY_SHARPNESS;
    options.faceColorMode=g_Adaptive ? GLMesh::FACECOLOR_BY_PATCHTYPE :GLMesh::FACECOLOR_SOLID;

    if (g_Adaptive) {
        g_vtr_glmesh.Initialize(options, *refiner, patchTables, (float *)&verts[0]);
        g_vtr_glmesh.SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);
    } else {
        g_vtr_glmesh.Initialize(options, *refiner, patchTables, (float *)&verts[0]);
        g_vtr_glmesh.SetDiffuseColor(0.75f, 0.9f, 1.0f, 1.0f);
    }


    //setFaceColors(*refiner);

    g_vtr_glmesh.InitializeDeviceBuffers();

    delete refiner;
    delete patchTables;
}
Esempio n. 9
0
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void FirstGeometryShader::onInitialization()
{
	// Call the base implementation
	IApplicationRenderer::onInitialization();

	// Get and check the renderer instance
	// -> Geometry shaders supported?
	Renderer::IRendererPtr renderer(getRenderer());
	if (nullptr != renderer && renderer->getCapabilities().maximumNumberOfGsOutputVertices)
	{
		// Create the buffer manager
		mBufferManager = renderer->createBufferManager();

		{ // Create the root signature
			// Setup
			Renderer::RootSignatureBuilder rootSignature;
			rootSignature.initialize(0, nullptr, 0, nullptr, Renderer::RootSignatureFlags::ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

			// Create the instance
			mRootSignature = renderer->createRootSignature(rootSignature);
		}

		// Vertex input layout
		const Renderer::VertexAttribute vertexAttributesLayout[] =
		{
			{ // Attribute 0
				// Data destination
				Renderer::VertexAttributeFormat::FLOAT_1,	// vertexAttributeFormat (Renderer::VertexAttributeFormat)
				"Position",									// name[32] (char)
				"POSITION",									// semanticName[32] (char)
				0,											// semanticIndex (uint32_t)
				// Data source
				0,											// inputSlot (uint32_t)
				0,											// alignedByteOffset (uint32_t)
				// Data source, instancing part
				0											// instancesPerElement (uint32_t)
			}
		};
		const Renderer::VertexAttributes vertexAttributes(glm::countof(vertexAttributesLayout), vertexAttributesLayout);

		{ // Create vertex array object (VAO)
			// Create the vertex buffer object (VBO)
			static const float VERTEX_POSITION[] =
			{			// Vertex ID
				42.0f	// 0
			};
			Renderer::IVertexBufferPtr vertexBuffer(mBufferManager->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));

			// Create vertex array object (VAO)
			// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
			// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
			// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
			//    reference of the used vertex buffer objects (VBO). If the reference counter of a
			//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
			const Renderer::VertexArrayVertexBuffer vertexArrayVertexBuffers[] =
			{
				{ // Vertex buffer 0
					vertexBuffer,	// vertexBuffer (Renderer::IVertexBuffer *)
					sizeof(float)	// strideInBytes (uint32_t)
				}
			};
			mVertexArray = mBufferManager->createVertexArray(vertexAttributes, glm::countof(vertexArrayVertexBuffers), vertexArrayVertexBuffers);
		}

		// Create the program: Decide which shader language should be used (for example "GLSL" or "HLSL")
		Renderer::IShaderLanguagePtr shaderLanguage(renderer->getShaderLanguage());
		if (nullptr != shaderLanguage)
		{
			// Create the program
			Renderer::IProgramPtr program;
			{
				// Get the shader source code (outsourced to keep an overview)
				const char *vertexShaderSourceCode = nullptr;
				const char *geometryShaderSourceCode = nullptr;
				const char *fragmentShaderSourceCode = nullptr;
				#include "FirstGeometryShader_GLSL_410.h"
				#include "FirstGeometryShader_HLSL_D3D10_D3D11_D3D12.h"
				#include "FirstGeometryShader_Null.h"

				// Create the program
				program = shaderLanguage->createProgram(
					*mRootSignature,
					vertexAttributes,
					shaderLanguage->createVertexShaderFromSourceCode(vertexAttributes, vertexShaderSourceCode),
					shaderLanguage->createGeometryShaderFromSourceCode(geometryShaderSourceCode, Renderer::GsInputPrimitiveTopology::POINTS, Renderer::GsOutputPrimitiveTopology::TRIANGLE_STRIP, 3),
					shaderLanguage->createFragmentShaderFromSourceCode(fragmentShaderSourceCode));
			}

			// Create the pipeline state object (PSO)
			if (nullptr != program)
			{
				Renderer::PipelineState pipelineState = Renderer::PipelineStateBuilder(mRootSignature, program, vertexAttributes);
				pipelineState.primitiveTopologyType = Renderer::PrimitiveTopologyType::POINT;
				mPipelineState = renderer->createPipelineState(pipelineState);
			}
		}

		// Since we're always submitting the same commands to the renderer, we can fill the command buffer once during initialization and then reuse it multiple times during runtime
		fillCommandBuffer();
	}
}
Esempio n. 10
0
void Renderer2::GenerateRoomBuffer()
{
    float h = 4.0f * m_surfaceSize.y / m_surfaceSize.x;
    
    vec3 roomVertices[] =
    {
        {-2.0f, -h / 2.0f, -4.0f},
        {2.0f, -h / 2.0f, -4.0f},
        {2.0f, h / 2.0f, -4.0f},
        {-2.0f, h / 2.0f, -4.0f},
        
        {-2.0f, -h / 2.0f, -10.0f},
        {2.0f, -h / 2.0f, -10.0f},
        {2.0f, h / 2.0f, -10.0f},
        {-2.0f, h / 2.0f, -10.0f}
    };
    
    GLushort roomIndices[] =
    {
        0, 4, 3,
        7, 3, 4,
        4, 5, 7,
        6, 7, 5,
        1, 2, 5,
        6, 5, 2,
        6, 2, 7,
        3, 7, 2,
        0, 1, 4,
        5, 4, 1
    };
    
    m_roomVertexCount = sizeof(roomIndices) / sizeof(roomIndices[0]);
    vector<RoomVertex> vertexBuffer(m_roomVertexCount);
    
    for (int i = 0; i < m_roomVertexCount; i += 3)
    {
        GLushort c = roomIndices[i];
        GLushort r = roomIndices[i + 1];
        GLushort l = roomIndices[i + 2];
        
        vec3 centerVertex = roomVertices[c];
        vec3 rightVertex = roomVertices[r];
        vec3 leftVertex = roomVertices[l];
        
        vec3 a(rightVertex.x - centerVertex.x,
               rightVertex.y - centerVertex.y,
               rightVertex.z - centerVertex.z);
        vec3 b(leftVertex.x - centerVertex.x,
               leftVertex.y - centerVertex.y,
               leftVertex.z - centerVertex.z);
        
        vec3 normal = a.Cross(b).Normalized();
        
        vertexBuffer[i].Position = centerVertex;
        vertexBuffer[i + 1].Position = rightVertex;
        vertexBuffer[i + 2].Position = leftVertex;
        
        vertexBuffer[i].Normal = normal;
        vertexBuffer[i + 1].Normal = normal;
        vertexBuffer[i + 2].Normal = normal;
    }
    
    glGenBuffers(1, &m_roomVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, m_roomVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertexBuffer.size() * sizeof(RoomVertex), &vertexBuffer[0], GL_STATIC_DRAW);
}
Esempio n. 11
0
bool Console::draw()
{
	int windowHeight = Ego::GraphicsSystem::window->getSize().height();

	if (!windowHeight || !this->on)
	{
		return false;
	}

	SDL_Rect *pwin = &(this->rect);

	auto& renderer = Renderer::get();
	renderer.getTextureUnit().setActivated(nullptr);

    // The colour white.
	static const auto white = Math::Colour4f::white();
    // The colour black.
	static const auto black = Math::Colour4f::black();
    // The vertex data structure and the vertex descriptor.
    struct Vertex { float x, y; };
    static const Ego::VertexDescriptor vertexDescriptor({Ego::VertexElementDescriptor(0, Ego::VertexElementDescriptor::Syntax::F2, Ego::VertexElementDescriptor::Semantics::Position)});


	renderer.setColour(white);
	renderer.setLineWidth(5);
    Ego::VertexBuffer vertexBuffer(4, vertexDescriptor);
    {
        Ego::BufferScopedLock lock(vertexBuffer);
        Vertex *vertex = lock.get<Vertex>();
        vertex->x = pwin->x;           vertex->y = pwin->y;           ++vertex;
        vertex->x = pwin->x + pwin->w; vertex->y = pwin->y;           ++vertex;
        vertex->x = pwin->x + pwin->w; vertex->y = pwin->y + pwin->h; ++vertex;
        vertex->x = pwin->x;           vertex->y = pwin->y + pwin->h;
    }
    renderer.render(vertexBuffer, Ego::PrimitiveType::LineLoop, 0, 4);
	renderer.setLineWidth(1);

	renderer.setColour(black);
    renderer.render(vertexBuffer, Ego::PrimitiveType::Quadriliterals, 0, 4);


    {
        Ego::OpenGL::PushAttrib pa(GL_SCISSOR_BIT | GL_ENABLE_BIT);
        {
            int textWidth, textHeight, height;

            // clip the viewport
            renderer.setScissorTestEnabled(true);
            renderer.setScissorRectangle(pwin->x, windowHeight - (pwin->y + pwin->h), pwin->w, pwin->h);

            height = pwin->h;

            char buffer[ConsoleSettings::InputSettings::Length];

            // draw the current command line
            sprintf(buffer, "%s ", ConsoleSettings::InputSettings::Prompt.c_str());

            strncat(buffer, this->buffer, 1022);
            buffer[1022] = CSTR_END;

            this->pfont->getTextSize(buffer, &textWidth, &textHeight);
            height -= textHeight;
            this->pfont->drawText(buffer, pwin->x, height - textHeight, white);

            if (CSTR_END != this->output_buffer[0]) {
                // grab the line offsets
                size_t console_line_count = 0;
                size_t console_line_offsets[1024];
                size_t console_line_lengths[1024];
                char *pstr = this->output_buffer;
                while (pstr) {
                    size_t len = strcspn(pstr, "\n");

                    console_line_offsets[console_line_count] = pstr - this->output_buffer;
                    console_line_lengths[console_line_count] = len;

                    if (0 == len) {
                        break;
                    }

                    pstr += len + 1;
                    console_line_count++;
                }

                // draw the last output line and work backwards
                for (size_t i = console_line_count; i >= 1 && height > 0; --i) {
                    size_t j = i - 1;
                    size_t len = std::min((size_t)1023, console_line_lengths[j]);

                    strncpy(buffer, this->output_buffer + console_line_offsets[j], len);
                    buffer[len] = CSTR_END;

                    this->pfont->getTextSize(buffer, &textWidth, &textHeight);
                    height -= textHeight;
                    this->pfont->drawText(buffer, pwin->x, height - textHeight, white);
                }
            }
        }
    }

	return true;
}
Esempio n. 12
0
int main()
{
	// first, create a vulkan instance
	// the needed/used instance extensions
	constexpr const char* iniExtensions[] = {
		VK_KHR_SURFACE_EXTENSION_NAME,
		VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
		VK_EXT_DEBUG_REPORT_EXTENSION_NAME
	};

	// enables all default layers
	constexpr auto layer = "VK_LAYER_LUNARG_standard_validation";

	// basic application info
	// we use vulkan api version 1.0
	vk::ApplicationInfo appInfo ("vpp-intro", 1, "vpp", 1, VK_API_VERSION_1_0);

	vk::InstanceCreateInfo instanceInfo;
	instanceInfo.pApplicationInfo = &appInfo;
	instanceInfo.enabledExtensionCount = sizeof(iniExtensions) / sizeof(iniExtensions[0]);
	instanceInfo.ppEnabledExtensionNames = iniExtensions;
	instanceInfo.enabledLayerCount = 1;
	instanceInfo.ppEnabledLayerNames = &layer;

	vpp::Instance instance(instanceInfo);

	// create a debug callback for our instance and the default layers
	// the default implementation will just output to std::cerr when a debug callback
	// is received
	vpp::DebugCallback debugCallback(instance);

	// this function will create a winapi window wrapper and also create a surface for it
	// this should usually be done by a cross platform window abstraction
	Window window(instance);

	// now create a device for the instance and surface
	// note how vpp will automatically select a suited physical device and query
	// queue families to create basic-needs queues with this constructor.
	// We also retrieve the present queue to present on our surface from this
	// constructor
	const vpp::Queue* presentQueue;
	vpp::Device device(instance, window.surface, presentQueue);

	// now we can create a vulkan swapchain
	// again, we just use the fast way that choses quite sane defaults for us but note
	// that the class offers many convininient configuration possibilities
	vpp::Swapchain swapchain(device, window.surface);

	// to render the triangle we also need to create a render pass
	vpp::RenderPass renderPass = createRenderPass(swapchain);

	// we also create the graphics pipeline that will render our triangle as well
	// as the buffer to hold our vertices
	vpp::PipelineLayout pipelineLayout(device, {});
	auto pipeline = createGraphicsPipeline(device, renderPass, pipelineLayout);

	// note how vpp takes care of buffer allocation (in an efficient way, even when used
	// for multiple resources)
	constexpr auto size = 3u * (2u + 4u) * 4u; // 3 vertices, vec2, vec4 with 4 bytes components
	constexpr auto usage = vk::BufferUsageBits::vertexBuffer | vk::BufferUsageBits::transferDst;
	vpp::Buffer vertexBuffer(device, {{}, size, usage});

	// vertex data (only positions and color)
	constexpr std::array<float, 6 * 3> vertexData = {{
		0.f, -0.75f,     1.f, 0.f, 0.f, 1.f, // top
		-0.75f, 0.75f,    0.f, 1.f, 0.f, 1.f, // left
		0.75f, 0.75f,    0.f, 0.f, 1.f, 1.f // right
	}};

	// vpp can now be used to fill the vertex buffer with data in the most efficient way
	// in this case the buffer layout does not matter since its a vertex buffer
	// note how vpp automatically unpacks the std::array
	vpp::fill140(vertexBuffer, vpp::raw(vertexData));

	// to render onto the created swapchain we can use vpp::SwapchainRenderer
	// the class implements the default framebuffer and commandbuffer handling
	// we simply implement the vpp::RendererBuilder interface that will be used
	// to build the render command buffers
	vpp::SwapchainRenderer::CreateInfo rendererInfo;
	rendererInfo.queueFamily = device.queue(vk::QueueBits::graphics)->family();
	rendererInfo.renderPass = renderPass;

	auto impl = std::make_unique<IntroRendererImpl>();
	impl->pipeline = pipeline;
	impl->vertexBuffer = vertexBuffer;

	vpp::SwapchainRenderer renderer(swapchain, rendererInfo, std::move(impl));
	renderer.record();

	// run the main loop
	// we just recevie windows events and render after all are processed
	// sry for windows again...
	using Clock = std::chrono::high_resolution_clock;
	auto frames = 0u;
	auto point = Clock::now();

	auto run = true;
	while(run) {
		MSG msg;
		while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) != 0) {
			if(msg.message == WM_QUIT) {
				run = false;
				break;
			} else {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}

		if(!run) break;
		renderer.renderBlock(*presentQueue);
		++frames;

		// output the average fps count ever second
		auto duration = Clock::now() - point;
		if(duration >= std::chrono::seconds(1)) {
			auto count = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
			std::cout << static_cast<int>(frames * (1000.0 / count)) << " fps\n";
			point = Clock::now();
			frames = 0u;
		}
	}

	return EXIT_SUCCESS;
}
//[-------------------------------------------------------]
//[ Public methods                                        ]
//[-------------------------------------------------------]
CubeRendererDrawInstanced::CubeRendererDrawInstanced(Renderer::IRenderer &renderer, unsigned int numberOfTextures, unsigned int sceneRadius) :
	mRenderer(&renderer),
	mNumberOfTextures(numberOfTextures),
	mSceneRadius(sceneRadius),
	mMaximumNumberOfInstancesPerBatch(0),
	mNumberOfBatches(0),
	mBatches(nullptr)
{
	// Begin debug event
	RENDERER_BEGIN_DEBUG_EVENT_FUNCTION(&renderer)

	// Check number of textures (limit of this implementation and renderer limit)
	if (mNumberOfTextures > MAXIMUM_NUMBER_OF_TEXTURES)
	{
		mNumberOfTextures = MAXIMUM_NUMBER_OF_TEXTURES;
	}
	if (mNumberOfTextures > mRenderer->getCapabilities().maximumNumberOf2DTextureArraySlices)
	{
		mNumberOfTextures = mRenderer->getCapabilities().maximumNumberOf2DTextureArraySlices;
	}

	// Get the maximum number of instances per batch
	// -> In this application, this depends on the maximum texture buffer size
	// -> /2 -> One instance requires two texels
	mMaximumNumberOfInstancesPerBatch = mRenderer->getCapabilities().maximumTextureBufferSize / 2;

	{ // Create the textures
		static const unsigned int TEXTURE_WIDTH   = 128;
		static const unsigned int TEXTURE_HEIGHT  = 128;
		static const unsigned int NUMBER_OF_BYTES = TEXTURE_WIDTH * TEXTURE_HEIGHT * 4;

		// Allocate memory for the 2D texture array
		unsigned char *data = new unsigned char[NUMBER_OF_BYTES * mNumberOfTextures];

		{ // Fill the texture content
			// TODO(co) Be a little bit more creative while filling the texture data
			unsigned char *dataCurrent = data;
			const float colors[][MAXIMUM_NUMBER_OF_TEXTURES] =
			{
				{ 1.0f, 0.0f, 0.0f},
				{ 0.0f, 0.1f, 0.0f},
				{ 0.0f, 0.0f, 0.1f},
				{ 0.5f, 0.5f, 0.5f},
				{ 1.0f, 1.0f, 1.0f},
				{ 0.1f, 0.2f, 0.2f},
				{ 0.2f, 0.5f, 0.5f},
				{ 0.1f, 0.8f, 0.2f}
			};
			for (unsigned int j = 0; j < mNumberOfTextures; ++j)
			{
				// Random content
				for (unsigned int i = 0; i < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++i)
				{
					*dataCurrent = static_cast<unsigned char>((rand() % 255) * colors[j][0]);
					++dataCurrent;
					*dataCurrent = static_cast<unsigned char>((rand() % 255) * colors[j][1]);
					++dataCurrent;
					*dataCurrent = static_cast<unsigned char>((rand() % 255) * colors[j][2]);
					++dataCurrent;
					*dataCurrent = 255;
					++dataCurrent;
				}
			}
		}

		// Create the texture instance
		// -> By using 2D array textures together with OpenGL/Direct3D 11 instancing we get a handy implementation
		// -> This limits of course the cross platform support, fallback solutions might be a good idea in productive code
		// -> A fallback is not really required in our example situation because we're using draw instanced which already requires a more modern graphics card
		mTexture2DArray = mRenderer->createTexture2DArray(TEXTURE_WIDTH, TEXTURE_HEIGHT, mNumberOfTextures, Renderer::TextureFormat::R8G8B8A8, data, Renderer::TextureFlag::MIPMAPS);

		// Free texture memory
		delete [] data;
	}

	// Create sampler state
	mSamplerState = mRenderer->createSamplerState(Renderer::ISamplerState::getDefaultSamplerState());

	// Decide which shader language should be used (for example "GLSL", "HLSL" or "Cg")
	Renderer::IShaderLanguagePtr shaderLanguage(mRenderer->getShaderLanguage());
	if (nullptr != shaderLanguage)
	{
		// Uniform buffer object (UBO, "constant buffer" in Direct3D terminology) supported?
		// -> If they are there, we really want to use them (performance and ease of use)
		if (mRenderer->getCapabilities().uniformBuffer)
		{
			{ // Create and set constant program uniform buffer at once
				// TODO(co) Uggly fixed hacked in model-view-projection matrix
				// TODO(co) OpenGL matrix, Direct3D has minor differences within the projection matrix we have to compensate
				static const float MVP[] =
				{
					 1.2803299f,	-0.97915620f,	-0.58038759f,	-0.57922798f,
					 0.0f,			 1.9776078f,	-0.57472473f,	-0.573576453f,
					-1.2803299f,	-0.97915620f,	-0.58038759f,	-0.57922798f,
					 0.0f,			 0.0f,			 9.8198195f,	 10.0f
				};
				mUniformBufferStaticVs = shaderLanguage->createUniformBuffer(sizeof(MVP), MVP, Renderer::BufferUsage::STATIC_DRAW);
			}

			// Create dynamic uniform buffers
			mUniformBufferDynamicVs = shaderLanguage->createUniformBuffer(sizeof(float) * 2, nullptr, Renderer::BufferUsage::DYNAMIC_DRAW);
			mUniformBufferDynamicFs = shaderLanguage->createUniformBuffer(sizeof(float) * 3, nullptr, Renderer::BufferUsage::DYNAMIC_DRAW);
		}

		{ // Create the program
			// Get the shader source code (outsourced to keep an overview)
			const char *vertexShaderSourceCode = nullptr;
			const char *fragmentShaderSourceCode = nullptr;
			#include "CubeRendererDrawInstanced_GLSL_140.h"
			#include "CubeRendererDrawInstanced_HLSL_D3D10_D3D11.h"
			#include "CubeRendererDrawInstanced_Null.h"

			// Create the program
			mProgram = shaderLanguage->createProgram(
				shaderLanguage->createVertexShader(vertexShaderSourceCode),
				shaderLanguage->createFragmentShader(fragmentShaderSourceCode));
		}

		// Is there a valid program?
		if (nullptr != mProgram)
		{
			// Create the vertex buffer object (VBO)
			static const float VERTEX_POSITION[] =
			{
				// Front face
				// Position					TexCoord		 Normal				// Vertex ID
				-0.5f, -0.5f,  0.5f,		0.0f, 0.0f,		 0.0f, 0.0f, 1.0f,	// 0
				 0.5f, -0.5f,  0.5f,		1.0f, 0.0f,		 0.0f, 0.0f, 1.0f,	// 1
				 0.5f,  0.5f,  0.5f,		1.0f, 1.0f,		 0.0f, 0.0f, 1.0f,	// 2
				-0.5f,  0.5f,  0.5f,		0.0f, 1.0f,		 0.0f, 0.0f, 1.0f,	// 3
				// Back face
				-0.5f, -0.5f, -0.5f,		1.0f, 0.0f,		 0.0f, 0.0f,-1.0f,	// 4
				-0.5f,  0.5f, -0.5f,		1.0f, 1.0f,		 0.0f, 0.0f,-1.0f,	// 5
				 0.5f,  0.5f, -0.5f,		0.0f, 1.0f,		 0.0f, 0.0f,-1.0f, 	// 6
				 0.5f, -0.5f, -0.5f,		0.0f, 0.0f,		 0.0f, 0.0f,-1.0f,	// 7
				// Top face
				-0.5f,  0.5f, -0.5f,		0.0f, 1.0f,		 0.0f, 1.0f, 0.0f,	// 8
				-0.5f,  0.5f,  0.5f,		0.0f, 0.0f,		 0.0f, 1.0f, 0.0f,	// 9
				 0.5f,  0.5f,  0.5f,		1.0f, 0.0f,		 0.0f, 1.0f, 0.0f,	// 10
				 0.5f,  0.5f, -0.5f,		1.0f, 1.0f,		 0.0f, 1.0f, 0.0f,	// 11
				// Bottom face
				-0.5f, -0.5f, -0.5f,		1.0f, 1.0f,		 0.0f,-1.0f, 0.0f,	// 12
				 0.5f, -0.5f, -0.5f,		0.0f, 1.0f,		 0.0f,-1.0f, 0.0f,	// 13
				 0.5f, -0.5f,  0.5f,		0.0f, 0.0f,		 0.0f,-1.0f, 0.0f,	// 14
				-0.5f, -0.5f,  0.5f,		1.0f, 0.0f,		 0.0f,-1.0f, 0.0f,	// 15
				// Right face
				 0.5f, -0.5f, -0.5f,		1.0f, 0.0f,		 1.0f, 0.0f, 0.0f,	// 16
				 0.5f,  0.5f, -0.5f,		1.0f, 1.0f,		 1.0f, 0.0f, 0.0f,	// 17
				 0.5f,  0.5f,  0.5f,		0.0f, 1.0f,		 1.0f, 0.0f, 0.0f,	// 18
				 0.5f, -0.5f,  0.5f,		0.0f, 0.0f,		 1.0f, 0.0f, 0.0f,	// 19
				// Left face
				-0.5f, -0.5f, -0.5f,		0.0f, 0.0f,		-1.0f, 0.0f, 0.0f,	// 20
				-0.5f, -0.5f,  0.5f,		1.0f, 0.0f,		-1.0f, 0.0f, 0.0f,	// 21
				-0.5f,  0.5f,  0.5f,		1.0f, 1.0f,		-1.0f, 0.0f, 0.0f,	// 22
				-0.5f,  0.5f, -0.5f,		0.0f, 1.0f,		-1.0f, 0.0f, 0.0f	// 23
			};
			Renderer::IVertexBufferPtr vertexBuffer(mRenderer->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));

			// Create the index buffer object (IBO)
			static const unsigned short INDICES[] =
			{
				// Front face	Triangle ID
				 1,  0,  2,		// 0
				 3,  2,  0,		// 1
				// Back face
				 6,  5,  4,		// 2
				 4,  7,  6,		// 3
				// Top face
				 9,  8, 10,		// 4
				11, 10,  8,		// 5
				// Bottom face
				13, 12, 14,		// 6
				15, 14, 12,		// 7
				// Right face
				17, 16, 18,		// 8
				19, 18, 16,		// 9
				// Left face
				21, 20, 22,		// 10
				23, 22, 20		// 11
			};
			Renderer::IIndexBuffer *indexBuffer = mRenderer->createIndexBuffer(sizeof(INDICES), Renderer::IndexBufferFormat::UNSIGNED_SHORT, INDICES, Renderer::BufferUsage::STATIC_DRAW);

			// Create vertex array object (VAO)
			// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
			// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
			// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
			//    reference of the used vertex buffer objects (VBO). If the reference counter of a
			//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
			const Renderer::VertexArrayAttribute vertexArray[] =
			{
				{ // Attribute 0
					// Data destination
					Renderer::VertexArrayFormat::FLOAT_3,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
					"Position",								// name[64] (char)
					"POSITION",								// semantic[64] (char)
					0,										// semanticIndex (unsigned int)
					// Data source
					vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
					0,										// offset (unsigned int)
					sizeof(float) * (3 + 2 + 3),			// stride (unsigned int)
					// Data source, instancing part
					0										// instancesPerElement (unsigned int)
				},
				{ // Attribute 1
					// Data destination
					Renderer::VertexArrayFormat::FLOAT_2,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
					"TexCoord",								// name[64] (char)
					"TEXCOORD",								// semantic[64] (char)
					0,										// semanticIndex (unsigned int)
					// Data source
					vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
					sizeof(float) * 3,						// offset (unsigned int)
					sizeof(float) * (3 + 2 + 3),			// stride (unsigned int)
					// Data source, instancing part
					0										// instancesPerElement (unsigned int)
				},
				{ // Attribute 2
					// Data destination
					Renderer::VertexArrayFormat::FLOAT_3,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
					"Normal",								// name[64] (char)
					"NORMAL",								// semantic[64] (char)
					0,										// semanticIndex (unsigned int)
					// Data source
					vertexBuffer,							// pertexBuffer (Renderer::IVertexBuffer *)
					sizeof(float) * (3 + 2),				// offset (unsigned int)
					sizeof(float) * (3 + 2 + 3),			// stride (unsigned int)
					// Data source, instancing part
					0										// instancesPerElement (unsigned int)
				}
			};
			mVertexArray = mProgram->createVertexArray(sizeof(vertexArray) / sizeof(Renderer::VertexArrayAttribute), vertexArray, indexBuffer);
		}
	}

	// End debug event
	RENDERER_END_DEBUG_EVENT(&renderer)
}
std::vector<AnimatedVertex> ModelBinaryLoader::readVertexBufferAnimation(int p_NumberOfVertex, std::istream* p_Input)
{
	std::vector<AnimatedVertex> vertexBuffer(p_NumberOfVertex);
	p_Input->read(reinterpret_cast<char*>(vertexBuffer.data()), sizeof(AnimatedVertex) * p_NumberOfVertex);
	return vertexBuffer;
}
Esempio n. 15
0
void Font::read(const void * data, size_t size) {
  std::istringstream in(std::string(static_cast<const char*>(data), size));
//  SignedDistanceFontFile sdff;
//  sdff.read(in);

  uint8_t header[4];
  readStream(in, header);
  if (memcmp(header, "SDFF", 4)) {
    FAIL("Bad font file");
  }

  uint16_t version;
  readStream(in, version);

  // read font name
  if (version > 0x0001) {
    char c;
    readStream(in, c);
    while (c) {
      mFamily += c;
      readStream(in, c);
    }
  }

  // read font data
  readStream(in, mLeading);
  readStream(in, mAscent);
  readStream(in, mDescent);
  readStream(in, mSpaceWidth);
  mFontSize = mAscent + mDescent;

  // read metrics data
  mMetrics.clear();

  uint16_t count;
  readStream(in, count);

  for (int i = 0; i < count; ++i) {
    uint16_t charcode;
    readStream(in, charcode);
    Metrics & m = mMetrics[charcode];
    readStream(in, m.ul.x);
    readStream(in, m.ul.y);
    readStream(in, m.size.x);
    readStream(in, m.size.y);
    readStream(in, m.offset.x);
    readStream(in, m.offset.y);
    readStream(in, m.d);
    m.lr = m.ul + m.size;
  }

  // read image data
  readPngToTexture((const char *) data + in.tellg(), size - in.tellg(),
      mTexture, mTextureSize);

  std::vector<TextureVertex> vertexData;
  std::vector<GLuint> indexData;
  float texH = 0, texW = 0, texA = 0;
  int characters = 0;
  std::for_each(mMetrics.begin(), mMetrics.end(),
      [&] ( MetricsData::reference & md ) {
        uint16_t id = md.first;
        Font::Metrics & m = md.second;
        ++characters;
        GLuint index = (GLuint)vertexData.size();
        rectf bounds = getBounds(m, mFontSize);
        rectf texBounds = getTexCoords(m);

        QuadBuilder qb(bounds, texBounds);
        for (int i = 0; i < 4; ++i) {
          vertexData.push_back(qb.vertices[i]);
        }

        m.indexOffset = indexData.size();
        indexData.push_back(index + 0);
        indexData.push_back(index + 1);
        indexData.push_back(index + 2);
        indexData.push_back(index + 0);
        indexData.push_back(index + 2);
        indexData.push_back(index + 3);
      });

  gl::VertexBufferPtr vertexBuffer(new gl::VertexBuffer(vertexData));
  gl::IndexBufferPtr indexBuffer(new gl::IndexBuffer(indexData));
  mGeometry = gl::GeometryPtr(
      new gl::Geometry(vertexBuffer, indexBuffer, characters * 2,
          gl::Geometry::Flag::HAS_TEXTURE));
  mGeometry->buildVertexArray();
}
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void IcosahedronTessellation::onInitialization()
{
	// Call the base implementation
	IApplicationRenderer::onInitialization();

	// Get and check the renderer instance
	// -> Uniform buffer object (UBO, "constant buffer" in Direct3D terminology) supported?
	// -> Geometry shaders supported?
	// -> Tessellation control and tessellation evaluation shaders supported?
	Renderer::IRendererPtr renderer(getRenderer());
	if (nullptr != renderer && renderer->getCapabilities().uniformBuffer && renderer->getCapabilities().maximumNumberOfGsOutputVertices > 0 && renderer->getCapabilities().maximumNumberOfPatchVertices > 0)
	{
		// Begin debug event
		RENDERER_BEGIN_DEBUG_EVENT_FUNCTION(renderer)

		// Decide which shader language should be used (for example "GLSL", "HLSL" or "Cg")
		Renderer::IShaderLanguagePtr shaderLanguage(renderer->getShaderLanguage());
		if (nullptr != shaderLanguage)
		{
			// Create uniform buffers and fill the static buffers at once
			mUniformBufferDynamicTcs = shaderLanguage->createUniformBuffer(sizeof(float) * 2, nullptr, Renderer::BufferUsage::DYNAMIC_DRAW);
			{	// "ObjectSpaceToClipSpaceMatrix"
				// TODO(co) Cleanup, correct aspect ratio
				glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -3.0f));
				glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f));
				glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.001f, 1000.0f);
				glm::mat4 MVP = Projection * View; 
//				glm::mat4 MVP = Projection * View * Model; 
				mUniformBufferStaticTes = shaderLanguage->createUniformBuffer(sizeof(float) * 4 * 4, glm::value_ptr(MVP), Renderer::BufferUsage::STATIC_DRAW);
				{	// "NormalMatrix"

					View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
					Model = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f));
					Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.001f, 1000.0f);
					MVP = Projection * View; 
					glm::mat3 nMVP(MVP);
					glm::mat4 tMVP(nMVP);
					mUniformBufferStaticGs = shaderLanguage->createUniformBuffer(sizeof(float) * 4 * 4, glm::value_ptr(tMVP), Renderer::BufferUsage::STATIC_DRAW);
				}
			}
			{ // Light and material
				static const float LIGHT_AND_MATERIAL[] =
				{
					0.25f, 0.25f, 1.0f, 1.0,	// "LightPosition"
					 0.0f, 0.75f, 0.75f,1.0, 	// "DiffuseMaterial"
					0.04f, 0.04f, 0.04f,1.0,	// "AmbientMaterial"
				};
				mUniformBufferStaticFs = shaderLanguage->createUniformBuffer(sizeof(LIGHT_AND_MATERIAL), LIGHT_AND_MATERIAL, Renderer::BufferUsage::STATIC_DRAW);
			}

			{ // Create the program
				// Get the shader source code (outsourced to keep an overview)
				const char *vertexShaderSourceCode = nullptr;
				const char *tessellationControlShaderSourceCode = nullptr;
				const char *tessellationEvaluationShaderSourceCode = nullptr;
				const char *geometryShaderSourceCode = nullptr;
				const char *fragmentShaderSourceCode = nullptr;
				#include "IcosahedronTessellation_GLSL_400.h"
				#include "IcosahedronTessellation_HLSL_D3D11.h"
				#include "IcosahedronTessellation_Null.h"

				// Create the program
				mProgram = shaderLanguage->createProgram(
					shaderLanguage->createVertexShader(vertexShaderSourceCode),
					shaderLanguage->createTessellationControlShader(tessellationControlShaderSourceCode),
					shaderLanguage->createTessellationEvaluationShader(tessellationEvaluationShaderSourceCode),
					shaderLanguage->createGeometryShader(geometryShaderSourceCode, Renderer::GsInputPrimitiveTopology::TRIANGLES, Renderer::GsOutputPrimitiveTopology::TRIANGLE_STRIP, 3),
					shaderLanguage->createFragmentShader(fragmentShaderSourceCode));
			}

			// Is there a valid program?
			if (nullptr != mProgram)
			{
				// Create the vertex buffer object (VBO)
				// -> Geometry is from: http://prideout.net/blog/?p=48 (Philip Rideout, "The Little Grasshopper - Graphics Programming Tips")
				static const float VERTEX_POSITION[] =
				{								// Vertex ID
					 0.000f,  0.000f,  1.000f,	// 0
					 0.894f,  0.000f,  0.447f,	// 1
					 0.276f,  0.851f,  0.447f,	// 2
					-0.724f,  0.526f,  0.447f,	// 3
					-0.724f, -0.526f,  0.447f,	// 4
					 0.276f, -0.851f,  0.447f,	// 5
					 0.724f,  0.526f, -0.447f,	// 6
					-0.276f,  0.851f, -0.447f,	// 7
					-0.894f,  0.000f, -0.447f,	// 8
					-0.276f, -0.851f, -0.447f,	// 9
					 0.724f, -0.526f, -0.447f,	// 10
					 0.000f,  0.000f, -1.000f	// 11
				};
				Renderer::IVertexBufferPtr vertexBuffer(renderer->createVertexBuffer(sizeof(VERTEX_POSITION), VERTEX_POSITION, Renderer::BufferUsage::STATIC_DRAW));

				// Create the index buffer object (IBO)
				// -> Geometry is from: http://prideout.net/blog/?p=48 (Philip Rideout, "The Little Grasshopper - Graphics Programming Tips")
				static const unsigned short INDICES[] =
				{				// Triangle ID
					 2,  1,  0,	// 0
					 3,  2,  0,	// 1
					 4,  3,  0,	// 2
					 5,  4,  0,	// 3
					 1,  5,  0,	// 4
					11,  6,  7,	// 5
					11,  7,  8,	// 6
					11,  8,  9,	// 7
					11,  9, 10,	// 8
					11, 10,  6,	// 9
					 1,  2,  6,	// 10
					 2,  3,  7,	// 11
					 3,  4,  8,	// 12
					 4,  5,  9,	// 13
					 5,  1, 10,	// 14
					 2,  7,  6,	// 15
					 3,  8,  7,	// 16
					 4,  9,  8,	// 17
					 5, 10,  9,	// 18
					 1,  6, 10	// 19
				};
				Renderer::IIndexBuffer *indexBuffer = renderer->createIndexBuffer(sizeof(INDICES), Renderer::IndexBufferFormat::UNSIGNED_SHORT, INDICES, Renderer::BufferUsage::STATIC_DRAW);

				// Create vertex array object (VAO)
				// -> The vertex array object (VAO) keeps a reference to the used vertex buffer object (VBO)
				// -> This means that there's no need to keep an own vertex buffer object (VBO) reference
				// -> When the vertex array object (VAO) is destroyed, it automatically decreases the
				//    reference of the used vertex buffer objects (VBO). If the reference counter of a
				//    vertex buffer object (VBO) reaches zero, it's automatically destroyed.
				const Renderer::VertexArrayAttribute vertexArray[] =
				{
					{ // Attribute 0
						// Data destination
						Renderer::VertexArrayFormat::FLOAT_3,	// vertexArrayFormat (Renderer::VertexArrayFormat::Enum)
						"Position",								// name[64] (char)
						"POSITION",								// semantic[64] (char)
						0,										// semanticIndex (unsigned int)
						// Data source
						vertexBuffer,							// vertexBuffer (Renderer::IVertexBuffer *)
						0,										// offset (unsigned int)
						sizeof(float) * 3,						// stride (unsigned int)
						// Data source, instancing part
						0										// instancesPerElement (unsigned int)
					}
				};
				mVertexArray = mProgram->createVertexArray(sizeof(vertexArray) / sizeof(Renderer::VertexArrayAttribute), vertexArray, indexBuffer);
			}
		}

		// End debug event
		RENDERER_END_DEBUG_EVENT(renderer)
	}