Commits

Jason McKesson committed e20185f

glscene: Scene graph parser seems to work now.

Comments (0)

Files changed (5)

glscene/Test/parseTest.cpp

 int g_width = 640;
 int g_height = 480;
 
+glscene::SceneGraph *g_pGraph = NULL;
+std::string g_nameCamera("main-camera");
+
+glutil::ObjectData g_objData = {glm::vec3(0, 3.0f, 0), glm::fquat(1.0f, 0.0f, 0.0f, 0.0f)};
+glutil::ObjectPole g_objectPole(g_objData, 90.0f/250.0f,
+								glutil::MB_RIGHT_BTN, NULL);
 
 void init()
 {
 	glViewport(0, 0, g_width, g_height);						// Reset The Current Viewport
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear Screen And Depth Buffer
 
+	glm::mat4 persp = glm::perspective(45.0f, g_width/(float)g_height, 0.1f, 100.0f);
+	g_pGraph->GetResources().SetUniform("perspective_matrix", persp);
+	SetMatrixCompose(GetNodeTM(*g_pGraph->FindNode("object")),
+		g_objectPole.CalcMatrix());
+
+	g_pGraph->Render(g_pGraph->GetResources().GetCamera(g_nameCamera).CalcMatrix(), glscene::ORDER_ARBITRARY, 0, "main");
+
 	glfwSwapBuffers();
 }
 
 	case GLFW_MOUSE_BUTTON_RIGHT: poleButton = glutil::MB_RIGHT_BTN; break;
 	}
 
-/*
 	g_objectPole.MouseClick((glutil::MouseButtons)poleButton, action == GLFW_PRESS, modifiers, mousePos);
 
 	if(g_pGraph)
 		g_pGraph->GetResources().GetCamera(g_nameCamera).MouseClick(
 			(glutil::MouseButtons)poleButton, action == GLFW_PRESS, modifiers, mousePos);
-*/
 }
 
 void GLFWCALL mouse_move_callback(int x, int y)
 {
-/*
 	g_objectPole.MouseMove(glm::ivec2(x, y));
 	if(g_pGraph)
 		g_pGraph->GetResources().GetCamera(g_nameCamera).MouseMove(glm::ivec2(x, y));
-*/
 }
 
 void GLFWCALL mouse_wheel_callback(int pos)
 	glfwGetMousePos(&mousePos.x, &mousePos.y);
 	int modifiers = calc_glfw_modifiers();
 
-/*
 	g_objectPole.MouseWheel(delta, modifiers, mousePos);
 	if(g_pGraph)
 		g_pGraph->GetResources().GetCamera(g_nameCamera).MouseWheel(delta, modifiers, mousePos);
-*/
 
 	lastPos = pos;
 }
 	if(unicodePoint > 127)
 		return;
 
-/*
 	if(g_pGraph)
 		g_pGraph->GetResources().GetCamera(g_nameCamera).CharPress((char)unicodePoint);
-*/
 }
 
 
 	{
 		try
 		{
-			glscene::ParseFromFile("test.glscene");
+			g_pGraph = glscene::ParseFromFile("test.glscene");
+			g_objectPole.SetLookatProvider(&g_pGraph->GetResources().GetCamera(g_nameCamera));
 		}
 		catch(std::runtime_error &e)
 		{
 			printf("%s\n", e.what());
+			glfwTerminate();
+			return 0;
 		}
 
-/*
 		//Main loop
 		while(true)
 		{
 
 			glfwSleep(0.005f);
 		}
-*/
+
+		delete g_pGraph;
 	}
 
 	glfwTerminate();

glscene/Test/test.glscene

 
 resources
-	sampler_res <spl>
-		mag [linear]
-		compare [pass]
-		aniso 1
-	end
-	
-	uniform_res <ident> {uniformName} [vec3] (-5.0)
-	
-	camera_res <ident> [left_btn] [left_kbd]
-		target (0 -5 0)
+	camera_res <main-camera> [left_btn] [left_kbd]
+		target (0 3.0 0)
 		orient (0 0 0 1)
 		spin 0
-		radius 10 1 20
-		radius_delta 0.5 2.0
-		pos_delta 0.25 1.5
+		radius 5 0.5 30
+		radius_delta 0.1 1.5
+		pos_delta 0.125 0.5
 		rotation_scale 0.36
 	end
 	
