示例#1
0
static bool
test_vertex_attrib_format()
{
	bool pass = true;

	/* "The error INVALID_OPERATION is generated by VertexAttribFormat, ...
	 * if <type> is UNSIGNED_INT_10F_11F_11F_REV and <size> is not 3."
	 */

	glVertexAttribFormat(0, 3, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0);
	TEST("VertexAttribFormat-ok", GL_NO_ERROR);

	glVertexAttribFormat(0, 2, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0);
	TEST("VertexAttribFormat-badsize", GL_INVALID_OPERATION);

	glVertexAttribFormat(0, GL_BGRA, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0);
	TEST("VertexAttribFormat-badsize-bgra", GL_INVALID_OPERATION);

	/* "The error INVALID_ENUM is generated by VertexAttribIFormat,
	 * VertexAttribLFormat, ...
	 * if <type> is UNSIGNED_INT_10F_11F_11F_REV."
	 */

	glVertexAttribIFormat(0, 3, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);
	TEST("VertexAttribIFormat-not-allowed", GL_INVALID_ENUM);

	glVertexAttribLFormat(0, 3, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);
	TEST("VertexAttribLFormat-not-allowed", GL_INVALID_ENUM);

	return pass;
}
void CadScene::enableVertexFormat(int attrPos, int attrNormal)
{
  glVertexAttribFormat(attrPos,    3,GL_FLOAT,GL_FALSE,0);
  glVertexAttribFormat(attrNormal, 3,GL_FLOAT,GL_FALSE,offsetof(CadScene::Vertex,normal));
  glVertexAttribBinding(attrPos,0);
  glVertexAttribBinding(attrNormal,0);
  glEnableVertexAttribArray(attrPos);
  glEnableVertexAttribArray(attrNormal);
  glBindVertexBuffer(0,0,0,sizeof(CadScene::Vertex));
}
示例#3
0
bool initVertexArray()
{
	glGenVertexArrays(1, &VertexArrayName);
	glBindVertexArray(VertexArrayName);
		glVertexAttribFormat(glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(glf::semantic::attr::POSITION, glf::semantic::buffer::STATIC);
		glEnableVertexAttribArray(glf::semantic::attr::POSITION);

		glVertexAttribFormat(glf::semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2));
		glVertexAttribBinding(glf::semantic::attr::TEXCOORD, glf::semantic::buffer::STATIC);
		glEnableVertexAttribArray(glf::semantic::attr::TEXCOORD);
	glBindVertexArray(0);

	return glf::checkError("initVertexArray");
}
示例#4
0
inline void vertex_attrib_format(uint32 attrib_index, uint32 element_count, uint32 type,
                                 bool normalize, uint32 offset)
{
    ARC_GL_CLEAR_ERRORS();
    glVertexAttribFormat(attrib_index,element_count,type,normalize,offset);
    ARC_GL_CHECK_FOR_ERRORS();
}
示例#5
0
void GLVertexArrayObject::setAttributeFormat( GLuint attributeIndex,
    GLint nComponents, GLVertexAttributeType type, bool normalized,
    GLuint relativeOffsetBytes )
{
    glVertexAttribFormat( attributeIndex, nComponents,
        glVertexAttributeType( type ), normalized, relativeOffsetBytes );
}
示例#6
0
void opengl_bind_vertex_array(const vertex_layout& layout) {
	auto iter = Stored_vertex_arrays.find(layout);
	if (iter != Stored_vertex_arrays.end()) {
		// Found existing vertex array!
		GL_state.BindVertexArray(iter->second);
		return;
	}

	GR_DEBUG_SCOPE("Create Vertex array");

	GLuint vao;
	glGenVertexArrays(1, &vao);
	GL_state.BindVertexArray(vao);

	for (size_t i = 0; i < layout.get_num_vertex_components(); ++i) {
		auto component = layout.get_vertex_component(i);

		auto& bind_info = GL_array_binding_data[component->format_type];
		auto& attrib_info = GL_vertex_attrib_info[bind_info.attribute_id];

		auto attribIndex = attrib_info.attribute_id;

		glEnableVertexAttribArray(attribIndex);
		glVertexAttribFormat(attribIndex,
							 bind_info.size,
							 bind_info.data_type,
							 bind_info.normalized,
							 static_cast<GLuint>(component->offset));

		// Currently, all vertex data comes from one buffer.
		glVertexAttribBinding(attribIndex, 0);
	}

	Stored_vertex_arrays.insert(std::make_pair(layout, vao));
}
示例#7
0
文件: topaz.cpp 项目: fetchhell/topaz
void TopazSample::drawModel(GLenum mode, NvGLSLProgram& program, TopazGLModel& model)
{
	glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, model.getModel()->getCompiledPositionOffset());

	glVertexAttribBinding(VERTEX_POS, 0);
	glEnableVertexAttribArray(VERTEX_POS);

	program.enable();

	program.bindTextureRect("pattern", 0, brushStyle->getTextureId());

	glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OBJECT, model.getBufferID("ubo"), 0, sizeof(ObjectData));

	glBindVertexBuffer(0, model.getBufferID("vbo"), 0, model.getModel()->getCompiledVertexSize() * sizeof(float));
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getBufferID("ibo"));
	glDrawElements(mode, model.getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES), GL_UNSIGNED_INT, nullptr);
	
	if (model.cornerPointsExists())
	{
		glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OBJECT, model.getCornerBufferID("ubo"), 0, sizeof(ObjectData));

		glBindVertexBuffer(0, model.getCornerBufferID("vbo"), 0, sizeof(nv::vec3f));
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getCornerBufferID("ibo"));

		glDrawElements(GL_LINE_STRIP, model.getCornerIndices().size(), GL_UNSIGNED_INT, nullptr);
	}
	
	program.disable();

	glDisableVertexAttribArray(VERTEX_POS);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindVertexBuffer(0, 0, 0, 0);
}
示例#8
0
void PipelineImpl::setVertexState(GlState& state) const
{
	if(state.m_stateHashes.m_vertex == m_hashes.m_vertex)
	{
		return;
	}

	state.m_stateHashes.m_vertex = m_hashes.m_vertex;

	for(U i = 0; i < m_in.m_vertex.m_attributeCount; ++i)
	{
		const Attribute& attrib = m_cache.m_attribs[i];
		ANKI_ASSERT(attrib.m_type);

		glVertexAttribFormat(
			i, attrib.m_compCount, attrib.m_type, attrib.m_normalized, m_in.m_vertex.m_attributes[i].m_offset);

		glVertexAttribBinding(i, m_in.m_vertex.m_attributes[i].m_binding);
	}

	for(U i = 0; i < m_in.m_vertex.m_bindingCount; ++i)
	{
		ANKI_ASSERT(m_in.m_vertex.m_bindings[i].m_stride > 0);
		state.m_vertexBindingStrides[i] = m_in.m_vertex.m_bindings[i].m_stride;
	}

	if(m_in.m_vertex.m_bindingCount)
	{
		state.m_vertBindingCount = m_in.m_vertex.m_bindingCount;
		state.m_vertBindingsDirty = true;
	}
}
 void TransparencyManagerOITClosestArray::drawQuad()
 {
   glEnableVertexAttribArray( 0 );
   glVertexAttribFormat( 0, 2, GL_FLOAT, GL_FALSE, 0 );
   glVertexAttribBinding( 0, 0 );
   glBindVertexBuffer( 0, m_fullScreenQuad->getGLId(), 0, 8 );
   glDrawArrays( GL_QUADS, 0, 4 );
 }
