Jump to content

  • Log In with Google      Sign In   
  • Create Account


PandaDragonThing

Member Since 07 Aug 2011
Offline Last Active Jan 22 2014 02:50 AM

Topics I've Started

Component design and game class design

10 January 2014 - 08:15 PM

So I am trying to implement a component design and I am currently unsure if I am implemented it effectively or correctly.

My classes and their children are as follow:
 

1. MainGame

2. VideoManager

3. EntityManager

4. Entity

             |---6. InputComponent  |---8. CharacterInputComponent
5. Component |
             |---7. RenderComponent |---9. CharacterRenderComponent

10. SmartList

1. So the main game class holds function for initializing, running, and terminating the game. It also has a pointer to the various managers( more will be added for like sounds or resources ) which manage more specialized parts of the game.

2. The video manager has collection of the shaders, the projection and view matrices, etc.. all for handling the drawing commands.

3. The entity manager has a list of all entities that are in the world and knows to update them if need be( drawing, input, etc. ). The list is my SmartList.

4. The entity has a list of components that are linked to it. These components give all functionality to the entity other than the basics. It operates kind of like a unique component manager.

5. This is a base class that only really defines a function( update call ) used by all components and the unique string id of all components( for use in my smart list ).

6 & 7. These are specialized components that have specific roles, one for rendering and one for input. More will inevitably be made.

8 & 9. These would be the actual components that I would link to my entities since they implement the functions more specifically.

10. It's my own template class that can store and sort through all the objects. It uses double pointers and a binary search to look up things and a merge sort to keep everything in order. Memory is automatically allocated as the list grows/shrinks in exponents of 2. Through template classes and function pointers I can use this for any value and sort by any value such is integers, strings( as for my use ), or even complicated sets of data with specialized comparison.

Now here is how the flow of a input and render call.

//Draw a single scene and starts in the main game loop
MainGame -> VideoManager -> EntityManager -> Entity -> RenderComponent


//Input detected
GLFWCallback -> EntityManager -> Entity -> InputComponent

Here is my main.cpp and how it starts/run the game + making entities and components.


#include "GameClass.h"
#include "EntityManager.h"
#include "Entity.h"
#include "components/InputComponent.h"
#include "components/RenderComponent.h"

#include "Logger.h"

using namespace std;

struct MyInputComponent : public InputComponent
{
    void KeyPressed( int iKey, int iAction )
    {
        if( iKey == GLFW_KEY_ESCAPE && iAction == GLFW_PRESS )
        {
            GameClass::GetGameInstance()->EndGame();
        }
    }
};

int main( int argc, char* argv[] )
{

    GameClass* pGame = GameClass::GetGameInstance();

    if( !pGame->InitGame( 640, 480, 640, 480, "My Game" ) )
    {
        Logger::Log( "", "Couldn't initialize game." );
        return 1;
    }

    EntityManager* pEntityManager = pGame->GetEntityManager();

    MyInputComponent* c = new MyInputComponent();
    b->SetComponentName( "InputComponent Dude" );

    Entity* a = new Entity();
    a->SetEntityName( "EntityA" );

    Entity* b = new Entity();
    b->SetEntityName( "EntityB" );

    pEntityManager->AddEntity( a );
    pEntityManager->AddEntity( b );

    b->BindComponent( c );

    pEntityManager->RemoveEntity( pEntityManager->LookUpEntity( "EntityA" ) );

    pEngine->RunEngine();

    pEngine->TerminateEngine();

    delete a;
    delete b;
    delete c;

    return 0;
}

I'm also trying to do my best to stop decoupling. For example my VideoManager shouldn't need to know about entities or components hence why the flow chart goes in such steps, but I am worried it's adding extra overhead.

This is my first time working a larger project. I would like some suggestions or notable problems with my design so I can refactor my code. I usually develop for a while, assess all issues, and rebuild it from scratch more streamlined, but my limited experience doesn't make it easy to assess everything completely.


Shader issues. Not drawing a box.

10 January 2014 - 01:59 AM

Hello. I am trying to render a 2D white box. Well actually I wanted to render a texture, but am making sure that at a minimum I can render an empty square to know what I have done so far is working. Well it's not. I get a black screen with no white square as I expected.

Here is my drawing:

glClear( GL_COLOR_BUFFER_BIT );

