Source

GL Profile Suite / tests / interleave_arrays / init.lua

local paramIface = ...

local attribute_list = dofile("attrib_data.lua")

assert(paramIface.attribute_count.max == #attribute_list, "Need to make sure the attribute list is kept up-to-date with the attribute_count parameter.")

local strlist = {}

strlist[#strlist + 1] = [[
separateArrayBuffers = util::CreateBufferObjects($attribute_count.max);
glGenBuffers(1, &individualArrayBuffer);
interleavedArrayBuffers = util::CreateBufferObjects($attribute_count.count);
glGenBuffers(1, &indexBuffer);
programs = util::CreatePrograms($attribute_count.count);

]]

strlist[#strlist + 1] = [[
attribSize.resize($attribute_count.max);
attribType.resize($attribute_count.max);
attribNormalized.resize($attribute_count.max);

]]

strlist[#strlist + 1] = "{\n"

for index, typedef in ipairs(attribute_list) do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format(
		"\tattribSize[%i] = %i; attribType[%i] = %s; attribNormalized[%i] = %s;\n",
		cindex, typedef.size,
		cindex, typedef.type,
		cindex, typedef.norm)
end

strlist[#strlist + 1] = "\n\t//Create separate array buffers\n"

for index, typedef in ipairs(attribute_list) do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format(
		"\tstd::vector<%s> %s(attribSize[%i] * $vertex_count.max, %s);\n",
		typedef.ctype,
		typedef.name,
		cindex,
		typedef.initVal)
end

strlist[#strlist + 1] = "\n"

for index, typedef in ipairs(attribute_list) do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format(
		"\tutil::FillBufferData(separateArrayBuffers[%i], GL_ARRAY_BUFFER, %s, GL_STATIC_DRAW);\n",
		cindex,
		typedef.name)
end

strlist[#strlist + 1] = "\n\t//Create the individual buffer\n"
strlist[#strlist + 1] = [[
	individualOffsets.reserve($attribute_count.max);
	int totalBufferSize = 0;
]]

for index, typedef in ipairs(attribute_list) do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format([[
	individualOffsets.push_back(totalBufferSize);
	totalBufferSize += util::CalcOffset(%s);
]]				,
		typedef.name)
end

strlist[#strlist + 1] = "\n"


strlist[#strlist + 1] = [[
	glBindBuffer(GL_ARRAY_BUFFER, individualArrayBuffer);
	glBufferData(GL_ARRAY_BUFFER, totalBufferSize, NULL, GL_STATIC_DRAW);
]]

for index, typedef in ipairs(attribute_list) do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format(
		"\tglBufferSubData(GL_ARRAY_BUFFER, individualOffsets[%i], %s.size() * sizeof(%s), &%s[0]);\n",
		cindex,
		typedef.name,
		typedef.ctype,
		typedef.name)
end

strlist[#strlist + 1] = "\tglBindBuffer(GL_ARRAY_BUFFER, 0);\n"

strlist[#strlist + 1] = "\n"


strlist[#strlist + 1] = [[
	//Create the interleaved buffer
	interleavedStrides.reserve($attribute_count.count);
	interleavedOffsets.reserve($attribute_count.max);
	std::vector<char> byteBuffer; //stores a single vertex worth of data.
]]


for index = 1, paramIface.attribute_count.min - 1 do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format(
[[
	interleavedOffsets.push_back(byteBuffer.size());
	util::AddToInterleaveBuffer(byteBuffer, %s[0], %s.size() / $vertex_count.max);
]]			,
	attribute_list[index].name, attribute_list[index].name)
end

for index, attrib in paramIface.attribute_count.iter() do
	local cindex = index - 1
	strlist[#strlist + 1] = string.format(
[[
	//%i attribs
	interleavedOffsets.push_back(byteBuffer.size());
	util::AddToInterleaveBuffer(byteBuffer, %s[0], %s.size() / $vertex_count.max);
	interleavedStrides.push_back(byteBuffer.size());
	util::FillBufferData(interleavedArrayBuffers[%i], GL_ARRAY_BUFFER, util::RepeatBuffer(byteBuffer, $vertex_count.max), GL_STATIC_DRAW);

]]			,
	attrib,
	attribute_list[attrib].name, attribute_list[attrib].name,
	cindex)
end

strlist[#strlist + 1] = "}\n"

strlist[#strlist + 1] = [[
std::string fragmentShader;
{
	std::ifstream input("frag.frag", std::ios::binary);
	if(input)
		fragmentShader.assign(std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>());
}

BOOST_FOREACH(int attrib, $attribute_count.range())
{
	std::ostringstream buildName;
	buildName << "attrib" << attrib << ".vert";
	std::string name = buildName.str();

	std::ifstream input(name.c_str(), std::ios::binary);
	std::string vertexShader((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());

	try
	{
		glutil::LinkProgram(programs[attrib - $attribute_count.min], vertexShader, fragmentShader);
	}
	catch(std::exception &e)
	{
		std::cout << e.what() << std::endl;
		throw;
	}
}]]
return table.concat(strlist)