示例#10
0
文件: topaz.cpp 项目: fetchhell/topaz
void TopazSample::updateCommandListState()
{
	enum StateObjects
	{
		STATE_DRAW,
		STATE_GEOMETRY_DRAW,
		STATE_LINES_DRAW,
		STATES_COUNT
	};

	if (cmdlist.state.programIncarnation != cmdlist.captured.programIncarnation)
	{
			glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene);

			glEnable(GL_DEPTH_TEST);

			glEnable(GL_POLYGON_OFFSET_FILL);
			glPolygonOffset(1, 1);

			glEnableVertexAttribArray(VERTEX_POS);
			glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, models.at(0)->getModel()->getCompiledPositionOffset());
			glVertexAttribBinding(VERTEX_POS, 0);

			 glBindVertexBuffer(0, 0, 0, models.at(0)->getModel()->getCompiledVertexSize() * sizeof(float));

			if (hwsupport)
			{
				glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, 0, 0);
				glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, 0, 0);
				glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, UBO_OBJECT, 0, 0);
				glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, UBO_SCENE, 0, 0);
			}
			
			shaderPrograms["draw"]->enable();
			glStateCaptureNV(cmdlist.stateObjects[STATE_DRAW], GL_TRIANGLES);

			glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f));

			glStateCaptureNV(cmdlist.stateObjects[STATE_LINES_DRAW], GL_LINES);

			glDisableVertexAttribArray(VERTEX_POS);
			glBindFramebuffer(GL_FRAMEBUFFER, 0);

			glDisable(GL_DEPTH_TEST);
	}

	if (hwsupport && (
		cmdlist.state.programIncarnation != cmdlist.captured.programIncarnation ||
		cmdlist.state.fboIncarnation != cmdlist.captured.fboIncarnation))
	{
		NVTokenSequence &seq = cmdlist.tokenSequenceList;
		glCommandListSegmentsNV(cmdlist.tokenCmdList, 1);
		glListDrawCommandsStatesClientNV(cmdlist.tokenCmdList, 0, (const void**)&seq.offsets[0], &seq.sizes[0], &seq.states[0], &seq.fbos[0], int(seq.states.size()));
		glCompileCommandListNV(cmdlist.tokenCmdList);
	}
	
	cmdlist.captured = cmdlist.state;
}
bool initVertexArray()
{
	GLuint Bindingindex(0);

	glGenVertexArrays(1, &VertexArrayName);
    glBindVertexBuffer( Bindingindex, BufferName[buffer::VERTEX], 0, sizeof(glf::vertex_v2fv2f));

    glVertexAttribBinding( glf::semantic::attr::POSITION, Bindingindex);
    glVertexAttribFormat( glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0);

    glVertexAttribBinding( glf::semantic::attr::TEXCOORD, Bindingindex);
    glVertexAttribFormat( glf::semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2));

    glEnableVertexAttribArray( glf::semantic::attr::POSITION);
    glEnableVertexAttribArray( glf::semantic::attr::TEXCOORD);


	return true;
}
	bool initVertexArray()
	{
		glGenVertexArrays(1, &VertexArrayName);
		glBindVertexArray(VertexArrayName);
			glVertexAttribBinding(semantic::attr::POSITION, 0);
			glVertexAttribFormat(semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0);

			glVertexAttribBinding(semantic::attr::TEXCOORD, 0);
			glVertexAttribFormat(semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2));

			glEnableVertexAttribArray(semantic::attr::POSITION);
			glEnableVertexAttribArray(semantic::attr::TEXCOORD);

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferName[buffer::ELEMENT]);
			glBindVertexBuffer(0, BufferName[buffer::VERTEX], 0, sizeof(glf::vertex_v2fv2f));
		glBindVertexArray(0);

		return true;
	}
/*OpenGL 4.3 version. */
GLuint vaoFactory(GLuint loc_attrib, GLuint normal_attrib, GLuint texcoord_attrib)
{
	GLuint array;
	glGenVertexArrays(1, &array);
	
	// Enable my attributes
	glEnableVertexAttribArray(loc_attrib);
	glEnableVertexAttribArray(normal_attrib);
	glEnableVertexAttribArray(texcoord_attrib);
	// Set up the formats for my attributes
	glVertexAttribFormat(loc_attrib, 3, GL_FLOAT, GL_FALSE, 0);
	glVertexAttribFormat(normal_attrib, 3, GL_FLOAT, GL_FALSE, 12);
	glVertexAttribFormat(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 24);
	// Make my attributes all use binding 0
	glVertexAttribBinding(loc_attrib, 0);
	glVertexAttribBinding(normal_attrib, 0);
	glVertexAttribBinding(texcoord_attrib, 0);
	
	return array;
}
示例#14
0
bool initVertexArray()
{
	glGenVertexArrays(pipeline::MAX, &VertexArrayName[0]);
	glBindVertexArray(VertexArrayName[pipeline::TEXTURE]);
		glVertexAttribFormat(glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(glf::semantic::attr::POSITION, glf::semantic::buffer::STATIC);
		glEnableVertexAttribArray(glf::semantic::attr::POSITION);

		glVertexAttribFormat(glf::semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2));
		glVertexAttribBinding(glf::semantic::attr::TEXCOORD, glf::semantic::buffer::STATIC);
		glEnableVertexAttribArray(glf::semantic::attr::TEXCOORD);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferName[buffer::ELEMENT]);
	glBindVertexArray(0);

	glBindVertexArray(VertexArrayName[pipeline::SPLASH]);
	glBindVertexArray(0);

	return true;
}
	bool initVertexArray()
	{
		glGenVertexArrays(program::MAX, &VertexArrayName[0]);

		glBindVertexArray(VertexArrayName[program::TRANSFORM]);
			glVertexAttribFormat(semantic::attr::POSITION, 4, GL_FLOAT, GL_FALSE, 0);
			glVertexAttribBinding(semantic::attr::POSITION, semantic::buffer::STATIC);
			glEnableVertexAttribArray(semantic::attr::POSITION);
		glBindVertexArray(0);

		glBindVertexArray(VertexArrayName[program::FEEDBACK]);
			glVertexAttribFormat(semantic::attr::POSITION, 4, GL_FLOAT, GL_FALSE, 0);
			glVertexAttribBinding(semantic::attr::POSITION, semantic::buffer::STATIC);
			glEnableVertexAttribArray(semantic::attr::POSITION);

			glVertexAttribFormat(semantic::attr::COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4));
			glVertexAttribBinding(semantic::attr::COLOR, semantic::buffer::STATIC);
			glEnableVertexAttribArray(semantic::attr::COLOR);
		glBindVertexArray(0);

		return this->checkError("initVertexArray");
	}
