void multidrawindirect_app::render(double currentTime)
{
    int j;
    static const float one = 1.0f;
    static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };

        
    static double last_time = 0.0;
    static double total_time = 0.0;

    if (!paused)
        total_time += (currentTime - last_time);
    last_time = currentTime;

    float t = float(total_time);
    int i = int(total_time * 3.0f);

    glViewport(0, 0, info.windowWidth, info.windowHeight);
    glClearBufferfv(GL_COLOR, 0, black);
    glClearBufferfv(GL_DEPTH, 0, &one);

    const vmath::mat4 view_matrix = vmath::lookat(vmath::vec3(100.0f * cosf(t * 0.023f), 100.0f * cosf(t * 0.023f), 300.0f * sinf(t * 0.037f) - 600.0f),
                                                  vmath::vec3(0.0f, 0.0f, 260.0f),
                                                  vmath::normalize(vmath::vec3(0.1f - cosf(t * 0.1f) * 0.3f, 1.0f, 0.0f)));
    const vmath::mat4 proj_matrix = vmath::perspective(50.0f,
                                                       (float)info.windowWidth / (float)info.windowHeight,
                                                       1.0f,
                                                       2000.0f);

    glUseProgram(render_program);

    glUniform1f(uniforms.time, t);
    glUniformMatrix4fv(uniforms.view_matrix, 1, GL_FALSE, view_matrix);
    glUniformMatrix4fv(uniforms.proj_matrix, 1, GL_FALSE, proj_matrix);
    glUniformMatrix4fv(uniforms.viewproj_matrix, 1, GL_FALSE, proj_matrix * view_matrix);

    glBindVertexArray(object.get_vao());

    if (mode == MODE_MULTIDRAW)
    {
        glMultiDrawArraysIndirect(GL_TRIANGLES, NULL, NUM_DRAWS, 0);
    }
    else if (mode == MODE_SEPARATE_DRAWS)
    {
        for (j = 0; j < NUM_DRAWS; j++)
        {
            GLuint first, count;
            object.get_sub_object_info(j % object.get_sub_object_count(), first, count);
            glDrawArraysInstancedBaseInstance(GL_TRIANGLES,
                                              first,
                                              count,
                                              1, j);
        }
    }
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		static int FrameIndex = 0;

		// Bind shared objects
		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);
		glBindSampler(0, SamplerName);
		glBindVertexArray(VertexArrayName);

		// Update a colorbuffer bound as a framebuffer attachement and as a texture
		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
		glBindProgramPipeline(PipelineName[pipeline::UPDATE]);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, FrameIndex ? TextureName[texture::COLORBUFFER] : TextureName[texture::DIFFUSE]);

		glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0);

		// Blit to framebuffer
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glBindProgramPipeline(PipelineName[pipeline::BLIT]);
	
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]);

		glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0);

		FrameIndex = (FrameIndex + 1) % 256;

		return true;
	}
void display()
{
	glViewportIndexedf(0, 0, 0, float(Window.Size.x), float(Window.Size.y));
	glDrawBuffer(GL_BACK);
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.5f, 1.0f, 1.0f)[0]);

	// Renderer to image
	{
		glDrawBuffer(GL_NONE);

		glBindProgramPipeline(PipelineName[pipeline::SAVE]);
		glBindImageTexture(glf::semantic::image::DIFFUSE, TextureName, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
		glBindVertexArray(VertexArrayName);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);
	}

	// Read from image
	{
		GLint Border(8);
		glEnable(GL_SCISSOR_TEST);
		glScissorIndexed(0, Border, Border, Window.Size.x - 2 * Border, Window.Size.y - 2 * Border);

		glDrawBuffer(GL_BACK);

		glBindProgramPipeline(PipelineName[pipeline::READ]);
		glBindImageTexture(glf::semantic::image::DIFFUSE, TextureName, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
		glBindVertexArray(VertexArrayName);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		glDisable(GL_SCISSOR_TEST);
	}

	glf::swapBuffers();
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());
		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);

		glBindVertexArray(this->VertexArrayName);
		glBindSampler(0, this->SamplerName);

		// Render
		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]);

		glBindProgramPipeline(PipelineName[pipeline::RENDER]);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::DIFFUSE]);
		glBindImageTexture(semantic::image::DIFFUSE, TextureName[texture::COLORBUFFER], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		// Splash
		glBindFramebuffer(GL_FRAMEBUFFER, 0);

		glBindProgramPipeline(PipelineName[pipeline::SPLASH]);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		return true;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);
		glDrawBuffer(GL_BACK);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.5f, 1.0f, 1.0f)[0]);

		// Renderer to image
		{
			glDrawBuffer(GL_NONE);

			glBindProgramPipeline(PipelineName[pipeline::SAVE]);
			glBindImageTexture(semantic::image::DIFFUSE, TextureName, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
			glBindVertexArray(VertexArrayName);
			glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);
		}

		// Read from image
		{
			glDrawBuffer(GL_BACK);

			glBindProgramPipeline(PipelineName[pipeline::READ]);
			glBindImageTexture(semantic::image::DIFFUSE, TextureName, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
			glBindVertexArray(VertexArrayName);
			glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);
		}

		return true;
	}