//GLint iTexture = glGetUniformLocation( m_uiShaderProgram, "texture_sampler" );

glUseProgram( uiShaderProgram );

//glUniform1i( iTexture, 0 );

glUniformMatrix4fv( glGetUniformLocation( uiShaderProgram, "projection_matrix" ), 1, GL_FALSE, glm::value_ptr( mat4ProjectionMatrix ) );
glUniformMatrix4fv( glGetUniformLocation( uiShaderProgram, "view_matrix" ), 1, GL_FALSE, glm::value_ptr( mat4ViewMatrix ) );
glUniformMatrix4fv( glGetUniformLocation( uiShaderProgram, "model_matrix" ), 1, GL_FALSE, glm::value_ptr( mat4ModelMatrix ) );

//glActiveTexture( GL_TEXTURE0 );
//glBindTexture( GL_TEXTURE_2D, uiTextureID );

glBindBuffer( GL_ARRAY_BUFFER, uiVertexBuffer );
glVertexPointer( 3, GL_FLOAT, 0, (void*)0 );

glBindBuffer( GL_ARRAY_BUFFER, uiTexCoordBuffer );
glVertexPointer( 2, GL_FLOAT, 0, (void*)0 );

glDrawArrays( GL_QUADS, 0, 4 );

And these are my initializations for the various buffers:

//Shader program
const char* pchVertexShaderCode =
"#version 150\n"
"layout( location = 0 ) in vec3 vertex_position;"
"layout( location = 1 ) in vec2 vertex_uv;"
"out vec2 uv_coord;"
"uniform mat4 model_matrix, view_matrix, projection_matrix;"
"void main () {"
"  gl_Position = projection_matrix * view_matrix * model_matrix * vec4( vertex_position, 1.0 );"
"  uv_coord = vertex_uv;"
"}";

const char* pchFragmentShaderCode =
"#version 150\n"
"in vec2 uv_coord;"
"out vec4 frag_color;"
"uniform sampler2dD texture_sampler;"
"void main () {"
//"  frag_color = texture( texture_sampler, uv_coord ).rgb;"
"   frag_color = vec4( 1.0, 1.0, 1.0, 1.0 );"
"}";

unsigned int uiVertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( uiVertexShader, 1, &pchVertexShaderCode, NULL );
glCompileShader( uiVertexShader );

unsigned int uiFragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( uiFragmentShader, 1, &pchFragmentShaderCode, NULL );
glCompileShader( uiFragmentShader );

m_uiShaderProgram = glCreateProgram();
glAttachShader( uiShaderProgram, uiFragmentShader );
glAttachShader( uiShaderProgram, uiVertexShader );
glLinkProgram( uiShaderProgram );

//View matrix
mat4ViewMatrix = glm::lookAt( glm::vec3( 0.f, 0.f, 1.f ), glm::vec3( 0.f, 0.f, 0.f ), glm::vec3( 0.f, 1.f, 0.f ) );

//Projection matrix
mat4ProjectionMatrix = glm::ortho( 0.f, (float)iWindowWidth, (float)iWindowHeight, 0.f, 0.01f, 1000.f );

//Model matrix
glm::mat4 mat4T = glm::translate( glm::mat4( 1.f ), glm::vec3( m_fPosX, m_fPosY, 0.f ) );
glm::mat4 mat4Rx = glm::rotate( mat4T, m_fRotX, glm::vec3( 1.f, 0.f, 0.f ) );
glm::mat4 mat4M = glm::rotate( mat4Rx, m_fRotY, glm::vec3( 0.f, 1.f, 0.f ) );
glm::mat4 mat4S = glm::scale( glm::mat4( 1.f ), glm::vec3( m_fScale ) );
mat4ModelMatrix = mat4M * mat4S;

//Vertex and tex coord buffer
float fVertices[] = {
0.f, 0.f, 0.f,
100.f, 0.f, 0.f,
100.f, 100.f, 0.f,
0.f, 100.f, 0.f
};

float fTexCoords[] = {
0.f, 0.f,
1.f, 0.f,
1.f, 1.f,
0.f, 1.f
};

glGenBuffers( 1, &uiVertexBuffer );
glBindBuffer( GL_ARRAY_BUFFER, uiVertexBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 12, fVertices, GL_STATIC_DRAW );