示例#16
0
void _004_lua_test::init() {
  m_shader.init();
  m_vao.init();

  // init buffer with stuff
  core::t_vec4f vertices[] = {
    {-1.0, -1.0, -1.0, 1.0},
    { 1.0, -1.0, -1.0, 1.0},
    { 0.0,  1.0, -1.0, 1.0}
  };

  m_buffer.init();
  m_buffer.data(ATTRIBUTES::POSITION, sizeof(vertices), 0, GL_STATIC_DRAW);
  void* memory = m_buffer.map(ATTRIBUTES::POSITION, GL_WRITE_ONLY);
  std::memcpy(memory, vertices, sizeof(vertices));
  m_buffer.unmap(ATTRIBUTES::POSITION);

  // init vao with attrib formats
  {
    auto v = m_vao.activate();

    // setup attribute format
    glVertexAttribBinding(ATTRIBUTES::POSITION, BINDINGS::PRIMARY);
    glVertexAttribFormat(ATTRIBUTES::POSITION, 4, GL_FLOAT, GL_FALSE, 0);

    // enable attrib array
    glEnableVertexAttribArray(ATTRIBUTES::POSITION);

    // bind buffer
    glBindVertexBuffer(BINDINGS::PRIMARY, m_buffer.get_name(BUFFER::POSITION), 0, sizeof(core::t_vec4f));

    // order between the 3 steps does not matter, but every step has to exist.
  }

  glClearColor(0.2f, 0.2f, 0.23f, 0.0f);

  m_lua_state = luaL_newstate();
  luaL_openlibs(m_lua_state);

  std::cout << "start run lua file" << std::endl;
  luaL_dofile(m_lua_state, "data/script/manipulator.lua");
  std::cout << "stop run lua file" << std::endl;
  lua_close(m_lua_state);
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void RendererStandard::displayGrid(const InertiaCamera& camera, const mat4f projection)
{
	//
	// Update what is inside buffers
	//
	g_globalMatrices.mVP = projection * camera.m4_view;
	g_globalMatrices.mW = mat4f(array16_id);
	glNamedBufferSubDataEXT(g_uboMatrix.Id, 0, sizeof(g_globalMatrices), &g_globalMatrices);
	//
	// The cross vertex change is an example on how command-list are compatible with changing
	// what is inside the vertex buffers. VBOs are outside of the token buffers...
	//
	const vec3f& p = camera.curFocusPos;
	vec3f crossVtx[6] = {
		vec3f(p.x - CROSSSZ, p.y, p.z), vec3f(p.x + CROSSSZ, p.y, p.z),
		vec3f(p.x, p.y - CROSSSZ, p.z), vec3f(p.x, p.y + CROSSSZ, p.z),
		vec3f(p.x, p.y, p.z - CROSSSZ), vec3f(p.x, p.y, p.z + CROSSSZ),
	};
	glNamedBufferSubDataEXT(s_vboCross, 0, sizeof(vec3f)* 6, crossVtx);
	// ------------------------------------------------------------------------------------------
	// Case of regular rendering
	//
	s_shaderGrid.bindShader();
	glEnableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

    // --------------------------------------------------------------------------------------
	// Using regular VBO
	//
	glBindBufferBase(GL_UNIFORM_BUFFER, UBO_MATRIX, g_uboMatrix.Id);
	glBindVertexBuffer(0, s_vboGrid, 0, sizeof(vec3f));
	glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
	//
	// Draw!
	//
	glDrawArrays(GL_LINES, 0, GRIDDEF * 4);

	glBindVertexBuffer(0, s_vboCross, 0, sizeof(vec3f));
	glDrawArrays(GL_LINES, 0, 6);

    glDisableVertexAttribArray(0);
	//s_shaderGrid.unbindShader();
}
示例#18
0
bool EffectSkybox::initEffect()
{
	program = XRShaderManger::getShaderProgram(XRShaderManger::XR_SHADER_PROGRAM_ENVIRONMENT_MAPPING);

#pragma endregion

	//create and initialize vao
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

#pragma region setup position attribute
	{
		//create and initialize position vbo_pos
		glGenBuffers(1, &vbo_pos);
		glBindBuffer(GL_ARRAY_BUFFER, vbo_pos);
		XRMesh* mesh = (XRMesh*)object->getComponent(XR_COMPONENT_MESH);
		glBufferStorage(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * mesh->vertexNum, mesh->positions, GL_MAP_WRITE_BIT);

		//binding vertex attribute with vertex buffer object
		glVertexAttribBinding(VPOS, 0);
		glBindVertexBuffer(0, vbo_pos, 0, sizeof(GLfloat) * 3);
		glVertexAttribFormat(VPOS, 3, GL_FLOAT, GL_FALSE, 0);
		glEnableVertexAttribArray(VPOS);
	}

#pragma endregion


#pragma endregion

	//by now everything is recorded in the vao
	//so we will unbind the buffer
	//and unbind the vao
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);

	return true;
}
示例#19
0
void StateSystem::VertexFormatState::applyGL(GLbitfield changedFormat, GLbitfield changedBinding) const
{
  for (GLuint i = 0; i < MAX_VERTEXATTRIBS; i++){
    if (!isBitSet(changedFormat,i)) continue;

    switch(formats[i].mode){
    case VERTEXMODE_FLOAT:
      glVertexAttribFormat(i, formats[i].size, formats[i].type, formats[i].normalized, formats[i].relativeoffset);
      break;
    case VERTEXMODE_INT:
    case VERTEXMODE_UINT:
      glVertexAttribIFormat(i, formats[i].size, formats[i].type, formats[i].relativeoffset);
      break;
    }
    glVertexAttribBinding(i,formats[i].binding);
  }

  for (GLuint i = 0; i < MAX_VERTEXBINDINGS; i++){
    if (!isBitSet(changedBinding,i)) continue;

    glVertexBindingDivisor(i,bindings[i].divisor);
    glBindVertexBuffer(i,0,0,bindings[i].stride);
  }
}
示例#20
0
static void redraw(struct glwin *win)
{
	struct glwin_thread_state thread_state;
	glwin_get_thread_state(&thread_state);
	glwin_make_current(win, g_ctx);

	lua_State *L = g_L;

	static bool gl_init_attempted = false;
	static bool gl_init_result = false;

	if (!gl_init_attempted) {
		gl_init_result = glb_glcore_init(3, 3);
	}
	if (!gl_init_result) {
		printf("Failed to initialize OpenGL bindings\n");
		exit(-1);
		return;
	}

	glViewport(0, 0, win->width, win->height);
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);

	lua_getglobal(L, "b2l_data"); //1
	if (!lua_istable(L, -1)) {
		lua_pop(L, 1);
		goto end;
	}
	lua_getfield(L, -1, "objects"); //2
	lua_getglobal(L, "current_object"); //3
	if (!lua_isstring(L, -1)) {
		lua_pop(L, 3);
		goto end;
	}
	const char *current_object = lua_tostring(L, -1);
	lua_getfield(L, -2, current_object); //4
	if (lua_isnil(L, -1)) {
		lua_pop(L, 4);
		goto end;
	}

	lua_getfield(L, -1, "type"); //5
	if(strcmp(lua_tostring(L, -1), "MESH")) {
		lua_pop(L, 5);
		goto end;
	}
	lua_getfield(L, -2, "data"); //6
	lua_getfield(L, -6, "meshes"); //7
	lua_getfield(L, -1, lua_tostring(L, -2)); //8

	if (lua_isnil(L, -1)) {
		lua_pop(L, 8);
		goto end;
	}

	if (!g_gl_state.initialized)
		init_gl_state();

	if (g_gl_state.recompile_shaders)
		g_gl_state.program_valid = recompile_shaders();

	if (!g_gl_state.initialized || !g_gl_state.program_valid) {
		lua_pop(L, 8);
		goto end;
	}

	g_gl_state.recompile_shaders = false;

	glUseProgram(g_gl_state.program);
	glBindVertexArray(g_gl_state.vao);

	if (g_gl_state.blob_updated)  {
		glBufferData(GL_ARRAY_BUFFER, g_gl_state.blob_size, g_gl_state.blob ,GL_STATIC_DRAW);
		g_gl_state.blob_updated = false;
	}

	lua_getfield(L, -1, "vertex_normal_array_offset"); //9
	int vertex_normal_array_offset = lua_tointeger(L, -1);
	lua_getfield(L, -2, "uv_array_offset"); //10
	int uv_array_offset = lua_tointeger(L, -1);

	lua_getfield(L, -3, "uv_layers"); //11
	lua_len(L, -1); //12
	int num_uv_layers = lua_tointeger(L, -1);

	int tangent_array_offset;
	if (num_uv_layers > 0) {
		lua_getfield(L, -5, "tangent_array_offset");
		tangent_array_offset = lua_tointeger(L, -1);
		lua_pop(L, 1);
	}

	lua_getfield(L, -5, "vertex_co_array_offset"); //13
	int vertex_co_array_offset = lua_tointeger(L, -1);

	lua_getfield(L, -6, "weights_per_vertex"); //14
	int weights_per_vertex = lua_tointeger(L, -1);

	int weights_array_offset;
	if (weights_per_vertex > 0) {
		lua_getfield(L, -7, "weights_array_offset");
		weights_array_offset = lua_tointeger(L, -1);
		lua_pop(L, 1);
	} else {
		weights_array_offset = -1;
	}

	lua_getfield(L, -11, "vertex_groups"); //15
	int num_vertex_groups;
	if (lua_isnil(L, -1)) {
		num_vertex_groups = 0;
	} else {
		lua_len(L, -1);
		num_vertex_groups = lua_tointeger(L, -1);
		lua_pop(L, 1);
	}

	glBindVertexBuffer(NORMAL, g_gl_state.vbo, vertex_normal_array_offset, sizeof(float) * 3);
	if (num_uv_layers > 0) {
		glBindVertexBuffer(UV, g_gl_state.vbo, uv_array_offset, sizeof(float) * 2 * num_uv_layers);
		glBindVertexBuffer(TANGENT, g_gl_state.vbo, tangent_array_offset, sizeof(float) * 4);
	}
	glBindVertexBuffer(POS, g_gl_state.vbo, vertex_co_array_offset, sizeof(float) * 3);
	if (weights_per_vertex > 0)
		glBindVertexBuffer(WEIGHTS, g_gl_state.vbo, weights_array_offset, weights_per_vertex * 4);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_gl_state.vbo);
	if (g_gl_state.normal_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.normal_index);
		glVertexAttribFormat(g_gl_state.normal_index, 3, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.normal_index, NORMAL);
	}

	if (g_gl_state.uv_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.uv_index);
		glVertexAttribFormat(g_gl_state.uv_index, 2, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.uv_index, UV);
	}

	if (g_gl_state.pos_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.pos_index);
		glVertexAttribFormat(g_gl_state.pos_index, 3, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.pos_index, POS);
	}
	int i = 0;
	for (i = 0; i < 6; i++) {
		if (g_gl_state.weights_index[i] >= 0 && weights_per_vertex > 0) {
			glEnableVertexAttribArray(g_gl_state.weights_index[i]);
			glVertexAttribIFormat(g_gl_state.weights_index[i], 2, GL_SHORT, 4 * i);
			glVertexAttribBinding(g_gl_state.weights_index[i], WEIGHTS);
		}
	}
	if (num_uv_layers > 0 && g_gl_state.tangent_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.tangent_index);
		glVertexAttribFormat(g_gl_state.tangent_index, 4, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.tangent_index, TANGENT);
	}

	struct mat4 view;
	struct mat4 model;
	struct quaternion next;
	quaternion_mul(&q_delta, &q_cur, &next);
	quaternion_to_mat4(&next, &view);
	view.v[3][3] = 1;
	mat4_identity(&model);
	model.v[3][0] = g_offset[0] + g_offset_next[0];
	model.v[3][1] = g_offset[1] + g_offset_next[1];
	model.v[3][2] = g_offset[2] + g_offset_next[2];
	glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "model"), 1, GL_FALSE, (GLfloat *)&model);
	struct mat4 ident;
	mat4_identity(&ident);
	glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "view"), 1, GL_FALSE, (GLfloat *)&view);

	float zoom = exp(g_log_zoom);
	float zr = 100;
	struct mat4 proj;
	mat4_zero(&proj);
	proj.v[0][0] = 1.0/zoom;
	proj.v[1][1] = 1.0*win->width/(zoom*win->height);
	proj.v[2][2] = 1.0/zr;
	proj.v[3][3] = 1.0;
	glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "proj"), 1, GL_FALSE, (GLfloat *)&proj);

	if (weights_per_vertex > 0) {
		static int render_count = 0;
		render_count++;
		double frame;
		int frame_start;
		int frame_end;
		lua_getglobal(L, "frame_start"); //16
		frame_start = lua_tointeger(L, -1);
		lua_getglobal(L, "frame_end"); //17
		frame_end = lua_tointeger(L, -1);
		lua_getglobal(L, "frame_delta"); //18
		frame = frame_start + lua_tonumber(L, -1);
		int frame_i = floorf(frame);
		double frame_fract = frame - frame_i;

		lua_getfield(L, -18, "scenes"); //19
		lua_getglobal(L, "current_scene"); //20
		lua_getfield(L, -2, lua_tostring(L, -1)); //21
		if (!lua_istable(L, -1)) {
			lua_pop(L, 20);
			goto end;
		}
		lua_getfield(L, -1, "objects");
		lua_getfield(L, -1, current_object);
		lua_getfield(L, -1, "vertex_group_transform_array_offset");
		int offset = lua_tointeger(L, -1);
		lua_pop(L, 9);
		int stride = sizeof(float) * 4 * 4 * num_vertex_groups;
		int i;
		for (i = 0; i < num_vertex_groups; i++) {
			struct mat4 res;
			struct mat4 M1;
			struct mat4 M2;
			struct mat4 *base = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + frame_i * stride);
			struct mat4 *next = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + (frame_i + 1) * stride);

			if (frame_i == (frame_end-1)) {
				next = (struct mat4 *)(g_gl_state.blob + offset + i * sizeof(float) * 4 * 4 + (frame_start) * stride);
			} else if (frame_fract == 0) {
				next = base;
			}