bool testDrawArrays::render()
{
	glm::vec2 const WindowSize(this->getWindowSize());

	float Depth(1.0f);
	glClearBufferfv(GL_DEPTH, 0, &Depth);
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f)[0]);

	{
		glBindBuffer(GL_UNIFORM_BUFFER, this->BufferName[buffer::BUFFER_FRAME]);
		glm::mat4* Pointer = reinterpret_cast<glm::mat4*>(glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));

		glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 1000.0f);
		glm::mat4 View = this->view();
		glm::mat4 Model = glm::mat4(1.0f);
		glm::mat4 MVP = Projection * View * Model;

		*Pointer = Projection * View * Model;
		glUnmapBuffer(GL_UNIFORM_BUFFER);
	}

	glViewportIndexedfv(0, &glm::vec4(0, 0, WindowSize)[0]);

	this->beginTimer();
	switch(this->DrawType)
	{
	case INSTANCED:
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, static_cast<GLsizei>(DrawCount), 0);
		break;
	case MULTI_DISCARD:
	case MULTI_DRAW:
		for(int i = 0; i < 2; ++i)
			glMultiDrawArraysIndirect(GL_TRIANGLES, 0, static_cast<GLsizei>(DrawCount / 2), 0);
		break;
	case DRAW_PACKED:
		for(std::size_t DrawIndex(0); DrawIndex < DrawCount; ++DrawIndex)
		{
			if(this->UniformUpdate != testDrawArrays::CONSTANT_UNIFORM && this->UniformUpdate != testDrawArrays::NO_UNIFORM)
				::updateUniform(this->ProgramName, DrawIndex, this->UniformUpdate);
			glDrawArrays(GL_TRIANGLES, static_cast<GLint>(this->VertexDataType == SEPARATED_VERTEX_DATA ? VertexCount * DrawIndex : 0), VertexCount);
		}
		break;
	case DRAW_PARAMS:
		for(std::size_t DrawIndex(0); DrawIndex < DrawCount; ++DrawIndex)
		{
			if(this->UniformUpdate != testDrawArrays::CONSTANT_UNIFORM && this->UniformUpdate != testDrawArrays::NO_UNIFORM)
				::updateUniform(this->ProgramName, DrawIndex, this->UniformUpdate);
			glDrawArraysInstancedBaseInstance(GL_TRIANGLES, static_cast<GLint>(this->VertexDataType == SEPARATED_VERTEX_DATA ? VertexCount * DrawIndex : 0), VertexCount, 1, 0);
		}
		break;
	default:
		assert(0);
		break;
	}
	this->endTimer();

	return true;
}
void resolveMultisampling()
{
	{
		glm::mat4* Pointer = (glm::mat4*)glMapNamedBufferRangeGTC(
			BufferName[buffer::BLIT], 0, sizeof(glm::mat4),
			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);

		glm::mat4 Perspective = glm::perspective(45.0f, float(Window.Size.x) / Window.Size.y, 0.1f, 100.0f);
		glm::mat4 ViewFlip = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f,-1.0f, 1.0f));
		glm::mat4 ViewTranslate = glm::translate(ViewFlip, glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y * 2.0));
		glm::mat4 View = glm::rotate(ViewTranslate,-15.f, glm::vec3(0.f, 0.f, 1.f));
		glm::mat4 Model = glm::mat4(1.0f);
		glm::mat4 MVP = Perspective * View * Model;

		*Pointer = MVP;
		glUnmapNamedBufferGTC(BufferName[buffer::BLIT]);
		//glNamedBufferSubDataEXT(BufferName[buffer::BLIT], 0, sizeof(glm::mat4), &MVP[0][0]);
	}

	glViewportIndexedf(0, 0, 0, float(Window.Size.x), float(Window.Size.y));
	glEnable(GL_SCISSOR_TEST);
	glBindNamedTextureLevelGTC(GL_FRAMEBUFFER, 0, 0, 0);

	glBindNamedBufferGTC(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::BLIT]);
	glBindNamedTextureGTC(GL_TEXTURE, 0, TextureName[texture::MULTISAMPLE]);
	glBindNamedSamplerGTC(0, SamplerName);
	glBindNamedVertexArrayGTC(VertexArrayName);

	// Box
	{
		glScissorIndexed(0, 1, 1, Window.Size.x  / 2 - 2, Window.Size.y - 2);
		glBindNamedProgramPipelineGTC(PipelineName[program::RESOLVE_BOX]);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 5, 0);
	}

	// Near
	{
		glScissorIndexed(0, Window.Size.x / 2 + 1, 1, Window.Size.x / 2 - 2, Window.Size.y - 2);
		glBindNamedProgramPipelineGTC(PipelineName[program::RESOLVE_NEAR]);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 5, 0);
	}

	//glBindImageBaseGTC(GL_READ_FRAMEBUFFER, glf::semantic::renderbuffer::COLOR0, TextureName[texture::MULTISAMPLE], 0);
	//glBindImageBaseGTC(GL_READ_FRAMEBUFFER, glf::semantic::renderbuffer::DEPTH, TextureName[texture::DEPTH], 0);
	//glBindImageBaseGTC(GL_DRAW_FRAMEBUFFER, glf::semantic::renderbuffer::COLOR0, 0, 0);
	//glBlitFramebuffer(
	//	0, 0, FRAMEBUFFER_SIZE.x, FRAMEBUFFER_SIZE.y, 
	//	0, 0, FRAMEBUFFER_SIZE.x, FRAMEBUFFER_SIZE.y, 
	//	GL_COLOR_BUFFER_BIT, GL_NEAREST);

	glDisable(GL_SCISSOR_TEST);

	glf::checkError("renderFB");
}
	bool render()
	{
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

		glm::vec2 WindowSize(this->getWindowSize());
		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
				GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4),
				GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			*Pointer = Projection * this->view() * glm::mat4(1.0f);

			// Make sure the uniform buffer is uploaded
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glViewportIndexedfv(0, &glm::vec4(0, 0, WindowSize)[0]);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f)[0]);

		glBindProgramPipeline(PipelineName);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindVertexArray(VertexArrayName);
		glPatchParameteri(GL_PATCH_VERTICES, VertexCount);

		assert(!validate(ProgramName[program::VERT]));
		glDrawArraysInstancedBaseInstance(GL_PATCHES, 0, VertexCount, 1, 0);

		return true;
	}
