So, people including Cody complain about me being over-achiever in my Game Engineering class. So what? I like the way I structure my code even though I have 14 projects within my solution. It looks neat and easy to use for me. Yes, I spend extra 3 hours moving my Utilities which used in both GameEngine and RendererEngine into another project I called Utilities. But, the result is I don't have to copy paste the same class I used in both projects. Shall one of the utilities has bug, I only need to fix one copy. And yes, I spent a lot of time restructuring JP's code into my GameEngine. However, I believe in future I will do less work. And my point is even though I did more that the requirement, I still complete the assignment ON TIME! Even earlier than most people in the cohort.
My whole Game Engineering solution looks so nice, right?
To make my GameEngine able to draw 3D, I decided to implement my RendererFramework from Game Graphics class. First I created a new RendererEngine in my solution to handle all the DirectX. Basically this is the RendererFramework with some modification to fit GameEngine. My GameEngine communicate with RendererEngine only through the Renderer class. This renderer class will initialize, tell the RendererEngine to create the necessary shaders/texture/meshes, tell RendererEngine to draw and shut it down.
When I read the configuration of the game which store all the information about the game (number of monsters, the position of player, the texture used by each entity, window size, etc...), I created the entity and create the model if it is 3D object or sprite if it is 2D object. Then World will ask Renderer to create the model/sprite and store it in database (Renderer.cpp has model and sprite class and only Renderer can use it). When Renderer is told to create a model, it will ask RendererEngine to create the entities, materials, effects, fragment shaders, vertex shaders, textures (like in JP class) in Model's Load function. Upon receiving the function call, the RendererEngine.cpp will create the data if it is not exist yet in the mapped-database. This is how I create the necessary information to draw object in DirectX.
Then every frame after I finished all the update sequence (physics, collision, ...), I draw the entities, quad (2D), line, and text in Renderer.cpp's Update function. I fed RendererEngine's Draw function with the vector of entities, quads, lines, and texts to be drawn. This the main function which doing the drawing. First, I looped through the entities to be drawn, then the line, the quads, and finally the text. This is my 3D pipeline and how I am able to draw the 3D mesh. Using the same pipeline, I am able to draw sphere, boxes (which I used) and Maya objects.
For 3D line, I created Line class in RendererEngine which contains the key of the vertex shader, the fragment shader used to draw the line and the vertex buffer. The vertex shader and the fragment shader will be created upon Line initialization when RendererEngine is initialized. I didn't store the vertex shader and the fragment shader in the line as I already have the database in RendererEngine.cpp. And I made the Line class into singleton because I can use the same vertex shader, fragment shader and vertex buffer for every line I am going to draw. And because I am using the same vertex buffer, I reload the vertex buffer every frame - every lines to be draw. I give only give the start position, end position, start colour, and end colour on LoadVertexBuffer.
Then for the 2D, I have a quad class. Same as Line class, I have the key to the vertex shader and fragment shader used to draw 2D while the real data is in RendererEngine.cpp's database. I also initialize this class when RendererEngine is initialized and make this function singleton with the same reason as Line. When drawing 2D in RendererEngine.cpp's Draw function, I loop through the quads to be drawn and only replace the texture for every quads, set the size and the position.
Finally font! To enable drawing font, I created Text class in RendererEngine. Same as Line and Quad, I initialized and created the ID3DXFont font and ID3DXSprite sprite when RendererEngine is initialized. With the very same reason ans Line and Quad, I made this class singleton and draw different text, different position, and different colour for every text in RendererEngine.cpp's Draw function.
That's how I made my 3D pipeline in my GameEngine and handle the meshes, quads, lines, and texts. This may not the best way but this works for me. With this system, I am able to add/remove entities easily. In the future I can also use different fragment shaders, vertex shaders, or materials for every entity.
![]() |
The Game solution explorer |
My whole Game Engineering solution looks so nice, right?
To make my GameEngine able to draw 3D, I decided to implement my RendererFramework from Game Graphics class. First I created a new RendererEngine in my solution to handle all the DirectX. Basically this is the RendererFramework with some modification to fit GameEngine. My GameEngine communicate with RendererEngine only through the Renderer class. This renderer class will initialize, tell the RendererEngine to create the necessary shaders/texture/meshes, tell RendererEngine to draw and shut it down.
When I read the configuration of the game which store all the information about the game (number of monsters, the position of player, the texture used by each entity, window size, etc...), I created the entity and create the model if it is 3D object or sprite if it is 2D object. Then World will ask Renderer to create the model/sprite and store it in database (Renderer.cpp has model and sprite class and only Renderer can use it). When Renderer is told to create a model, it will ask RendererEngine to create the entities, materials, effects, fragment shaders, vertex shaders, textures (like in JP class) in Model's Load function. Upon receiving the function call, the RendererEngine.cpp will create the data if it is not exist yet in the mapped-database. This is how I create the necessary information to draw object in DirectX.
Then every frame after I finished all the update sequence (physics, collision, ...), I draw the entities, quad (2D), line, and text in Renderer.cpp's Update function. I fed RendererEngine's Draw function with the vector of entities, quads, lines, and texts to be drawn. This the main function which doing the drawing. First, I looped through the entities to be drawn, then the line, the quads, and finally the text. This is my 3D pipeline and how I am able to draw the 3D mesh. Using the same pipeline, I am able to draw sphere, boxes (which I used) and Maya objects.
For 3D line, I created Line class in RendererEngine which contains the key of the vertex shader, the fragment shader used to draw the line and the vertex buffer. The vertex shader and the fragment shader will be created upon Line initialization when RendererEngine is initialized. I didn't store the vertex shader and the fragment shader in the line as I already have the database in RendererEngine.cpp. And I made the Line class into singleton because I can use the same vertex shader, fragment shader and vertex buffer for every line I am going to draw. And because I am using the same vertex buffer, I reload the vertex buffer every frame - every lines to be draw. I give only give the start position, end position, start colour, and end colour on LoadVertexBuffer.
Then for the 2D, I have a quad class. Same as Line class, I have the key to the vertex shader and fragment shader used to draw 2D while the real data is in RendererEngine.cpp's database. I also initialize this class when RendererEngine is initialized and make this function singleton with the same reason as Line. When drawing 2D in RendererEngine.cpp's Draw function, I loop through the quads to be drawn and only replace the texture for every quads, set the size and the position.
Finally font! To enable drawing font, I created Text class in RendererEngine. Same as Line and Quad, I initialized and created the ID3DXFont font and ID3DXSprite sprite when RendererEngine is initialized. With the very same reason ans Line and Quad, I made this class singleton and draw different text, different position, and different colour for every text in RendererEngine.cpp's Draw function.
That's how I made my 3D pipeline in my GameEngine and handle the meshes, quads, lines, and texts. This may not the best way but this works for me. With this system, I am able to add/remove entities easily. In the future I can also use different fragment shaders, vertex shaders, or materials for every entity.
No comments:
Post a Comment