#if USE_SLERP
			struct mat4 temp;
			mat4_zero(&temp);
			temp.v[3][3] = 1;
			M1 = *base;
			M2 = *next;
			spherical_lerp(M1.v[0], M2.v[0], frame_fract, temp.v[0]);
			spherical_lerp(M1.v[1], M2.v[1], frame_fract, temp.v[1]);
			spherical_lerp(M1.v[2], M2.v[2], frame_fract, temp.v[2]);
			mat4_transpose(&temp, &res);
			float v1[3];
			float v2[3];
			v1[0] = M1.v[0][3];
			v1[1] = M1.v[1][3];
			v1[2] = M1.v[2][3];
			v2[0] = M2.v[0][3];
			v2[1] = M2.v[1][3];
			v2[2] = M2.v[2][3];
			lerp(v1, v2, frame_fract, res.v[3]);
#else
			mat4_zero(&res);
			res.v[3][3] = 1;
			mat4_transpose(base, &M1);
			mat4_transpose(next, &M2);
			lerp(M1.v[0], M2.v[0], frame_fract, res.v[0]);
			lerp(M1.v[1], M2.v[1], frame_fract, res.v[1]);
			lerp(M1.v[2], M2.v[2], frame_fract, res.v[2]);
			lerp(M1.v[3], M2.v[3], frame_fract, res.v[3]);