void display()
{
	{
		// Compute the MVP (Model View Projection matrix)
		glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
		glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y));
		glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
		glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f));
		glm::mat4 Model = glm::mat4(1.0f);
		glm::mat4 MVP = Projection * View * Model;

		glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
		glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(MVP), GL_MAP_WRITE_BIT);
		*Pointer = MVP;
		glUnmapBuffer(GL_UNIFORM_BUFFER);
	}

	glViewportIndexedfv(0, &glm::vec4(0, 0, Window.Size.x, Window.Size.y)[0]);
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]);

	glBindProgramPipeline(PipelineName);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Texture2DName);
	glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
	glBindVertexArray(VertexArrayName);

	glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, glf::semantic::attr::POSITION, Address, VertexSize);
	glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, glf::semantic::attr::TEXCOORD, Address + sizeof(glm::vec2), VertexSize - sizeof(glm::vec2));

	glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0);

	glf::swapBuffers();
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glm::mat4 Model = glm::mat4(1.0f);
			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			glm::mat4 MVP = Projection * this->view() * Model;

			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(MVP), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
			*Pointer = MVP;
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glViewportIndexedfv(0, &glm::vec4(0, 0, WindowSize.x, WindowSize.y)[0]);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]);

		glBindProgramPipeline(PipelineName);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::COPY]);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindVertexArray(VertexArrayName);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0);

		return true;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
				GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4),
				GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			//glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, 640.f, 480.f, 0.1f, 100.0f);
			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
		
			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glBindProgramPipeline(PipelineName[pipeline::SPLASH]);
		glActiveTexture(GL_TEXTURE0);
		glBindVertexArray(VertexArrayName);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::DIFFUSE]);
		glBindSampler(0, SamplerName);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		return true;
	}