-	uniform_buffer_res <ubuff> 64 [stream_draw]
-	storage_buffer_res <sbuff> 128 placeholder
-
-	program_res <ident>
-		vert "filename.vert"
-		nmtc {blah2}
-		sampler {foo} 0
-		sampler {false} 1
-		image {boo} 2
-		mtc {blah}
+	mesh_res <object> [cube_pyramid] 2
+	mesh_res <ground> [ground_plane] 2 2
+	
+	texture_res <tex> "tex.png"
+	
+	sampler_res <nearest>
+		mag [linear]
+		min [linear]
+		wrap_s [edge_clamp]
+		wrap_t [edge_clamp]
+		wrap_r [edge_clamp]
 	end
 	
-	mesh_res <ident> [ground_plane] 3 20
-	texture_res <tex> "foo.file[ground_plane]"
+	uniform_res <perspective_matrix> {cameraToPerspective} [mat4] (1.0)
+	
+	program_res <ground>
+		vert "ground.vert"
+		frag "ground.frag"
+		mtc {modelToCamera}
+	end
+	
+	program_res <object>
+		vert "object.vert"
+		frag "object.frag"
+		mtc {modelToCamera}
+	end
+	
+	program_res <texture>
+		vert "texture.vert"
+		frag "texture.frag"
+		mtc {modelToCamera}
+		sampler {image} 0
+	end
 end
 
 scene
-	layer_defs 'foo' 'bar'
-	style_check <id> <blabal> <bol>
+	layer_defs 'main'
+	style_check <main>
 	
-	node <foo>
-		layers 'foo' -'bar' +'bar' +-'foo'
+	node <ground>
+		layers +'main'
+		
+		node_tm
+			orientation (-0.707 0 0 0.707)
+		end
 		
 		object_tm
-			translate (4)
-			scale (1)
-			orientation (0 0.707 0 0.707)
-			matrix (1)
+			scale (10)
 		end
 		
 		local <ident>
 		end
 		
-		style <id>
-		end
-		
-		node <ident>
-			local <ident2>
-			end
-
-			style <id>
-				using <ident2>
-				
-				mesh <ident>
-				texture 0 <tex> <spl>
-				uniform_buffer 0 <ubuff>
-				uniform_buffer 1 <ubuff> 32
-				storage_buffer 0 <sbuff>
-				
-//				program <ident>
-//				end
-				
-				pipeline
-					program <ident> [vert] [frag] end
-					program <ident> [geom] end
-				end
-			end
-		end
-		
-		node
-			style <id>
+		style <main>
+			mesh <ground>
+			program <ground>
+				uniform <perspective_matrix>
 			end
 		end
 	end
+	
+	node <object>
+		layers +'main'
+		
+		node_tm
+			translate (0 3 0)
+		end
+		
+		object_tm
+			scale (0.1)
+		end
+		
+		style <main>
+			mesh <object> 'lit'
+			program <object>
+				uniform <perspective_matrix>
+			end
+		end
+	end
+	
+	node <texObject>
+		layers +'main'
+		
+		node_tm
+			translate (0 3 0)
+		end
+		
+		object_tm
+			translate (0 2.5 -5.0)
+		end
+		
+		style <main>
+			mesh <ground> 'lit-tex'
+			program <texture>
+				uniform <perspective_matrix>
+			end
+			texture 0 <tex> <nearest>
+		end
+	end
 end

glscene/source/Parse.cpp

 		std::string txtFile((std::istreambuf_iterator<char>(loadFile)),
 			std::istreambuf_iterator<char>());
 
-		return ParseFromMemory(txtFile, loader);
+		return ParseFromString(txtFile, std::string(filename.data(), filename.size()), loader);
 	}
 }

glscene/source/ParsedData.cpp

 
 #include "pch.h"
 
+#include <sstream>
 #include <boost/container/flat_map.hpp>
 #include <boost/variant.hpp>
 #include "glscene/SceneGraph.h"
 #include "ParsedData.h"
 #include "glscene/Parse.h"
 #include "ParserEnums.h"
+#include "glscene/Style.h"
+#include "ParserExceptions.h"
 
 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 		}
 	};
 