#endif

			glUniformMatrix4fv(g_gl_state.groups_index + i,
					1, /*num_vertex_groups, */
					GL_FALSE,
					(GLfloat *)&res);
		}
	}

	lua_getglobal(L, "controls"); //16
	int controls = lua_gettop(L);
	lua_getglobal(L, "materials"); //17
	int materials = lua_gettop(L);

	lua_getfield(L, -10, "index_array_offset"); //18
	int index_array_offset = lua_tointeger(L, -1);

	lua_getfield(L, -11, "submeshes"); //19
	lua_len(L, -1); //20
	int num_submeshes = lua_tointeger(L, -1);

	for (i = 0; i < num_submeshes; i++) {
		lua_rawgeti(L, -2, i + 1);
		lua_getfield(L, -1, "material_name");

		const char *material_name = lua_tostring(L, -1);

		lua_getfield(L, -2, "triangle_no");
		int triangle_no = lua_tointeger(L, -1);
		lua_getfield(L, -3, "triangle_count");
		int triangle_count = lua_tointeger(L, -1);
		lua_getfield(L, materials, material_name);
		lua_getfield(L, -1, "params");
		lua_pushnil(L);  /* first key */
		while (lua_next(L, -2)) {
			int variable = lua_gettop(L);
			const char *variable_name = lua_tostring(L, variable - 1);
			int uniform_loc = glGetUniformLocation(g_gl_state.program, variable_name);
			if (uniform_loc == -1) {
				lua_pop(L, 1);
				continue;
			}
			lua_getfield(L, variable, "value");
			int value = variable + 1;
			lua_getfield(L, variable, "datatype");
			const char *datatype = strdup(lua_tostring(L, -1));
			lua_pop(L, 1);
			if (!strcmp(datatype, "bool")) {
				int bool_value = lua_toboolean(L, value);
				glUniform1i(uniform_loc, bool_value);
			} else if (!strcmp(datatype, "vec3")) {
				lua_rawgeti(L, value, 1);
				lua_rawgeti(L, value, 2);
				lua_rawgeti(L, value, 3);
				float val[3];
				val[0] = (float)lua_tonumber(L, -3);
				val[1] = (float)lua_tonumber(L, -2);
				val[2] = (float)lua_tonumber(L, -1);
				glUniform3fv(uniform_loc, 1, val);
				lua_pop(L, 3);
			} else if (!strcmp(datatype, "float")) {
				float fval = lua_tonumber(L, value);
				glUniform1f(uniform_loc, fval);
			} else if (!strcmp(datatype, "sampler2D")) {
				lua_getfield(L, controls, variable_name);
				int control = lua_gettop(L);
				lua_getfield(L, control, "needs_upload");
				int needs_upload = lua_toboolean(L, -1);
				lua_pop(L, 1);
				if (needs_upload) {
					int texunit;
					GdkPixbuf *pbuf;
					lua_getfield(L, control, "texunit");
					texunit = lua_tointeger(L, -1) - 1;
					lua_pop(L, 1);

					lua_getfield(L, control, "pbuf");
					lua_getfield(L, -1, "_native");
					pbuf = (GdkPixbuf *)lua_touserdata(L, -1);
					lua_pop(L, 2);
					glActiveTexture(GL_TEXTURE0 + texunit);
					glBindTexture(GL_TEXTURE_2D, g_texture_names[texunit]);
					int width = gdk_pixbuf_get_width(pbuf);
					int height = gdk_pixbuf_get_height(pbuf);
					int n_chan = gdk_pixbuf_get_n_channels(pbuf);
					glPixelStorei(GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_rowstride(pbuf)/ n_chan);
					glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
					glTexImage2D(GL_TEXTURE_2D,
						0, /* level */
						n_chan > 3 ? GL_RGBA : GL_RGB,
						width,
						height,
						0, /* border */
						n_chan > 3 ? GL_RGBA : GL_RGB,
						GL_UNSIGNED_BYTE,
						gdk_pixbuf_get_pixels(pbuf));
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
					glGenerateMipmap(GL_TEXTURE_2D);
					glUniform1i(uniform_loc, texunit);

					lua_pushboolean(L, 0);
					lua_setfield(L, control, "needs_upload");
				}
				lua_pop(L, 1);
			}
			free((void *)datatype);
			lua_pop(L, 2);
		} //while (lua_next(L, -2) != 0)
		glDrawElements(GL_TRIANGLES,
				3 * triangle_count,
				GL_UNSIGNED_SHORT,
				(void *)((int64_t)index_array_offset) + 3 * 2 * triangle_no);
		lua_pop(L, 6);
	}
	lua_pop(L, 20);