void display()
{
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
	glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y));
	glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
	glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f));
	glm::mat4 Model = glm::mat4(1.0f);
	glm::mat4 MVP = Projection * View * Model;

	glProgramUniformMatrix4fv(ProgramName[program::VERT], UniformMVP, 1, GL_FALSE, &MVP[0][0]);

	glViewportIndexedfv(0, &glm::vec4(0, 0, Window.Size)[0]);
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f)[0]);

	glBindProgramPipeline(PipelineName);

	glBindVertexArray(VertexArrayName);
	glPatchParameteri(GL_PATCH_VERTICES, VertexCount);

	assert(!validate(ProgramName[program::VERT]));
	glDrawArraysInstancedBaseInstance(GL_PATCHES, 0, VertexCount, 1, 0);

	glf::swapBuffers();
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
				GL_UNIFORM_BUFFER, 0,	sizeof(glm::mat4),
				GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
		
			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f)[0]);

		glUseProgram(ProgramName);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D_ARRAY, TextureName);
		glBindSampler(0, SamplerName);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);

		glBindVertexArray(VertexArrayName);
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 15, 0);

		return true;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

		glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
		glm::mat4 Model = glm::mat4(1.0f);
		glm::mat4 MVP = Projection * this->view() * Model;

		glProgramUniformMatrix4fv(ProgramName[program::VERT], UniformMVP, 1, GL_FALSE, &MVP[0][0]);

		glViewportIndexedfv(0, &glm::vec4(0, 0, WindowSize)[0]);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f)[0]);

		glBindProgramPipeline(PipelineName);

		glBindVertexArray(VertexArrayName);
		glPatchParameteri(GL_PATCH_VERTICES, VertexCount);

		assert(!validate(ProgramName[program::VERT]));
		glDrawArraysInstancedBaseInstance(GL_PATCHES, 0, VertexCount, 1, 0);

		return true;
	}
void display()
{
	// Update of the uniform buffer
	{
		glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
		glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
			GL_UNIFORM_BUFFER, 0,	sizeof(glm::mat4),
			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

		glm::mat4 Projection = glm::perspectiveFov(45.f, 640.f, 480.f, 0.1f, 100.0f);
		//glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
		glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y));
		glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
		glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f));
		glm::mat4 Model = glm::mat4(1.0f);
		
		*Pointer = Projection * View * Model;

		// Make sure the uniform buffer is uploaded
		glUnmapBuffer(GL_UNIFORM_BUFFER);
	}

	glViewportIndexedf(0, 0, 0, float(Window.Size.x), float(Window.Size.y));
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)[0]);

	glBindProgramPipeline(PipelineName);
	glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
	glBindVertexArray(VertexArrayName);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, BufferName[buffer::VERTEX]);

	glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 6, 1, 0);

	glf::swapBuffers();
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER,
				0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, WindowSize.x, WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
		
			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)[0]);

		glBindProgramPipeline(PipelineName);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindVertexArray(VertexArrayName);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, BufferName[buffer::VERTEX]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 6, 1, 0);

		return true;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		glm::mat4 Projection = glm::ortho(-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, -1.0f);
		glm::mat4 View = glm::mat4(1.0f);
		glm::mat4 Model = glm::mat4(1.0f);
		glm::mat4 MVP = Projection * View * Model;

		glProgramUniformMatrix4fv(ProgramName[LAYERING], UniformMVP[LAYERING], 1, GL_FALSE, &MVP[0][0]);
		glProgramUniformMatrix4fv(ProgramName[VIEWPORT], UniformMVP[VIEWPORT], 1, GL_FALSE, &MVP[0][0]);

		// Pass 1
		{
			glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
	//		glBindFramebuffer(GL_FRAMEBUFFER, 0);
			glViewportIndexedfv(0, &glm::vec4(0, 0, FRAMEBUFFER_SIZE)[0]);

			glBindProgramPipeline(PipelineName[LAYERING]);
			glBindVertexArray(VertexArrayName[LAYERING]);
			glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 4, 0);
		}

		// Pass 2
		{
			GLint Border = 2;

			glBindFramebuffer(GL_FRAMEBUFFER, 0);
			glViewportIndexedfv(0, &glm::vec4(Border, Border, WindowSize * 0.5f - 2.0f * Border)[0]);
			glViewportIndexedfv(1, &glm::vec4((WindowSize.x * 0.5f) + Border, Border, WindowSize * 0.5f - 2.0f * Border)[0]);
			glViewportIndexedfv(2, &glm::vec4((WindowSize.x * 0.5f) + Border, (WindowSize.y * 0.5f) + 1, WindowSize * 0.5f - 2.0f * Border)[0]);
			glViewportIndexedfv(3, &glm::vec4(Border, (WindowSize.y * 0.5f) + Border, WindowSize * 0.5f - 2.0f * Border)[0]);

			glBindProgramPipeline(PipelineName[VIEWPORT]);

			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D_ARRAY, TextureColorbufferName);
			glBindSampler(0, SamplerName);

			glBindVertexArray(VertexArrayName[VIEWPORT]);
			glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 4, 0);
		}

		return true;
	}