+	typedef boost::container::flat_map<unsigned int, const FilePosition *> UsedBindingMap;
+
+	struct UsedData
+	{
+		const FilePosition *pMeshPos;
+		const FilePosition *pProgramPos;
+		UsedBindingMap textures;
+		UsedBindingMap uniformBuffers;
+		UsedBindingMap storageBuffers;
+
+		UsedData() : pMeshPos(), pProgramPos() {}
+	};
+
+	void ThrowMultipleUseError(const std::string &name, const FilePosition &firstDef,
+		const FilePosition &currDef)
+	{
+		std::stringstream str;
+		str << "A " << name << " has already been imported into this style.\n";
+		str << "\tThe first " << name << " was defined here: " << firstDef << std::endl;
+		str << "\t" << firstDef.theLine << std::endl;
+		str << "\t";
+		if(firstDef.columnNumber > 1)
+			str << std::setw(firstDef.columnNumber - 1) << " ";
+		str << "^- here";
+
+		throw BaseParseError(str.str(), currDef);
+	}
+
+	void ThrowMultipleBindingError(boost::string_ref name, unsigned int bindingIx,
+		const FilePosition &firstDef, const FilePosition &currDef)
+	{
+		std::stringstream str;
+		str << "The " << name << " binding to " << bindingIx << " is already in use.\n";
+		str << "\tThe first " << name << " binding was defined here: " << firstDef << std::endl;
+		str << "\t" << firstDef.theLine << std::endl;
+		str << "\t";
+		if(firstDef.columnNumber > 1)
+			str << std::setw(firstDef.columnNumber - 1) << " ";
+		str << "^- here";
+
+		throw BaseParseError(str.str(), currDef);
+	}
+
+	struct FetchProgramStyle : public boost::static_visitor<ProgramBinding>
+	{
+		ProgramBinding operator()(const ParsedPipelineDef &pipeDef) const
+		{
+			SeparableProgramBinding ret;
+
+			ret.pipeline.reserve(pipeDef.progs.size());
+			BOOST_FOREACH(const ParsedProgramMask &mask, pipeDef.progs)
+			{
+				ret.pipeline.push_back(ProgramMask());
+				ProgramMask &newMask = ret.pipeline.back();
+				newMask.stages = mask.stages;
+				newMask.prog = GetBinding(mask.prog);
+			}
+
+			return ret;
+		}
+
+		ProgramBinding operator()(const ParsedSingleProgramDef &progDef) const
+		{
+			return GetBinding(progDef);
+		}
+
+		static SingleProgramBinding GetBinding(const ParsedSingleProgramDef &progDef)
+		{
+			SingleProgramBinding ret;
+
+			ret.programId = progDef.programId.str();
+
+			ret.uniformIds.reserve(progDef.uniformReferences.size());
+			BOOST_FOREACH(const ParsedIdentifier &id, progDef.uniformReferences)
+			{
+				ret.uniformIds.push_back(id.str());
+			}
+
+			return ret;
+		}
+	};
+
+	void ApplyStyleData(StyleInfo &info, UsedData &used, const ParsedStyleData &data)
+	{
+		if(data.mesh)
+		{
+			if(used.pMeshPos)
+				ThrowMultipleUseError("mesh", *used.pMeshPos, data.mesh->pos);
+			used.pMeshPos = &data.mesh->pos;
+			info.meshResourceId = data.mesh->meshId.str();
+			info.meshVariantString = data.mesh->variant;
+		}
+
+		if(data.prog)
+		{
+			if(used.pProgramPos)
+				ThrowMultipleUseError("program", *used.pProgramPos, GetFilePosition(data.prog.get()));
+			used.pProgramPos = &GetFilePosition(data.prog.get());
+			info.progBinding = boost::apply_visitor(FetchProgramStyle(), data.prog.get());
+		}
+
+		BOOST_FOREACH(const ParsedTextureRefDef &texDef, data.textures)
+		{
+			if(used.textures.find(texDef.texUnit) != used.textures.end())
+				ThrowMultipleBindingError("texture", texDef.texUnit, *used.textures[texDef.texUnit], texDef.pos);
+			used.textures[texDef.texUnit] = &texDef.pos;
+			info.textureBindings.push_back(TextureBinding());
+			TextureBinding &binding = info.textureBindings.back();
+			binding.textureUnit = texDef.texUnit;
+			binding.textureId = texDef.textureId.str();
+			binding.samplerId = texDef.samplerId.str();
+		}
+
+		BOOST_FOREACH(const ParsedBufferRefDef &bufDef, data.uniformBuffers)
+		{
+			if(used.uniformBuffers.find(bufDef.buffBinding) != used.uniformBuffers.end())
+				ThrowMultipleBindingError("uniform buffer", bufDef.buffBinding, *used.uniformBuffers[bufDef.buffBinding], bufDef.pos);
+			used.uniformBuffers[bufDef.buffBinding] = &bufDef.pos;
+			info.uniformBufferBindings.push_back(BufferInterfaceBinding());
+			BufferInterfaceBinding &binding = info.uniformBufferBindings.back();
+			binding.bindPoint = bufDef.buffBinding;
+			binding.bindOffset = bufDef.offset;
+			binding.bufferId = bufDef.bufferId.str();
+		}
+
+		BOOST_FOREACH(const ParsedBufferRefDef &bufDef, data.storageBuffers)
+		{
+			if(used.storageBuffers.find(bufDef.buffBinding) != used.storageBuffers.end())
+				ThrowMultipleBindingError("storage buffer", bufDef.buffBinding, *used.storageBuffers[bufDef.buffBinding], bufDef.pos);
+			used.storageBuffers[bufDef.buffBinding] = &bufDef.pos;
+			info.storageBufferBindings.push_back(BufferInterfaceBinding());
+			BufferInterfaceBinding &binding = info.storageBufferBindings.back();
+			binding.bindPoint = bufDef.buffBinding;
+			binding.bindOffset = bufDef.offset;
+			binding.bufferId = bufDef.bufferId.str();
+		}
+	}
+
+	void ValidateStyle(const ParsedStyleDef &styleDef, const StyleInfo &info, const UsedData &used)
+	{
+		if(!used.pMeshPos)
+			throw BaseParseError("This style does not define a mesh or include a 'local' that does.", styleDef.pos);
+
+		if(!used.pProgramPos)
+			throw BaseParseError("This style does not define a program or pipeline, or include a 'local' that does.", styleDef.pos);
+	}
+
 	void ApplyNode(NodeData &rootNode, SceneGraph &graph, const ParsedNodeDef &nodeDef,
 		const LayerToIndexMap &layerToIndex)
 	{
 		node.GetObjectTM().SetComposable(boost::apply_visitor(ApplyTransform(), nodeDef.objectTM.trans));
 
 		//Set the styles.
+		BOOST_FOREACH(const ParsedStyleMap::value_type &stylePair, nodeDef.styles)
+		{
+			StyleInfo info;
+			UsedData used;
+			BOOST_FOREACH(const ParsedLocalDef *pLocalDef, stylePair.second.includes)
+			{
+				ApplyStyleData(info, used, pLocalDef->data);
+			}
+
+			ApplyStyleData(info, used, stylePair.second.data);
+
+			ValidateStyle(stylePair.second, info, used);
+
+			node.DefineStyle(stylePair.first.str(), info);
+		}
 
 
 		//Set the nodes.

glscene/source/ParsedData.h

 		bool hasOrientation;
 		bool hasScale;
 
-		ParsedDecomposedTransform() : hasOrientation(false), hasScale(false) {}
+		ParsedDecomposedTransform()
+			: mat(DecomposedMatrix::CreateDefault())
+			, hasOrientation(false)
+			, hasScale(false) {}
 	};
 
 	typedef boost::variant<glm::mat4, ParsedDecomposedTransform> ParsedTransform;
 
 	typedef boost::variant<ParsedPipelineDef, ParsedSingleProgramDef> ParsedProgramVariantDef;
 
-	struct ProgramVariantDefVisit : public boost::static_visitor<FilePosition>
+	struct ProgramVariantDefVisit : public boost::static_visitor<const FilePosition &>
 	{
-		template<typename T> FilePosition operator()(const T& t) const {return t.pos;}
+		template<typename T> const FilePosition &operator()(const T& t) const {return t.pos;}
 	};
 
-	inline FilePosition GetFilePosition(const ParsedProgramVariantDef &def)
+	inline const FilePosition &GetFilePosition(const ParsedProgramVariantDef &def)
 	{
 		return boost::apply_visitor(ProgramVariantDefVisit(), def);
 	}