end:
	{
		GLenum err = glGetError();
		if (err)
			printf("render_scene GL error = %d\n", err);
	}
	glwin_swap_buffers(g_win);
	glwin_set_thread_state(&thread_state);
	g_need_redraw = false;
	return;
}
示例#21
0
文件: gfx.c 项目: onatto/luminos
static void initVertexFormats()
{
  // Specify vertex formats using ARB_vertex_attrib_binding
  glBindVertexArray(gctx.vtxformats[VERT_POS_NOR]);  
  // Position
  glVertexAttribFormat(0,                 // Attribute index layout (location = 0) for pos
                       3,                 // Size 3 * floats
                       GL_FLOAT,          // Type of attrib
                       GL_FALSE,          // Normalised?
                       0                  // Offset
                       );
  glVertexAttribBinding(0, 0);
  glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);            // NORMAL
  glVertexAttribBinding(1, 1);

  glBindVertexArray(gctx.vtxformats[VERT_POS_NOR_T0]);
  glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);            // POS
  glVertexAttribBinding(0, 0);
  glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);            // NORMAL
  glVertexAttribBinding(1, 1);
  glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 0);            // TEXCOORD0
  glVertexAttribBinding(2, 2);

  glBindVertexArray(gctx.vtxformats[VERT_POS_NOR_STRIDED]);
  glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);                            // POS
  glVertexAttribBinding(0, 0);
  glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float));            // NORMAL
  glVertexAttribBinding(1, 0);

  glBindVertexArray(gctx.vtxformats[VERT_POS_NOR_T0_STRIDED]);
  glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);                            // POS
  glVertexAttribBinding(0, 0);
  glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float));            // NORMAL
  glVertexAttribBinding(1, 0);
  glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(float));            // TEXCOORD0
  glVertexAttribBinding(2, 0);

  glBindVertexArray(gctx.vtxformats[VERT_POS_T0_STRIDED]);
  glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0 * sizeof(float));             // POS
  glVertexAttribBinding(0, 0);
  glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float));            // NORMAL
  glVertexAttribBinding(1, 0);

  glBindVertexArray(0);
}
示例#22
0
文件: topaz.cpp 项目: fetchhell/topaz
void TopazSample::renderStandartWeightedBlendedOIT()
{
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_POLYGON_OFFSET_FILL);

	glBindBufferBase(GL_UNIFORM_BUFFER, UBO_SCENE, ubos.sceneUbo);
	glBindBufferBase(GL_UNIFORM_BUFFER, UBO_IDENTITY, ubos.identityUbo);

	glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene);
	drawModel(GL_TRIANGLES, *shaderPrograms["draw"], *models.at(0));
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	
	/* first pass oit */
	glDisable(GL_DEPTH_TEST);

	// TODO : change on transparent list of models
	for (auto model = models.begin() + 1; model != models.end(); model++)
	{
		/* geometry pass */
		{
			glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID());

			const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
			glDrawBuffers(2, drawBuffers);

			GLfloat clearColorZero[4] = { 0.0f };
			GLfloat clearColorOne[4] = { 1.0f };

			glClearBufferfv(GL_COLOR, 0, clearColorZero);
			glClearBufferfv(GL_COLOR, 1, clearColorOne);

			glEnable(GL_BLEND);
			glBlendEquation(GL_FUNC_ADD);
			glBlendFunci(0, GL_ONE, GL_ONE);
			glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);

			objectData.objectColor = nv::vec4f(1.0f, 1.0f, 1.0f, oit->getOpacity());
			glNamedBufferSubDataEXT((*model)->getBufferID("ubo"), 0, sizeof(ObjectData), &objectData);

			objectData.objectColor = nv::vec4f(1.0f, 0.0f, 0.0f, oit->getOpacity());
			glNamedBufferSubDataEXT((*model)->getCornerBufferID("ubo"), 0, sizeof(ObjectData), &objectData);

			drawModel(GL_TRIANGLES, *shaderPrograms["weightBlended"], **model);

			glDisable(GL_BLEND);
			CHECK_GL_ERROR();
		}

		/* composition pass */
		{
			glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene);
			glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OIT, ubos.weightBlendedUbo, 0, sizeof(WeightBlendedData));

			// check uniform buffer offset
			{
				const char* uniformNames[] = { "weightBlendedData.background", "weightBlendedData.colorTex0", "weightBlendedData.colorTex1" };

				std::unique_ptr<GLint>  parameters(new GLint[3]);
				std::unique_ptr<GLuint> uniformIndices(new GLuint[3]);

				glGetUniformIndices(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformNames, uniformIndices.get());
				glGetActiveUniformsiv(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformIndices.get(), GL_UNIFORM_OFFSET, parameters.get());

				GLint* offset = parameters.get();
			}

			{
				shaderPrograms["weightBlendedFinal"]->enable();

				glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0);

				glVertexAttribBinding(VERTEX_POS, 0);
				glEnableVertexAttribArray(VERTEX_POS);

				glBindVertexBuffer(0, fullScreenRectangle.vboFullScreen, 0, sizeof(nv::vec3f));
				glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

				shaderPrograms["weightBlendedFinal"]->disable();
			}
			CHECK_GL_ERROR();
		}
	}
}
示例#23
0
文件: topaz.cpp 项目: fetchhell/topaz
void TopazSample::initCommandListWeightBlended()
{
	if (!isTokenInternalsInited)
	{
		hwsupport = init_NV_command_list(sysGetProcAddress) ? true : false;
		nvtokenInitInternals(hwsupport, bindlessVboUbo);

		isTokenInternalsInited = true;
	}

	enum States
	{
		STATE_CLEAR,
		STATE_OPAQUE,
		STATE_TRANSPARENT,
		STATE_TRASPARENT_LINES,
		STATE_COMPOSITE,
		STATES_COUNT
	};

	if (hwsupport)
	{
		for (size_t i = 0; i < STATES_COUNT; i++)
		{
			glCreateStatesNV(1, &cmdlist.stateObjectsWeightBlended[i]);
		}

		glGenBuffers(1, &cmdlist.tokenBufferWeightBlended);
		glCreateCommandListsNV(1, &cmdlist.tokenCmdListWeightBlended);
	}

	NVTokenSequence& seq = cmdlist.tokenSequenceWeightBlended;
	std::string& stream = cmdlist.tokenDataWeightBlended;
	size_t offset = 0;

	{
		NVTokenUbo  ubo;
		ubo.setBuffer(ubos.sceneUbo, ubos.sceneUbo64, 0, sizeof(SceneData));
		ubo.setBinding(UBO_SCENE, NVTOKEN_STAGE_VERTEX);
		nvtokenEnqueue(stream, ubo);
		ubo.setBinding(UBO_SCENE, NVTOKEN_STAGE_FRAGMENT);
		nvtokenEnqueue(stream, ubo);
	}

	// 1. render 'background' into framebuffer 'fbos.scene' 
	{
		auto& model = models.at(0);
		setTokenBuffers(model.get(), stream);

		NVTokenDrawElems  draw;
		draw.setParams(model->getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES));
		draw.setMode(GL_TRIANGLES);
		nvtokenEnqueue(stream, draw);

		pushTokenParameters(seq, offset, stream, fbos.scene, cmdlist.stateObjectsWeightBlended[STATE_OPAQUE]);
	}

	// 2. geometry pass OIT 
	for (auto model = models.begin() + 1; model != models.end(); model++)
	{
		// like call glClearBufferfv
		{
			NVTokenVbo vbo;
			vbo.setBinding(0);
			vbo.setBuffer(fullScreenRectangle.vboFullScreen, fullScreenRectangle.vboFullScreen64, 0);
			nvtokenEnqueue(stream, vbo);

			NVTokenUbo ubo;
			ubo.setBuffer(ubos.identityUbo, ubos.identityUbo64, 0, sizeof(IdentityData));
			ubo.setBinding(UBO_IDENTITY, NVTOKEN_STAGE_VERTEX);
			nvtokenEnqueue(stream, ubo);

			NVTokenDrawArrays  draw;
			draw.setParams(4, 0);
			draw.setMode(GL_TRIANGLE_STRIP);
			nvtokenEnqueue(stream, draw);
		}
		pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_CLEAR]);

		// 2. geometry pass
		{
			setTokenBuffers((*model).get(), stream);

			NVTokenDrawElems  draw;
			draw.setParams((*model)->getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES));
			draw.setMode(GL_TRIANGLES);
			nvtokenEnqueue(stream, draw);
		}
		pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_TRANSPARENT]);

		{
			setTokenBuffers((*model).get(), stream, true);

			NVTokenDrawElems  draw;
			draw.setParams((*model)->getCornerIndices().size());
			draw.setMode(GL_LINE_STRIP);
			nvtokenEnqueue(stream, draw);
		}
		pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_TRASPARENT_LINES]);

		// 3. composite pass
		{
			NVTokenVbo vbo;
			vbo.setBinding(0);
			vbo.setBuffer(fullScreenRectangle.vboFullScreen, fullScreenRectangle.vboFullScreen64, 0);
			nvtokenEnqueue(stream, vbo);

			NVTokenUbo ubo;
			ubo.setBuffer(ubos.identityUbo, ubos.identityUbo64, 0, sizeof(IdentityData));
			ubo.setBinding(UBO_IDENTITY, NVTOKEN_STAGE_VERTEX);
			nvtokenEnqueue(stream, ubo);

			NVTokenUbo uboWeightBlended;
			uboWeightBlended.setBuffer(ubos.weightBlendedUbo, ubos.weightBlendedUbo64, 0, sizeof(WeightBlendedData));
			uboWeightBlended.setBinding(UBO_OIT, NVTOKEN_STAGE_FRAGMENT);
			nvtokenEnqueue(stream, uboWeightBlended);

			NVTokenDrawArrays  draw;
			draw.setParams(4, 0);
			draw.setMode(GL_TRIANGLE_STRIP);
			nvtokenEnqueue(stream, draw);
		}
		pushTokenParameters(seq, offset, stream, fbos.scene, cmdlist.stateObjectsWeightBlended[STATE_COMPOSITE]);
	}
	
	if (hwsupport)
	{
		glNamedBufferStorageEXT(cmdlist.tokenBufferWeightBlended, cmdlist.tokenDataWeightBlended.size(), &cmdlist.tokenDataWeightBlended.at(0), 0);

		cmdlist.tokenSequenceListWeightBlended = cmdlist.tokenSequenceWeightBlended;
		for (size_t i = 0; i < cmdlist.tokenSequenceListWeightBlended.offsets.size(); i++)
		{
			cmdlist.tokenSequenceListWeightBlended.offsets[i] += (GLintptr)&cmdlist.tokenDataWeightBlended.at(0);
		}
	}
	
	glEnableVertexAttribArray(VERTEX_POS);
	glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0);
	glVertexAttribBinding(VERTEX_POS, 0);

	glEnable(GL_DEPTH_TEST);

	// 1. opaque modes
	{
		glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene);

		shaderPrograms["draw"]->enable();

		glBindVertexBuffer(0, 0, 0, 9 * sizeof(float));
		glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_OPAQUE], GL_TRIANGLES);
		
		shaderPrograms["draw"]->disable();

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	glDisable(GL_DEPTH_TEST);

	// like a glClearBufferfv
	{
		glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID());

		const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
		glDrawBuffers(2, drawBuffers);

		shaderPrograms["clear"]->enable();

		glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f));
		glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_CLEAR], GL_TRIANGLES);

		shaderPrograms["clear"]->disable();

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	// 2. oit first step
	{
		glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID());

		// ???
		//glEnable(GL_POLYGON_STIPPLE);
		//glPolygonStipple(brushStyle->brushPattern8to32(QtStyles::DiagCrossPattern).data());

		const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
		glDrawBuffers(2, drawBuffers);

		glEnable(GL_BLEND);
		glBlendEquation(GL_FUNC_ADD);
		glBlendFunci(0, GL_ONE, GL_ONE);
		glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);

		shaderPrograms["weightBlended"]->enable();

		glBindVertexBuffer(0, 0, 0, 9 * sizeof(float));
		glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_TRANSPARENT], GL_TRIANGLES);

		glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f));
		glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_TRASPARENT_LINES], GL_LINES);

		shaderPrograms["weightBlended"]->disable();

		// ???
		//glDisable(GL_POLYGON_STIPPLE);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	// 3. oit second step
	{
		glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene);
		glDisable(GL_BLEND);

		shaderPrograms["weightBlendedFinal"]->enable();

		glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f));
		glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_COMPOSITE], GL_TRIANGLES);

		shaderPrograms["weightBlendedFinal"]->disable();
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	// compile command list
	NVTokenSequence& sequenceList = cmdlist.tokenSequenceListWeightBlended;
	glCommandListSegmentsNV(cmdlist.tokenCmdListWeightBlended, 1);
	glListDrawCommandsStatesClientNV(cmdlist.tokenCmdListWeightBlended, 0, (const void**)&sequenceList.offsets[0], &sequenceList.sizes[0], &sequenceList.states[0], &sequenceList.fbos[0], int(sequenceList.states.size()));
	glCompileCommandListNV(cmdlist.tokenCmdListWeightBlended);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_glVertexAttribFormat(JNIEnv *__env, jclass clazz, jint attribindex, jint size, jint type, jboolean normalized, jint relativeoffset) {
    glVertexAttribFormatPROC glVertexAttribFormat = (glVertexAttribFormatPROC)tlsGetFunction(908);
    UNUSED_PARAM(clazz)
    glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglVertexAttribFormat(JNIEnv *__env, jclass clazz, jint attribindex, jint size, jint type, jboolean normalized, jint relativeoffset, jlong __functionAddress) {
	glVertexAttribFormatPROC glVertexAttribFormat = (glVertexAttribFormatPROC)(intptr_t)__functionAddress;
	UNUSED_PARAMS(__env, clazz)
	glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
}
示例#26
0
ShovelerDrawable *shovelerDrawableTilesCreate(unsigned char width, unsigned char height)
{
	Tiles *tiles = malloc(sizeof(Tiles));
	tiles->width = width;
	tiles->height = height;
	tiles->vertices = malloc(4 * width * height * sizeof(TilesVertex));
	tiles->triangles = malloc(2 * width * height * sizeof(TilesTriangle));
	tiles->drawable.data = tiles;
	tiles->drawable.draw = drawTiles;
	tiles->drawable.free = freeTiles;

	for(unsigned char x = 0; x < width; x++) {
		for(unsigned char y = 0; y < height; y++) {
			unsigned int index = x * height + y;

			tiles->vertices[4 * index + 0].position[0] = x;
			tiles->vertices[4 * index + 0].position[1] = y;
			tiles->vertices[4 * index + 0].uv[0] = 0;
			tiles->vertices[4 * index + 0].uv[1] = 0;

			tiles->vertices[4 * index + 1].position[0] = x + 1;
			tiles->vertices[4 * index + 1].position[1] = y;
			tiles->vertices[4 * index + 1].uv[0] = 1;
			tiles->vertices[4 * index + 1].uv[1] = 0;

			tiles->vertices[4 * index + 2].position[0] = x;
			tiles->vertices[4 * index + 2].position[1] = y + 1;
			tiles->vertices[4 * index + 2].uv[0] = 0;
			tiles->vertices[4 * index + 2].uv[1] = 1;

			tiles->vertices[4 * index + 3].position[0] = x + 1;
			tiles->vertices[4 * index + 3].position[1] = y + 1;
			tiles->vertices[4 * index + 3].uv[0] = 1;
			tiles->vertices[4 * index + 3].uv[1] = 1;

			tiles->triangles[2 * index + 0].indices[0] = 4 * index + 1;
			tiles->triangles[2 * index + 0].indices[1] = 4 * index + 3;
			tiles->triangles[2 * index + 0].indices[2] = 4 * index + 0;

			tiles->triangles[2 * index + 1].indices[0] = 4 * index + 3;
			tiles->triangles[2 * index + 1].indices[1] = 4 * index + 2;
			tiles->triangles[2 * index + 1].indices[2] = 4 * index + 0;
		}
	}

	glGenVertexArrays(1, &tiles->vertexArrayObject);
	glBindVertexArray(tiles->vertexArrayObject);
	glEnableVertexAttribArray(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_POSITION);
	glEnableVertexAttribArray(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_UV);
	glVertexAttribFormat(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_POSITION, 2, GL_UNSIGNED_BYTE, GL_FALSE, offsetof(TilesVertex, position));
	glVertexAttribFormat(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_UV, 2, GL_UNSIGNED_BYTE, GL_FALSE, offsetof(TilesVertex, uv));
	glVertexAttribBinding(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_POSITION, 0);
	glVertexAttribBinding(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_UV, 0);

	glGenBuffers(1, &tiles->vertexBuffer);
	glGenBuffers(1, &tiles->indexBuffer);

	glBindBuffer(GL_ARRAY_BUFFER, tiles->vertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, 4 * width * height * sizeof(TilesVertex), tiles->vertices, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tiles->indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * width * height * sizeof(TilesTriangle), tiles->triangles, GL_STATIC_DRAW);

	if(!shovelerOpenGLCheckSuccess()) {
		freeTiles(&tiles->drawable);
		return NULL;
	}

	return &tiles->drawable;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglVertexAttribFormat(JNIEnv *env, jclass clazz, jint attribindex, jint size, jint type, jboolean normalized, jint relativeoffset, jlong function_pointer) {
	glVertexAttribFormatPROC glVertexAttribFormat = (glVertexAttribFormatPROC)((intptr_t)function_pointer);
	glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
}
示例#28
0
bool StaticMesh::loadFromFile(const std::string& infile)
{
    Assimp::Importer imp;

    // Load scene and grab first mesh only
    imp.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,
                           aiPrimitiveType_LINE |
                           aiPrimitiveType_POINT |
                           aiPrimitiveType_POLYGON, nullptr);

    #ifdef DEBUG
    std::cout << "Calling Assimp::Importer::ReadFile...\n";
    #endif // DEBUG

    const aiScene *scene = imp.ReadFile(infile, aiProcessPreset_TargetRealtime_Quality
                                                & (!aiProcess_SplitLargeMeshes));
    #ifdef DEBUG
    std::cout << "Checking for a mesh...\n";
    #endif // DEBUG
    if(scene == nullptr)
        return false;
    else if(!scene->HasMeshes())
        return false;

    imp.ApplyPostProcessing(aiProcess_JoinIdenticalVertices);

    // Will only load one mesh
    const aiMesh *mesh = scene->mMeshes[0];

    #ifdef DEBUG
    std::cout << "Checking mesh has what we need...\n";
    #endif // DEBUG
    // Don't process special mesh types
    if(!mesh->HasPositions() ||
       !mesh->HasFaces())
        return false;

    vertexCount = mesh->mNumVertices;
    triangleCount = mesh->mNumFaces;

    // Check what attributes are in the mesh and
    // calculate total count of floats
    std::size_t componentCount = components.vertex = 3;
    if(mesh->HasNormals())
    {
        componentCount += components.normal = 3;
        #ifdef DEBUG
        std::cout << "Has normals\n";
        #endif // DEBUG
    }
    if(mesh->HasTangentsAndBitangents())
    {
        componentCount += (components.tangentBitangent = 3) * 2;
        #ifdef DEBUG
        std::cout << "Has tangents and bitangents\n";
        #endif // DEBUG
    }
    if(mesh->HasTextureCoords(0))
    {
        componentCount += components.texture = 3;
        #ifdef DEBUG
        std::cout << "Has texture coordinates\n";
        #endif // DEBUG
    }

    // Scale size for size of float
    std::size_t totalSize = componentCount * sizeof(float) * vertexCount;

    #ifdef DEBUG
    std::cout << totalSize << std::endl;
    std::cout << "Allocating and mapping vertex buffer...\n";
    #endif // DEBUG

    // Set size and map buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
    GLfloat *mapPtr = (GLfloat*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
//    glNamedBufferDataEXT(buffer, totalSize, nullptr, GL_STATIC_DRAW);
//    GLfloat *mapPtr = (GLfloat*) glMapNamedBufferEXT(buffer, GL_WRITE_ONLY);
    if(mapPtr == nullptr)
        return false;

    #ifdef DEBUG
    std::cout << "Worked!\n";
    #endif // DEBUG

    // Load all attributes into mapped buffer
    for(unsigned int i = 0; i < vertexCount; ++i)
    {
        GLfloat *head = mapPtr + i * componentCount;

        *head++ = mesh->mVertices[i].x;
        *head++ = mesh->mVertices[i].y;
        *head++ = mesh->mVertices[i].z;

        if(mesh->HasNormals())
        {
            *head++ = mesh->mNormals[i].x;
            *head++ = mesh->mNormals[i].y;
            *head++ = mesh->mNormals[i].z;
        }
        if(mesh->HasTextureCoords(0))
        {
            *head++ = mesh->mTextureCoords[0][i].x;
            *head++ = mesh->mTextureCoords[0][i].y;
            *head++ = mesh->mTextureCoords[0][i].z;
        }
        if(mesh->HasTangentsAndBitangents())
        {
            *head++ = mesh->mTangents[i].x;
            *head++ = mesh->mTangents[i].y;
            *head++ = mesh->mTangents[i].z;
            *head++ = mesh->mBitangents[i].x;
            *head++ = mesh->mBitangents[i].y;
            *head++ = mesh->mBitangents[i].z;
        }
    }

    if(!glUnmapBuffer(GL_ARRAY_BUFFER))
        return false;

    #ifdef DEBUG
    std::cout << "Allocating and mapping index buffer...\n";
    #endif // DEBUG

    // Same for index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangleCount*3*sizeof(GLshort), nullptr, GL_STATIC_DRAW);
    GLushort *indexMapPtr = (GLushort*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
//    glNamedBufferDataEXT(indices, triangleCount * 3 * sizeof(GLushort), nullptr, GL_STATIC_DRAW);
//    GLushort *indexMapPtr = (GLushort*) glMapNamedBufferEXT(indices, GL_WRITE_ONLY);
    if(indexMapPtr == nullptr)
        return false;

    #ifdef DEBUG
    std::cout << "Worked!\n";
    #endif // DEBUG

    for(unsigned int i = 0; i < triangleCount; ++i)
    {
        #ifdef DEBUG
        assert(mesh->mFaces[i].mNumIndices == 3);
        #endif // DEBUG
        unsigned int *indexArray = mesh->mFaces[i].mIndices;
        for(unsigned int j = 0; j < 3; ++j)
        {
            #ifdef DEBUG
            assert(*indexArray <= std::numeric_limits<GLushort>::max());
            #endif // DEBUG
            *indexMapPtr++ = *indexArray++;
        }
    }

    if(!glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER))
        return false;;

    #ifdef DEBUG
    std::cout << "Loading mesh successful!\n";
    std::cout << "Setting up vertex array...\n";
    #endif // DEBUG

    glBindVertexArray(vertexArray);

    glBindVertexBuffer(0, buffer, 0, (components.vertex +
                                      components.normal +
                                      components.texture +
                                      components.tangentBitangent * 2)
                                        * sizeof(GLfloat));
    glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
    glVertexAttribBinding(0, 0);
    glEnableVertexAttribArray(0);

    if(components.normal)
    {
        glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, components.vertex * sizeof(float));
        glVertexAttribBinding(1, 0);
        glEnableVertexAttribArray(1);
    }
    if(components.texture)
    {
        glVertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, (components.vertex +
                                                        components.normal) * sizeof(float));
        glVertexAttribBinding(2, 0);
        glEnableVertexAttribArray(2);
    }
    if(components.tangentBitangent)
    {
        glVertexAttribFormat(3, 3, GL_FLOAT, GL_FALSE, (components.vertex +
                                                        components.normal +
                                                        components.texture) * sizeof(float));
        glVertexAttribBinding(3, 0);
        glEnableVertexAttribArray(3);

        glVertexAttribFormat(4, 3, GL_FLOAT, GL_FALSE, (components.vertex +
                                                        components.normal +
                                                        components.texture +
                                                        components.tangentBitangent) * sizeof(float));
        glVertexAttribBinding(4, 0);
        glEnableVertexAttribArray(4);
    }

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);

    glBindVertexArray(0);

    #ifdef DEBUG
    std::cout << vertexCount << ' ' << triangleCount << std::endl;
    std::cout << +components.vertex << ' ';
    std::cout << +components.normal << ' ';
    std::cout << +components.texture << ' ';
    std::cout << +components.tangentBitangent << std::endl;
    #endif // DEBUG

    return true;
}
示例#29
0
int main()
{
	int w, h, c;
	unsigned char *datum = SOIL_load_image("materials/ok.jpg", &w, &h, &c, SOIL_LOAD_RGBA);

	GlRunner *runner = new GlRunner(RenderCB, w, h);

	GLuint VS = runner->BuildShaderProgram("shaders/quad.vert", GL_VERTEX_SHADER);
	GLuint FS = runner->BuildShaderProgram("shaders/cartoonify.frag", GL_FRAGMENT_SHADER);
	GLuint PPO = runner->BuildProgramPipeline();

	glUseProgramStages(PPO, GL_FRAGMENT_SHADER_BIT, FS);
	glUseProgramStages(PPO, GL_VERTEX_SHADER_BIT, VS);

	glProgramUniform1i(FS, glGetUniformLocation(FS, "tColor2D"), 0);

	GLfloat pos_buf[] = {
		-1.0, 1.0,
		1.0, 1.0,
		-1.0, -1.0,
		1.0, -1.0,
	};

	GLuint posVBO;
	glGenBuffers(1, &posVBO);
	glBindBuffer(GL_ARRAY_BUFFER, posVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(pos_buf), pos_buf, GL_STATIC_DRAW);

	GLfloat texc_buf[] = {
		0.0, 0.0,
		1.0, 0.0,
		0.0, 1.0,
		1.0, 1.0,
	};

	GLuint TexcVBO;
	glGenBuffers(1, &TexcVBO);
	glBindBuffer(GL_ARRAY_BUFFER, TexcVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(texc_buf), texc_buf, GL_DYNAMIC_DRAW);

	GLuint VAO;
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
	glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 0);

	glVertexAttribBinding(0, 0);
	glVertexAttribBinding(1, 1);

	glBindVertexBuffer(0, posVBO, 0, 2*sizeof(GLfloat));
	glBindVertexBuffer(1, TexcVBO, 0, 2*sizeof(GLfloat));

	GLuint srcTexObj;
	glGenTextures(1, &srcTexObj);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, srcTexObj);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, datum);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	runner->OnRender();

	return 0;
}
示例#30
0
/**
 * TODO: Test if you can pass a NULL mesh to Geometry.
 */