inline void drawArraysInstancedBaseInstance(
	DrawArraysInstancedBaseInstanceMode mode,
	GLint first,
	GLsizei count,
	GLsizei primcount,
	GLuint baseinstance =0) {
	glDrawArraysInstancedBaseInstance(
		GLenum(mode),first,count,primcount, baseinstance
		);
}
Exemple #19
0
		Error operator()(GlState& state)
		{
			state.flushVertexState();
			state.flushStencilState();
			glDrawArraysInstancedBaseInstance(
				state.m_topology, m_info.m_first, m_info.m_count, m_info.m_instanceCount, m_info.m_baseInstance);

			ANKI_TRACE_INC_COUNTER(GR_DRAWCALLS, 1);
			return ErrorCode::NONE;
		}
	bool render()
	{
		this->beginTimer();

		for(std::size_t DrawIndex = 0; DrawIndex < this->DrawCount; ++DrawIndex)
			glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 2, 0);

		this->endTimer();

		return true;
	}
void NavigationBuildingBufferGeometry::RenderBoundingBoxBuffer()
{
	glBindVertexArray(m_VAO);
    
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_Buffers[VB_TYPES::BOUNDING_VB]);

	//glDrawArraysInstanced(GL_POINTS, 0, 10, 1);
	glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 6, 1, 0);
    glBindVertexArray(0);

}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
				GL_UNIFORM_BUFFER, 0,	sizeof(glm::mat4),
				GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, WindowSize.x, WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
			*Pointer = Projection * this->view() * Model;

			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		// Clear
		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName[framebuffer::CLEAR]);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]);

		// Render
		glViewportIndexedf(0, 0, 0, WindowSize.x * this->Supersampling, WindowSize.y * this->Supersampling);
		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName[framebuffer::BLEND]);
		glBindVertexArray(this->VertexArrayName[pipeline::RENDER]);

		glBindProgramPipeline(PipelineName[pipeline::RENDER]);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::DIFFUSE]);
		glBindImageTexture(semantic::image::DIFFUSE, TextureName[texture::COLORBUFFER], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantic::storage::VERTEX, BufferName[buffer::VERTEX]);

		for (std::size_t i = 0; i < this->Viewports.size(); ++i)
		{
			glViewportIndexedfv(0, &this->Viewports[i][0]);
			glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
		}

		// Splash
		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glBindVertexArray(this->VertexArrayName[pipeline::SPLASH]);

		glBindProgramPipeline(PipelineName[pipeline::SPLASH]);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		return true;
	}
	Error operator()(GlCommandBuffer*)
	{
		glDrawArraysInstancedBaseInstance(
			mode,
			m_info.m_first,
			m_info.m_count,
			m_info.m_instanceCount,
			m_info.m_baseInstance);

		ANKI_COUNTER_INC(GL_DRAWCALLS_COUNT, (U64)1);

		return ErrorCode::NONE;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glm::mat4* Pointer = static_cast<glm::mat4*>(glMapNamedBufferRange(BufferName[buffer::TRANSFORM],
				0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));

			//glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, 640.f, 480.f, 0.1f, 100.0f);
			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
		
			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapNamedBuffer(BufferName[buffer::TRANSFORM]);
		}

		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
		glViewportIndexedf(0, 0, 0, WindowSize.x / 16.0f, WindowSize.y / 16.0f);

		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f)[0]);

		// Bind rendering objects
		glViewportIndexedf(0, 0, 0, WindowSize.x / 16.0f, WindowSize.y / 16.0f);
		glBindProgramPipeline(PipelineName[pipeline::TEXTURE]);
		glBindVertexArray(VertexArrayName[pipeline::TEXTURE]);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);

		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::MATERIAL, BufferName[buffer::MATERIAL0]);

		//glSubpixelPrecisionBiasNV(-8, -8);
		glEnable(GL_CONSERVATIVE_RASTERIZATION_NV);
		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 1, 0, 0);

		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::MATERIAL, BufferName[buffer::MATERIAL1]);

		glDisable(GL_CONSERVATIVE_RASTERIZATION_NV);
		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 1, 0, 0);

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);

		glBindProgramPipeline(PipelineName[pipeline::SPLASH]);
		glBindVertexArray(VertexArrayName[pipeline::SPLASH]);
		glBindTextureUnit(0, TextureName[texture::COLORBUFFER]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		return true;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
				GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4),
				GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);

			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glClearTexImage(TextureName[texture::COLORBUFFER], 0, GL_RGBA, GL_FLOAT, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]);

		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);

		// Bind rendering objects
		glBindProgramPipeline(PipelineName[pipeline::TEXTURE]);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::DIFFUSE]);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]);
		glBindVertexArray(VertexArrayName[pipeline::TEXTURE]);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);

		for (std::size_t i = 0; i < this->Viewports.size(); ++i)
		{
			glViewportIndexedfv(0, &this->Viewports[i][0]);
			glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
			glTextureBarrier();
		}

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);

		glBindProgramPipeline(PipelineName[pipeline::SPLASH]);
		glActiveTexture(GL_TEXTURE0);
		glBindVertexArray(VertexArrayName[pipeline::SPLASH]);
		glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		return true;
	}