glGenBuffers( 1, &uiTexCoordBuffer );
glBindBuffer( GL_ARRAY_BUFFER, uiTexCoordBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 8, fTexCoords, GL_STATIC_DRAW );

Beginner Shader Problems or Misunderstandings..

14 September 2013 - 10:55 AM

I am trying to be compliant with more the more up to date OpenGL profile such as not using glRotate, glTranslate, or glScale and instead doing all of that through shaders and managing my own matrixes.

 

I'm getting weird behavior like rotation is happening at weird angles or my test triangle just completely dissappears. Also with transformation anything higher than 1 will make it dissappear and on the z pos the triangles doesn't even move in depth unless to dissappear.

I'm both new to the math and shader language so I think I made some mistakes.
 

//Handled in my Mesh struct
glm::mat4 mat4T = glm::translate( glm::mat4( 1 ), glm::vec3( m_dPosX, m_dPosY, m_dPosZ ) );
glm::mat4 mat4Rx = glm::rotate( mat4T, (GLfloat)m_dRotX, glm::vec3( 1, 0, 0 ) );
glm::mat4 mat4Ry = glm::rotate( mat4Rx, (GLfloat)m_dRotY, glm::vec3( 0, 1, 0 ) );
glm::mat4 mat4V = glm::rotate( mat4Ry, (GLfloat)m_dRotZ, glm::vec3( 0, 0, 1 ) );
glm::mat4 mat4M = glm::scale( glm::mat4( 1 ), glm::vec3( m_dScale ) );
m_mat4ModelViewMatrix = mat4V * mat4M;

//Handled by my main game class
m_mat4PerspectiveMatrix = glm::perspective( (double)45, (double)iResolutionWidth / (double)iResolutionWidth, (double)1, (double)1000 );

//Done in my drawing loop after using the shader program
glUniformMatrix4fv( glGetUniformLocation( m_uiTestShader, "MVP"), 1, GL_FALSE, glm::value_ptr( m_pTestMesh->m_mat4ModelViewMatrix * m_mat4PerspectiveMatrix ) );

Here's my shader program too:

//Vertex Shader
#version 400
layout( location = 0 ) in vec3 vertex_position;
layout( location = 1 ) in vec3 vertex_color;

out vec3 color;

uniform mat4 MVP;

void main()
{
  color = vertex_color;
  gl_Position = MVP * vec4( vertex_position, 1.0 );
}

//Fragment Shader
#version 400
in vec3 color;
out vec4 frag_color;
void main()
{
  frag_color = vec4( color, 1.0 );
}

GLFW3 Linker Errors

03 September 2013 - 09:00 AM

I am attempting to upgrade from GLFW2 to GLFW3, but I am getting these linker errors

lib\mingw\libglfw3.a(win32_monitor.c.obj):win32_monitor.c:(.text+0x30a): undefined reference to `_imp__CreateDCW@16'
lib\mingw\libglfw3.a(win32_monitor.c.obj):win32_monitor.c:(.text+0x356): undefined reference to `_imp__GetDeviceCaps@8'
lib\mingw\libglfw3.a(win32_monitor.c.obj):win32_monitor.c:(.text+0x3a2): undefined reference to `_imp__DeleteDC@4'
lib\mingw\libglfw3.a(win32_gamma.c.obj):win32_gamma.c:(.text+0x7b): undefined reference to `_imp__CreateDCW@16'
lib\mingw\libglfw3.a(win32_gamma.c.obj):win32_gamma.c:(.text+0x91): undefined reference to `_imp__GetDeviceGammaRamp@8'
lib\mingw\libglfw3.a(win32_gamma.c.obj):win32_gamma.c:(.text+0x9d): undefined reference to `_imp__DeleteDC@4'
lib\mingw\libglfw3.a(win32_gamma.c.obj):win32_gamma.c:(.text+0x35b): undefined reference to `_imp__CreateDCW@16'
lib\mingw\libglfw3.a(win32_gamma.c.obj):win32_gamma.c:(.text+0x36d): undefined reference to `_imp__SetDeviceGammaRamp@8'
lib\mingw\libglfw3.a(win32_gamma.c.obj):win32_gamma.c:(.text+0x379): undefined reference to `_imp__DeleteDC@4'
lib\mingw\libglfw3.a(wgl_context.c.obj):wgl_context.c:(.text+0x13b): undefined reference to `_imp__DescribePixelFormat@16'
lib\mingw\libglfw3.a(wgl_context.c.obj):wgl_context.c:(.text+0x989): undefined reference to `_imp__DescribePixelFormat@16'
lib\mingw\libglfw3.a(wgl_context.c.obj):wgl_context.c:(.text+0xac2): undefined reference to `_imp__DescribePixelFormat@16'
lib\mingw\libglfw3.a(wgl_context.c.obj):wgl_context.c:(.text+0xae4): undefined reference to `_imp__SetPixelFormat@12'
lib\mingw\libglfw3.a(wgl_context.c.obj):wgl_context.c:(.text+0x1592): undefined reference to `_imp__SwapBuffers@4'

