I am getting confused on why the compiler is not recognizing my classes. So I am just going to show you my code and let you guys decide. My error is this
error C2653: 'RenderEngine' : is not a class or namespace name
and it's pointing to this line
std::vector<RenderEngine::rDefaultVertex> m_verts;
Here is the code for rModel, in its entirety. It contains the varible. the class that holds it is further down.
#ifndef _MODEL_H
#define _MODEL_H
#include "stdafx.h"
#include <vector>
#include <string>
//#include "RenderEngine.h"
#include "rTri.h"
class rModel {
public:
typedef tri<WORD> sTri;
std::vector<sTri> m_tris;
std::vector<RenderEngine::rDefaultVertex> m_verts;
std::wstring m_name;
ID3D10Buffer *m_pVertexBuffer;
ID3D10Buffer *m_pIndexBuffer;
rModel( const TCHAR *filename );
rModel( const TCHAR *name, int nVerts, int nTris );
~rModel();
float GenRadius();
void Scale( float amt );
void Draw();
//------------------------------------ Access functions.
int NumVerts(){ return m_verts.size(); }
int NumTris(){ return m_tris.size(); }
const TCHAR *Name(){ return m_name.c_str(); }
RenderEngine::cDefaultVertex *VertData(){ return &m_verts[0]; }
sTri *TriData(){ return &m_tris[0]; }
};
#endif
at the very top of the code there is a header file
#include "stdafx.h"
that includes this
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include "resource.h"
#include "d3d10.h"
#include "d3dx10.h"
#include "dinput.h"
#include "RenderEngine.h"
#include "rModel.h"
// TODO: reference additional headers your program requires here
as you can see, RenderEngine.h comes before rModel.h
#include "RenderEngine.h"
#include "rModel.h"
According to my knowledge, it should recognize it. But on the other hand, I am not really that great with organizing headers. Here my my RenderEngine Declaration.
#pragma once
#include "stdafx.h"
#define MAX_LOADSTRING 100
#define MAX_LIGHTS 10
class RenderEngine {
public:
class rDefaultVertex
{
public:
D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vNormal;
D3DXCOLOR m_vColor;
D3DXVECTOR2 m_TexCoords;
};
class rLight
{
public:
rLight()
{
}
D3DXCOLOR m_vColor;
D3DXVECTOR3 m_vDirection;
};
static HINSTANCE m_hInst;
HWND m_hWnd;
int m_nCmdShow;
TCHAR m_szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR m_szWindowClass[MAX_LOADSTRING]; // the main window class name
void DrawTextString(int x, int y, D3DXCOLOR color, const TCHAR *strOutput);
//static functions
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
bool InitWindow();
bool InitDirectX();
bool InitInstance();
int Run();
void ShutDown();
void AddLight(D3DCOLOR color, D3DXVECTOR3 pos);
RenderEngine()
{
m_screenRect.right = 800;
m_screenRect.bottom = 600;
m_iNumLights = 0;
}
protected:
RECT m_screenRect;
//direct3d Members
ID3D10Device *m_pDevice; // The IDirect3DDevice10
// interface
ID3D10Texture2D *m_pBackBuffer; // Pointer to the back buffer
ID3D10RenderTargetView *m_pRenderTargetView; // Pointer to render target view
IDXGISwapChain *m_pSwapChain; // Pointer to the swap chain
RECT m_rcScreenRect; // The dimensions of the screen
ID3D10Texture2D *m_pDepthStencilBuffer;
ID3D10DepthStencilState *m_pDepthStencilState;
ID3D10DepthStencilView *m_pDepthStencilView;
//transformation matrixs system
D3DXMATRIX m_mtxWorld;
D3DXMATRIX m_mtxView;
D3DXMATRIX m_mtxProj;
//pointers to shaders matrix varibles
ID3D10EffectMatrixVariable* m_pmtxWorldVar;
ID3D10EffectMatrixVariable* m_pmtxViewVar;
ID3D10EffectMatrixVariable* m_pmtxProjVar;
//Application Lights
rLight m_aLights[MAX_LIGHTS]; // Light array
int m_iNumLights; // Number of active lights
//light pointers from shader
ID3D10EffectVectorVariable* m_pLightDirVar;
ID3D10EffectVectorVariable* m_pLightColorVar;
ID3D10EffectVectorVariable* m_pNumLightsVar;
//Effect members
ID3D10Effect *m_pDefaultEffect;
ID3D10EffectTechnique *m_pDefaultTechnique;
ID3D10InputLayout* m_pDefaultInputLayout;
ID3DX10Font *m_pFont; // The font used for rendering text
// Sprites used to hold font characters
ID3DX10Sprite *m_pFontSprite;
ATOM RegisterEngineClass();
void DoFrame(float);
bool LoadEffects();
void UpdateMatrices();
void UpdateLights();
};
The classes are defined within the class
class rDefaultVertex
{
public:
D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vNormal;
D3DXCOLOR m_vColor;
D3DXVECTOR2 m_TexCoords;
};
class rLight
{
public:
rLight()
{
}
D3DXCOLOR m_vColor;
D3DXVECTOR3 m_vDirection;
};
Not sure if thats good practice, but I am just going by the book.
In the end, I just need a good way to organize it so that rModel recognizes RenderEngine. and if possible, the other way around.
[edit]
I can literally just point to the render engine class, and it still won't recognize
#ifndef _MODEL_H
#define _MODEL_H
//#include "stdafx.h"
#include <vector>
#include <string>
#include "RenderEngine.h" //<-------pointing to render engine. still does not recognize.
#include "rTri.h"
class rModel {
public:
typedef tri<WORD> sTri;
std::vector<sTri> m_tris;
std::vector<RenderEngine::rDefaultVertex> m_verts;
std::wstring m_name;
ID3D10Buffer *m_pVertexBuffer;
ID3D10Buffer *m_pIndexBuffer;
rModel( const TCHAR *filename );
rModel( const TCHAR *name, int nVerts, int nTris );
~rModel();
float GenRadius();
void Scale( float amt );
void Draw();
//------------------------------------ Access functions.
int NumVerts(){ return m_verts.size(); }
int NumTris(){ return m_tris.size(); }
const TCHAR *Name(){ return m_name.c_str(); }
RenderEngine::cDefaultVertex *VertData(){ return &m_verts[0]; }
sTri *TriData(){ return &m_tris[0]; }
};
#endif
As others mentioned, a decoupling/refactoring is in order here - stdafx.h is not meant to hold all header files your application has.
Your problem is that renderengine.h also includes stdafx.h. This time the renderengine.h include is ignored due to #pragma once and rmodel.h is included next - at the top of renderengine.h.
The simplest thing in your case would be to:
remove renderengine.h & rmodel.h from stdafx.h
rmodel.h includes renderengine.h
... done
I can't tell for sure, but RenderEngine.h probably includes rModel.h. Then when you include stdafx.h it brings in RenderEngine.h, but before it fully processes that header it then includes rModel.h. Then inside rModel.h the include guards prevent it from including stdafx.h again and it proceeds to compile rModel.h without full knowledge of anything in RenderEngine.h.
Without understanding the full relationship of your various classes its extremely hard to suggest a fix. Most likely you'll want to carefully consider which classes are defined in which headers and use forward declarations to remove the circular dependency.
It's pretty hard to understand all your dependencies and I think that your code needs refactoring (if not rewriting). Also, rushing into a rendering engine development without any architecture building experience (as I assume) generally results in crappy unreliable code, hacks "to make it work" and other evil stuff.
Anyway, in this case, try to decompose your application's parts and distinguish them. In your case, one of possible approaches would mean putting all rendering objects / structs such as Vertex, Light, Model in another header (you could call it render.types.h or render.objects.h or something like that).
Then you should simply make your rendering engine work with these render objects. Once you're done with it, you won't need statements like std::vector<RenderEngine::rDefaultVertex> m_verts; or RenderEngine::cDefaultVertex *VertData().
Note that this would also solve your circular dependencies, because your engine would only have to know about models, models - only about vertexes and so on.
If you still face the dependency troubles, use forward declarations. Google it for full description, and just a sample for you to understand what I mean:
class ForwardDeclared;
class Object {
ForwardDeclared* member;
void Method(const ForwardDeclared& fd) { (...) }
};
// This could also resude in another file
class ForwardDeclared { (...) };
Related
I have a file that is generating the error
"Block" is not a class or a namespace name
on the line
typedef Block::point point;
However, I'm positive that it's a class that I've both created and #included in the file below
'texture.h'.
#pragma once
#include "Block.h"
#include <iostream>
#include <vector>
#include <GL/glut.h>
#include "lodepng.h"
using namespace std;
typedef Block::point point;
class Texture
{
public:
Texture(int width, int height, string filename);//initialises our texture and loads its pixeldata into a buffer
Texture(void);
~Texture(void);
void draw(point centerPoint, point dimensions);
unsigned int w;//width of our imagefile
unsigned int h;
GLuint texID;//the ID we will give OGL for this particular texture.
private:
vector<unsigned char> image;
void texGLInit();
};
Also just for good measure, here is the block.h file in question.
#pragma once
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "Texture.h"
class Block
{
public:
struct point
{
GLfloat x, y;
};
enum State {STATIC, FALLING, SELECTED};
enum Colour {RED, BLUE, PURPLE, GREEN, YELLOW, DEAD};
Block(void);
~Block(void);
Block(int gridPosX, int gridPosY, point offset);
point gridPos;//the blocks designated position in the 8x8 array
point centerPos;//the blocks coordinates for the actual purpose of drawing
State blockState;//the state of the block
Colour blockColour;//the colour of the block
void move();//checks whether the block is in a falling state and moves it appropriately
void drawBlock();//no need to include the drawing coords as parameters. the block knows where it should be. The grid will simply tell it to draw itself.
private:
void fall();//decrements the blocks position
void assignRandomColour();//assigns a random colour to the block dependant upon its' texture
void generateWorldPos();//gets our block a center position, for us to later to use to draw it.
//the above function will also inherently define the size of each cell in the grid. I'm thinking each
//cell should be 40x40. So each cell will be offset initially by 20px by 20px.
point gridOffset;
};
I have no idea as to why i could be getting this error for a class that certainly exists.
Thanks in advance.
I see cyclic includes : Block.h includes Texture.h which includes Block.h.
Search for "cyclic header dependency" on this site, you will see many topics on this, where you can find solution as to how to solve this puzzle, the most common being using forward declarations of classes and pointers declarations of member data. Forward declarations of classes helps you avoid including headers, and pointers declarations of data helps you defining the enclosing class. That is a just a hint, now search for aforementioned topics for detailed answers.
This is my first question, so I apologize in advance for any things about stack overflow that I may not be aware of!
The issue I am having is that I am making a simple SDL program, currently it is just supposed to draw a PNG image (Assets/Board.png) to the screen, but I am being faced with many errors to do with the two classes communicating with each other, I think that I have circular inclusion errors. But I have been trying to fix the problem for days and I haven't been able to solve it.
Here are the errors that I am getting:
http://imgur.com/gallery/vq3XLwU/new
(Here is a text version of it, but the formatting is bad sorry)
1>d:\code\c++\games\chess\chess\manager.h(41): error C2079: 'Manager::Tex' uses undefined class 'Render'
1>d:\code\c++\games\chess\chess\render.h(32): error C2146: syntax error : missing ';' before identifier 'manager'
1>d:\code\c++\games\chess\chess\render.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\code\c++\games\chess\chess\render.h(32): error C2146: syntax error : missing ';' before identifier 'manager'
1>d:\code\c++\games\chess\chess\render.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
(I have used an image because the formatting of the image is easier to read.)
(Also click on the image in imgur to see the zoomed in version)
You can download the entire code project here (ZIP FILE):
https://www.mediafire.com/?og21315fc1d58sk
But here is the code that I think is causing the issues:
(Manager.h file)
//Include guards.
#pragma once
//Headers.
#include "Render.h"
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
//Namespaces.
using namespace std;
//Enumerator.
enum State { Play, Exit };
class Manager
{
public:
Manager(); //Constructor.
~Manager(); //Destructor.
//Rendering.
SDL_Window* Window;
SDL_Surface* Screen;
SDL_Renderer* Renderer;
//Functions.
void Run();
void Init();
void Close();
void Input();
void Update();
void Error(string);
//Game variables.
State state;
Render Tex;
private:
//Constant values.
const int WINDOW_POS_X = SDL_WINDOWPOS_CENTERED;
const int WINDOW_POS_Y = SDL_WINDOWPOS_CENTERED;
const int INIT_FLAGS = SDL_INIT_VIDEO;
const int SCREEN_HEIGHT = 600;
const int SCREEN_WIDTH = 600;
};
(And here is the Render.h file)
//Include guards.
#pragma once
//Headers.
#include "Manager.h"
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
//Namespaces.
using namespace std;
class Render
{
public:
Render(); //Constructor.
~Render(); //Destructor.
//Functions.
void Draw(int, int); //Draws texture at position.
void Load(string); //Loads texture from path.
void Deallocate(); //Destroy texture.
//Getter functions.
int GetHeight() { return Height; };
int GetWidth() { return Width; };
private:
SDL_Texture* Texture; //Actual image.
Manager manager; //Manager class.
int Height; //Height of image.
int Width; //Wdith of image.
};
So in conclusion, I am having errors related to the class objects, which I believe are being caused by circular inclusion, despite my research I have not been able to fix these issues. I would greatly appreciate any help with this issue.
P.S I know I am not supposed to use the std namespace, instead I must write std::foo, I am aware, so please don't comment about it!
In C++ "ownership" is a very important concept. A class "owns" its members. The problem is you have two objects and you've told the compiler that both "own" the other, which won't do. You have to decide which of them owns the other, and has it as a member (or maybe neither owns the other). At least one class must refer to the other, rather than listing it as a child/member. And the best sort of reference is a pointer.
class Manager;
// this forward declaration tell the compiler the class exists, but
// we don't care about the details yet, so we won't include the header.
// if we try to include it, that header refers to Render, which the compiler
// hasn't seen yet, so the compiler will fail.
class Render
{
public:
Render(Manager* parent_); //Constructor.
...stuff...
Manager* parent;
};
Cpp file:
#include "manager.h"
#include "render.h"
Render::Render(Manager* parent_)
: parent(parent_)
{}
SUGGESTIONS:
1. Eliminate the "Render.h" include:
There doesn't seem to be anything in "Manager.h" that needs anything in "Render.h" - so why include it?
Similarly, 2. Eliminate the "Manager.h" include.
You can simply use a "forward declaration", instead of including the whole class interface (.h file).
These links might help:
C++ circular include
Headers and Includes: Why and How
Okay, I think that I have solved the problem, thanks to a variety of comments. The solution may not be ellegant but it works. Instead of defining the Render Tex variabel inside the Manager header, I declared it inside the Manager.cpp class. Once I had done that I can #include "Render.h" inside the Manager .cpp file. I dont know if that explanation is clear but here is the top of the manager.h file:
//Include guards.
#pragma once
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
And here is the top of the Manager.cpp file:
//Header.
#include "Manager.h"
#include "Render.h"
//Librarys.
#include <iostream>
//Objects.
Render Tex;
While trying to make a simple game, I've run in to a circular dependency problem.
I searched on the internet and found that forward declaring could fix it, but... Both of my classes depend on a static value.
Is there any easy way to fix, perhaps to forward declare the static values, or do I have to rewrite the core of my game?
2ND EDIT: Looks like I was wrong, the error's still there even after removing almost everything:
main.cpp:
#include "App.h"
//Start the app
int main(int argc, char* args[]){
App App;
return App.on_execute();
}
App.h:
#ifndef APP_H
#define APP_H
#include "Object.h"
class App
{
public:
//Runs when the program starts
int on_execute();
};
#endif // APP_H
App.cpp:
#include "App.h"
int App::on_execute(){
return 0;
}
Object.h:
#ifndef OBJECT_H
#define OBJECT_H
#include <string>
#include <vector>
#include <stdio.h>
#include <SDL.h>
#include <math.h>
#include "Entity.h"
class Object
{
public:
Object(int character, int x, int y, std::string name, SDL_Color color, bool blocks);
//Object vector
static std::vector<Object*> objects;
};
#endif // OBJECT_H
Object.cpp:
#include "Object.h"
std::vector<Object*> Object::objects;
Object::Object(int character, int x, int y, std::string name, SDL_Color color, bool blocks){
}
Entity.h:
#ifndef ENTITY_H
#define ENTITY_H
#include "Object.h"
#include <sdl.h>
class Entity : public Object
{
public:
Entity(int character, int x, int y, std::string name, SDL_Color color, bool blocks, int hp, int power, int defense);
};
#endif // ENTITY_H
Entity.cpp:
#include "Entity.h"
Entity::Entity(int character, int x, int y, std::string name, SDL_Color color, bool blocks, int hp, int power, int defense) : Object(character, x, y, name, color, blocks){
}
I think the design of your code may need to be reworked.
First of all, I'd really discourage you from using non-primitive, non-trivial class statics where possible, whether class static or global static. Non-trivial static classes will have an explicit constructor call before main, and will need to register a destruction to be called after main. The relative ordering of these things is undefined. Worse, if you have a library structure later such that the assembly from the same .cpp file shows up twice, weird things can happen where two copies of the object get constructed, but the same one is destroyed twice.
Second, some of the information is unclear. For example, you claim that the Map class has a static member of type Map. I really don't think this is possible; the static Map member will also have an object of type map, and so on. Similarly with the vector of Objects declared inside Object. Maybe in both these cases you mean inside the file Map.cpp or Object.cpp, as opposed to literally inside the class?
Third, be clear on what forward declaration gives you. It makes the compile aware that something exists, nothing more. It lets you have pointers and references to that type. You cannot create an object or even declare a member variable of a forward declared type, because the compiler doesn't know the size of the forward declared object. You can't use its methods because the compiler doesn't know they exist.
Fourth, you didn't talk about your header files at all. It's only a circular dependency if Map.h requires Object.h, and vice versa. Two header files can't both include each other. On the other hand, the implementation is in Map.cpp and Object.cpp, both of these files can include both Map.h and Object.h. However, personally I prefer to avoid having mutually dependent classes.
What I'd probably suggest is that a Map should own the Objects present on that map. The pattern right now with Map accessing this global is not a good one. Instead of having objects be a global, make std::vector objects a member of the Map class. Notice that if you decide to have multiple Maps later, this works much better, each Map will own the Objects located on that map. The current design doesn't work well if there's more than one Map.
You can then implement move_to as a method not of Object, but rather of Map. Map::move_to(i, dx, dy) moves the ith Object.
Current program layout. The left operand includes the right one.
source.cpp
app.hpp // Also includes SFML libraries with sf namespace
game.hpp
ball.hpp
brick.hpp
plate.hpp
The implementation of ball class (ball.cpp) throws a lot of errors "sf does not name a type".
source.cpp
#include "app.hpp"
int main () {
App app(640, 480, "Arkanoid");
while (app.getWindow()->isOpen()) app.run();
return 0; }
app.hpp
#ifndef ArkanoidApp
#define ArkanoidApp
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "game.hpp"
// code
#endif
game.hpp
#ifndef ArkanoidGame
#define ArkanoidGame
#include "ball.hpp"
#include "brick.hpp"
#include "paddle.hpp"
// code
#endif
ball.hpp
#ifndef ArkanoidBall
#define ArkanoidBall
class Ball
{
public:
Ball(void);
void draw(void);
public: // Setters & getters
private: // Variables
sf::CircleShape circle; // sf is not a class type
sf::Vector2i position; // sf is not a class type
sf::Vector2f direction; // sf is not a class type
private: // Constants
int RADIUS = 8;
int VELOCITY = 6;
};
#endif
Well if your app.hpp includes the sf, of course ball.cpp wouldn't know about it and throw an error, you would need to include the sf inside the ball.cpp as well.
To avoid multiple definitions use #pragma once in your header files.
Other then that it's unclear what and why are you trying to do, if you get to a point where files should include each other it's not a very good design and should be avoided, best design is a tree one.
edit:
For now you can just include the library in every header that requires it (app, ball...).
But you may try something more complicated like MVC. And since it's a graphics library you can create a View and write all your view management there, like opening the window drawing the model etc..
What you do in MVC is a complete separation between model(game, ball) and the view, since you can display the model in different ways, one in 2D and another in 3D, each may use different library and view but the model is still the same.
There are a lot of designs and no correct one, as long as it easy to understand and maintain/add features it's a good design.
I'm Working on a project in c++, but I am native to Java and have little c++ experience. the error i am having is that Cell and CellRenderer both include each other, but I have no idea how to fix this, as they both use one another. if I remove the #include, I get errors with cell, but if I keep it the errors disappear except for the Cell includes itself. This is my code:
#include <string>
#include <iostream>
#include <allegro5\allegro.h>
#include "Cell.h"
#include "Renderer.h"
using namespace std;
class CellRenderer: public Renderer{
Cell * cell;
ALLEGRO_BITMAP * image;
public:
CellRenderer(Cell * c)
{
cell = c;
image = cell->getImage();
}
void render(int x, int y)
{
al_draw_tinted_scaled_bitmap(image, cell->getColor(),0,0,al_get_bitmap_width(image),al_get_bitmap_height(image),x-cell->getRadius(),y-cell->getRadius(),cell->getRadius()*2,cell->getRadius()*2,0);
}
bool doesRender(int x, int y, int wid, int ht)
{
int cellX = cell->getX();
int cellY = cell->getY();
int radius = cell->getRadius();
return cellX>x-radius&&cellX<x+wid+radius&&cellY>y-radius&&cellY<y+ht+radius;
}
}
class Cell{
public:
bool doesRender(int x, int y, int wid, int ht)
{
return renderer->doesRender(x,y,wid,ht);
}
void render(int x, int y)//renders with center at x,y
{
renderer->render(x,y);
}
};
any help would be greatly appreciated
You need to surround all header file you write with guard.
There are 2 solutions to do that but only the 2nd will really works with all compilers.
Visual Studio supports #pragma once. Put that on the 1st line of your header.
All compiler have a preprocessor. Surround all the text in your header file with
#ifdef ...
#define ...
other include, class declaration, etc...
#endif
Replace the ... by a unique identifier for your file; for example, I often use as a convention:
_filenameinlowercase_h_
If you already have a header guard, please make sure that you didn't included the same header file in it by mistake.
Example
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
.
.
.
#include Example.h //It should be removed
.
.
#endif
Tip for the larger related issues. Sometimes the spelling might be off and it can be troubling to see where it is setup incorrectly if you have a large project with many include files.
I find compiling one file at a time can identify where the include was setup incorrectly.