void testScreenspaceCoherence::render()
{
	float Depth(1.0f);
	glClearBufferfv(GL_DEPTH, 0, &Depth);
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f)[0]);

	glViewportIndexedfv(0, &glm::vec4(0, 0, this->getWindowSize())[0]);

	this->beginTimer();
		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, this->DrawVertexCount, 1, 0);

		//glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, ::VertexCount, 1, 0);
	this->endTimer();
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x * 0.5f / WindowSize.y, 0.1f, 1000.0f);
			glm::mat4 View = this->view();
			glm::mat4 Model = glm::mat4(1.0f);
			glm::mat4 MVP = Projection * View * Model;
			glm::mat4 MV = View * Model;

			TransformPointer->MVP = Projection * View * Model;
			TransformPointer->MV = View * Model;
			TransformPointer->Camera = glm::vec3(0.0f, 0.0f, -this->cameraDistance());
		}

		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)[0]);

		glBindProgramPipeline(PipelineName);
		glBindTextures(semantic::sampler::DIFFUSE, 1, &TextureName);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindVertexArray(VertexArrayName);

		// Left side: seamless cubemap filtering
		glViewportIndexedf(0, 0, 0, WindowSize.x * 0.5f, WindowSize.y);
		glBindSamplers(semantic::sampler::DIFFUSE, 1, &SamplerName[sampler::SEAMLESS]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0);

		// Right side: per face cubemap filtering
		glViewportIndexedf(0, WindowSize.x * 0.5f, 0, WindowSize.x * 0.5f, WindowSize.y);
		glBindSamplers(semantic::sampler::DIFFUSE, 1, &SamplerName[sampler::NON_SEAMLESS]);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0);

		return true;
	}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glm::mat4* Pointer = reinterpret_cast<glm::mat4*>(glMapNamedBufferRange(BufferName[buffer::TRANSFORM],
				0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));

			//glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, 640.f, 480.f, 0.1f, 100.0f);
			glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
		
			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapNamedBuffer(BufferName[buffer::TRANSFORM]);
		}

		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LESS);

		glClearTexImage(TextureName[texture::COLORBUFFER], 0, GL_RGBA, GL_UNSIGNED_BYTE, &glm::u8vec4(255, 255, 255, 255)[0]);
		glClearTexImage(TextureName[texture::RENDERBUFFER], 0, GL_DEPTH_COMPONENT, GL_FLOAT, &glm::vec1(1.0)[0]);
		glClearTexImage(TextureName[texture::INVOCATION_COUNT], 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &glm::u32vec1(0)[0]);

		glViewportIndexedf(0, 0, 0, WindowSize.x * FRAMEBUFFER_SCALE, WindowSize.y * FRAMEBUFFER_SCALE);

		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
		glBindProgramPipeline(PipelineName[pipeline::TEXTURE]);
		glBindVertexArray(VertexArrayName[pipeline::TEXTURE]);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindImageTexture(0, TextureName[texture::INVOCATION_COUNT], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);

		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 5, 0, 0);

		glDisable(GL_DEPTH_TEST);

		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glBindProgramPipeline(PipelineName[pipeline::SPLASH]);
		glBindVertexArray(VertexArrayName[pipeline::SPLASH]);
		glBindImageTexture(0, TextureName[texture::INVOCATION_COUNT], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);

		glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);

		return true;
	}
	Error operator()(CommandBufferImpl*)
	{
		if(!m_query.isCreated() || !m_query.get().skipDrawcall())
		{
			glDrawArraysInstancedBaseInstance(
				m_mode,
				m_info.m_first,
				m_info.m_count,
				m_info.m_instanceCount,
				m_info.m_baseInstance);

			ANKI_COUNTER_INC(GL_DRAWCALLS_COUNT, (U64)1);
		}

		return ErrorCode::NONE;
	}