I've made the changes in the code to support GLFW3( or atleast everything that compiling was complaining about earlier ). It's version 3.0.2, the latest one.

I am using Code::Blocks and mingw, the header and library file, libglfw3.a and glfw3.h, from the binary build for 32 bit Windows.

Here is how I am including:

#define GLEW_STATIC

#include "GL/glew.h"
#include "GL/glfw3.h"

And finally, here is the order and libraries I am linking to:

lib\mingw\libglfw3.a
lib\glew32s.lib
lib\libSOIL.a
opengl3

[Solution]

If you are trying to link the static version of the library, libglfw3.a, you have to link gdi32 in this order.

libglfw3.a
gdi32
opengl32

If you are linking in the dynamic link version of the library, glfw3dll.a, you shouldn't need to link gdi32.


Engine Structure?

28 August 2013 - 01:25 AM

I'm building a simple 2D Engine, and I would like some input on my idea for the engine structure and also possibly other ideas that may be better.

Currently I have a header file which is used everywhere in my engine. It defines things that are universal such as struct Point or struct Image and other things such as enums and all that jazz.

Next I have an Engine class that's a singleton. It houses everything that is my engine and is the main interface through which you work with.

The final pieces are the important components that relate to different sections of the engine. They are their own class and can be accessed through gets in my Engine class. Here are some examples.

VideoInterface

  • Handles rendering.

ObjectInterface

  • Deals with the objects and instances

There is a lot more that is yet implemented such as input, networking, logic, sound, etc.. etc.

 

Here is an example of my main.cpp

Engine* g_pEngine;
ObjectInterface* g_pObjectInterface;
VideoInterface* g_pVideoInterface;

void MyStepFunc( double dTickStartTime )
{
    printf( "Render Speed: %fFPS\nGame Speed: %fFPS\n\n", g_pVideoInterface->GetFPS(), g_pEngine->GetGameSpeed() );
}

int main()
{
    //Set up Engine
    g_pEngine = Engine::GetEngine();
    g_pObjectInterface = g_pEngine->GetObjectInterface();
    g_pVideoInterface = g_pEngine->GetVideoInterface();
    g_pEngine->SetStepFunc( &MyStepFunc );

    //Engine initialization
    g_pEngine->Init( 640, 480, 640, 480, (char*)"Test Engine" );

    unsigned int uiObject = g_pObjectInterface->CreateObject();
    g_pObjectInterface->SetObjectTexture( (char*)"test.png", uiObject, 64, 64 );
    g_pObjectInterface->CreateAnimation( uiObject, 2 );
    g_pObjectInterface->AddAnimationFrame( uiObject, 0, Point( 0, 0 ), Point( 32, 64 ) );
    g_pObjectInterface->AddAnimationFrame( uiObject, 1, Point( 32, 64 ), Point( 64, 64 ) );

    unsigned int uiInstance = g_pObjectInterface->CreateInstance( uiObject );
    g_pObjectInterface->SetPosition( uiInstance, CluPoint( 0, 0 ) );

    //Engine main game loop
    g_pEngine->GameLoop();

    g_pEngine->Drop();

    delete g_pEngine;

    return -1;
}

What it does right now is create the game with a window of x and y size, x and y resolution, and a name. It then creates an object and creates an animation and then creates an instance of that object and set's the instances position.

g_pEngine->SetStepFunc( &MyStepFunc ); allows the setting of hooks. This hook is called every game step( 1/60th of a second ).

I just wanted input on if this was a good way of doing it, or if there is a better way that would allow more control by game developers. For example I can see just hooks being a limiting factor so I may try to code with polymorphism in mind and allower setter functions for the various interfaces.


PARTNERS