RenderableGeometry *renderableGeometryNew(Geometry geometry)
{
	RenderableGeometry *renderableGeometry = malloc(sizeof(RenderableGeometry));

	renderableGeometry->indices = 0;
	renderableGeometry->aabb.min = vec3(0.0f, 0.0f, 0.0f);
	renderableGeometry->aabb.max = vec3(0.0f, 0.0f, 0.0f);

	glGenVertexArrays(1, &renderableGeometry->vao);
	glGenBuffers(4, renderableGeometry->vbo);

	Mesh *mesh = NULL;

	if (geometry.type == GEOMETRY_MESH) {
		mesh = geometry.mesh;
	} else if (geometry.type == GEOMETRY_PLANE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_CUBE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_SPHERE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_CAPSULE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_CYLINDER) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_RAY) {
		// Generate mesh
	}

	if (mesh != NULL) {
		renderableGeometry->indices = (GLsizei)mesh->indices.length;

		/**
		 * Define VAO.
		 */
		glBindVertexArray(renderableGeometry->vao);

		glEnableVertexAttribArray(0);
		glEnableVertexAttribArray(1);
		glEnableVertexAttribArray(2);

		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); 
		glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 0); 
		glVertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 0);
		
		/**
		 * Define VBOs.
		 */
		if (mesh->vertices.length > 0) {
			glBindBuffer(GL_ARRAY_BUFFER, renderableGeometry->vbo[0]);
			glBufferStorage(GL_ARRAY_BUFFER, mesh->vertices.length * sizeof(Vec3), (float*)mesh->vertices.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);	
		}

		if (mesh->uvs.length > 0) {
			glBindBuffer(GL_ARRAY_BUFFER, renderableGeometry->vbo[1]);
			glBufferStorage(GL_ARRAY_BUFFER, mesh->uvs.length * sizeof(Vec2), (float*)mesh->uvs.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}

		if (mesh->normals.length > 0) {
			glBindBuffer(GL_ARRAY_BUFFER, renderableGeometry->vbo[2]);
			glBufferStorage(GL_ARRAY_BUFFER, mesh->normals.length * sizeof(Vec3), (float*)mesh->normals.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}

		if (mesh->indices.length > 0) {
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderableGeometry->vbo[3]);
			glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, mesh->indices.length * sizeof(unsigned), (unsigned*)mesh->indices.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}

		glBindVertexBuffer(0, renderableGeometry->vbo[0], 0, sizeof(Vec3));
		glBindVertexBuffer(1, renderableGeometry->vbo[1], 0, sizeof(Vec2));
		glBindVertexBuffer(2, renderableGeometry->vbo[2], 0, sizeof(Vec3));

		/**
		 * Unbind.
		 */
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
	}
	
	return renderableGeometry;
}