void renderFBO()
{
	{
		glm::mat4* Pointer = (glm::mat4*)glMapNamedBufferRangeGTC(
			BufferName[buffer::TRANSFORM], 0, sizeof(glm::mat4),
			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);

		glm::mat4 Perspective = glm::perspective(45.0f, float(FRAMEBUFFER_SIZE.x) / FRAMEBUFFER_SIZE.y, 0.1f, 100.0f);
		glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y * 2.0 - 4.0));
		glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
		glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f));
		glm::mat4 Model = glm::mat4(1.0f);
		glm::mat4 MVP = Perspective * View * Model;

		*Pointer = MVP;
		glUnmapNamedBufferGTC(BufferName[buffer::TRANSFORM]);
		//glNamedBufferSubDataGTC(BufferName[buffer::TRANSFORM], 0, sizeof(glm::mat4), &MVP[0][0]);
	}

	glViewportIndexedf(0, 0, 0, float(FRAMEBUFFER_SIZE.x), float(FRAMEBUFFER_SIZE.y));
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_MULTISAMPLE);

	glBindNamedImageGTC(GL_FRAMEBUFFER, glf::semantic::renderbuffer::COLOR0, TextureName[texture::MULTISAMPLE], 0);
	glBindNamedImageGTC(GL_FRAMEBUFFER, glf::semantic::renderbuffer::DEPTH, TextureName[texture::DEPTH], 0);
	float Depth(1.0f);
	glClearBufferfv(GL_DEPTH, 0, &Depth);
	glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]);

	glBindNamedProgramPipelineGTC(PipelineName[program::THROUGH]);
	glBindNamedBufferGTC(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
	glBindNamedTextureGTC(GL_TEXTURE, 0, TextureName[texture::DIFFUSE]);
	glBindNamedSamplerGTC(GL_TEXTURE, 0, SamplerName);
	glBindNamedVertexArrayGTC(GL_VERTEX_INPUT, 0, VertexArrayName[vertexarray::VERTEX_INPUT]);
	glBindNamedVertexArrayGTC(GL_TRANSFORM_FEEDBACK, 0, VertexArrayName[vertexarray::TRANSFORM_FEEDBACK]);
	glBindNamedBufferGTC(GL_ARRAY_BUFFER, glf::semantic::attr::POSITION, BufferName[buffer::VERTEX]);
	glBindNamedBufferGTC(GL_ARRAY_BUFFER, glf::semantic::attr::TEXCOORD, BufferName[buffer::VERTEX]);

	glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 5, 0);

	glDisable(GL_MULTISAMPLE);
	glDisable(GL_DEPTH_TEST);

	glf::checkError("renderFBO");
}