I'm trying to code a simple DirectX11 engine but I keep getting this strange error and I can't find the problem: I define a Terrain class and a Mesh class and #include the Mesh class in the Terrain class:
the Terrain class definition:
// Terrain.h
#pragma once
#include "Noise.h"
#include "Mesh.h"
class Terrain
{
public:
Terrain(float width, float depth, int numVerticesW, int numVerticesD);
~Terrain();
float GetHeight(float x, float z);
void Draw();
private:
Mesh mMesh; // I get the error on this line
Noise mNoiseGenerator;
std::vector<float> mHeights;
void CreateTerrain(float width, float depth, int numVerticesW, int numVerticesD);
float ComputeHeight(float x, float z, float startFrequency, float startAmplitude, float persistence, int octaves);
};
and the Mesh class definition:
// Mesh.h
#pragma once
#include <d3d11.h>
#include <vector>
#include "Game.h"
class Mesh
{
public:
Mesh();
~Mesh();
template <typename T, unsigned int N>
void LoadVertexBuffer(T data[][N], unsigned int size, bool dynamic = false);
void LoadIndexBuffer(std::vector<unsigned int> indices);
void SetVertexCount(unsigned int vertexCount);
void Bind();
void Draw();
private:
std::vector<ID3D11Buffer*> mVertexBuffers;
std::vector<unsigned int> mStrides;
ID3D11Buffer *mIndexBuffer;
unsigned int mVertexCount;
};
template <typename T, unsigned int N>
void Mesh::LoadVertexBuffer(T data[][N], unsigned int size, bool dynamic)
{
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_IMMUTABLE;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.ByteWidth = sizeof(T[N]) * size;
bufferDesc.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA bufferData = {};
bufferData.pSysMem = data;
ID3D11Buffer *buffer;
Game::GetInstance()->GetDevice()->CreateBuffer(&bufferDesc, &bufferData, &buffer);
mVertexBuffers.push_back(buffer);
mStrides.push_back(sizeof(T[N]));
}
When I compile the code I get:
Severity Code Description Project File Line Suppression State
Error C3646 'mMesh': unknown override specifier DirectX11 engine 0.3 c:\users\luca\desktop\programming\code\c++\source\visual studio\directx11 engine 0.3\terrain.h 14
Severity Code Description Project File Line Suppression State
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int DirectX11 engine 0.3 c:\users\luca\desktop\programming\code\c++\source\visual studio\directx11 engine 0.3\terrain.h 14
I searched the web but most results show missing semicolons or circular inclusion issues but I can't find any.
EDIT
I found the issue but I can't explain why my solution works:
following the inclusion tree:
Terrain.h --> Mesh.h --> Game.h --> Renderer.h --> Terrain.h
eliminating #include "Terrain.h" (since I just declare Terrain * pointers inside the class) and adding it to Terrain.cpp seems to solve the issue.
So it must be a matter of circular inclusion, but shouldn't I be guarded against that by using header/include guards?
Your problem is that #pragma once only prevents against double inclusion. I.e. it makes the following safe (simplified to make it obvious) :
// Terrain.cpp
#include "Terrain.h"
#include "Terrain.h"
It does not solve circular inclusion, which is far harder to solve automatically. With double inclusion, it's clear which one is first. But a circle has no begin.
Related
Mage/Interface/Context.h
#pragma once
#include <Mage/Interface/Element.h>
#include <Mage/Renderer/RenderingContext.h>
#include <Mage/Renderer/VertexBuffer.h>
#include <glm/glm.hpp>
namespace Mage {
namespace Interface {
class Context {
protected:
RenderingContext* ctx;
VertexBuffer* vbo;
glm::mat4 projection;
Mage::Interface::Frame* uiParent;
public:
Context(RenderingContext* ctx);
~Context();
void render();
Mage::Interface::Frame* createFrame();
};
}
}
Mage/Interface/Element.h
#pragma once
#include <vector>
#include <Mage/Interface/Context.h>
#include <glm/glm.hpp>
namespace Mage {
namespace Interface {
class Element {
protected:
Mage::Interface::Context* ctx;
std::vector<Element*> children;
glm::vec3 position;
float scale;
public:
virtual void draw();
void attach(Element* child) {
this->children.push_back(child);
}
inline glm::vec3 getPosition() {
return this->position;
}
float getScale() {
return this->scale;
}
};
// Frame is an untextured, single colour quad. Frame may contain other
// Elements.
class Frame : public Element {
public:
Frame();
Frame(glm::vec3 pos);
Frame(float width, float height);
Frame(glm::vec3 pos, float width, float height);
};
}
}
This gives me the following errors:
Error C2039 'Context': is not a member of 'Mage::Interface' Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
Error C2238 unexpected token(s) preceding ';' Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
Error C2143 syntax error: missing ';' before '*' Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
When I take out Mage::Interface::Context* ctx, the code compiles fine. I figured I must have missed a semi colon, but I can't see it - it all seems to check out just fine to me.
You have a circular dependency. Element.h includes Context.h and Context.h includes Element.h, that's not going to work.
The way to solve that is to forward-declare types instead of including their headers whenever you can, it'll also reduce compile times.
I have been having issues with Visual Studio 2013. I can't explain why its happening. The compile issue is shown in the pictures below.
I have one class "PhysicsEngine.cpp/h" that use the class "RigidBody.cpp/h" just fine. Once I attempt to use the RigidBody class in my Character class header, it fails to see the RigidBody class identifier. I have included "RigidBody.h" in my file, and even tried prototyping the class. Interesting enough when I delete the "RigidBody.h" header inclusion, it spits out even more errors, leading me to believe it is reading it. Is there something I'm doing wrong?
Here is the output I received as an error:
1>------ Rebuild All started: Project: SideScroller, Configuration: Debug Win32 ------
1> WorldChunkManager.cpp
1> World.cpp
1> Vector.cpp
1>e:(directory)\vector.cpp(41): warning C4244: 'argument' : conversion from 'double' to 'float', possible loss of data
1>e:(directory)\vector.cpp(48): warning C4244: 'argument' : conversion from 'double' to 'float', possible loss of data
1> Tile.cpp
1> RigidBody.cpp
1>e:(directory)\character.h(21): error C2146: syntax error : missing ';' before identifier 'pos'
1>e:(directory)\character.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:(directory)\character.h(21): error C2143: syntax error : missing ';' before '='
1>e:(directory)\character.h(21): error C2238: unexpected token(s) preceding ';'
Here is the code for the RigidBody.h
#ifndef RH
#define RH
#include "Vector.h"
#include "World.h"
#include <cmath>
#include <list>
class RigidBody
{
private:
int id;
float gravityFactor;
float airResistFactor;
float mass;
float elasticity;
Vector pos = Vector(0, 0);
int width;
int height;
Vector velocity = Vector(0, 0);
std::list<Vector>* additiveVelocities;
std::list<Vector>* forces;
public:
RigidBody(int x, int y, int w, int h, float mass, float elasticity, float gravityFactor, float airResistFactor);
~RigidBody();
static int rigidBodyCount;
//Get/Set
int getID();
double getX();
double getY();
float getGravFact();
float getAirFact();
float getMass();
float getElast();
Vector getPos();
Vector getVelocity();
std::list<Vector>* getadditiveVelocities();
std::list<Vector>* getForces();
void setX(double x);
void setY(double y);
void setVelocity(Vector& vec);
void setPos(Vector& vec);
//Interactino Functions
void addForce(Vector force);
void addVelocity(Vector velocity);
};
#endif
Here is the code that will not work (Character.h):
#ifndef CHARACTER_H
#define CHARACTER_H
#include "SDL.h"
#include "Camera.h"
#include "InputManager.h"
#include "Vector.h"
#include "RigidBody.h"
//TEMP DIM
const int CHAR_H = 64;
const int CHAR_W = 12;
class Character
{
private:
double speed;
//Vector pos = Vector(0, 0);
RigidBody pos = RigidBody(0, 0, CHAR_W, CHAR_H, 50, 0, 1, 1);
InputManager* inputPtr;
public:
Character(int x, int y, InputManager* inputPtr);
void getXY(int* dest);
void getChXY(int* dest);
void getCenterXY(int* dest);
//Update
void update(long double last);
bool isFloor();
//Draw
void draw(SDL_Surface* screen, Camera* camPtr);
};
#endif
Let me know if there is anything additional you could need to find the problem!!! I don't want to overload the page with potentially irreverent information. Thank you!
I think the problem with this line isn't that it's failing to find an identifier:
RigidBody pos = RigidBody(0, 0, CHAR_W, CHAR_H, 50, 0, 1, 1);
Rather, it's that you're trying to do an illegal initialization, in a C#-type way. You can't just assign a value to a class member as part of its declaration like that in C++. You need to assign the initial value in the constructor, or in an initializer attached to the constructor.
I have a .cu file that when compiled on its own, right click and select compile, it compiles just fine, but when I have another header file, a c++ header file, that calls this .cu file the build fails. The .cu file properties have been edited to build with the CUDA compiler. The errors that I am getting are 'blockIdx': undeclared identifier 'blockDim': undeclared identifier, etc.. basically errors that I would expect compiling cuda code with a c++ compiler. So is it possible to include a .cu cuda code in a c++ header?
Here is the .cu file:
Matrix.cu
#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_device_runtime_api.h>
#define BLOCKSIZE 32
using namespace std;
template<typename T> class Matrix
{
public:
typedef T value_type;
~Matrix();
Matrix();
Matrix(int rows, int columns);
int height;
int width;
int stride;
size_t size;
void CreateIdentity(Matrix<T>&I);
private:
vector<T> elements;
T* firstElement;
};
template<typename T>
Matrix<T>::~Matrix()
{
}
template<typename T>
Matrix<T>::Matrix()
{
}
template<typename T>
Matrix<T>::Matrix(int rows, int columns)
{
height = rows;
width = columns;
stride = columns; //in row major order this is equal to the # of columns
elements.resize(rows*columns);
firstElement = elements.data();
size = height*width*sizeof(T);
}
__global__ void IdentityMatrixKernel(float* identity, int size)
{
int index_x = blockIdx.x * blockDim.x + threadIdx.x;
int index_y = blockIdx.y * blockDim.y + threadIdx.y;
// map the two 2D indices to a single linear, 1D index
int grid_width = gridDim.x * blockDim.x;
int index = index_y * grid_width + index_x;
// map the two 2D block indices to a single linear, 1D block index
//int result = blockIdx.y * gridDim.x + blockIdx.x;
// write out the result
if (index % (size+1))
{
identity[index] = 0;
}
else
{
identity[index] = 1;
}
}
template<typename T>
void Matrix<T>::CreateIdentity(Matrix<T>&I)
{
float* d_I;
int size1 = I.height;
int size2 = I.height*I.width*sizeof(float);
cudaMalloc(&d_I,size2);
dim3 block_size;
block_size.x = BLOCKSIZE;
block_size.y = BLOCKSIZE;
dim3 grid_size;
grid_size.x = size1/ block_size.x + 1;
grid_size.y = size1/ block_size.y + 1;
IdentityMatrixKernel<<<block_size,grid_size>>>(d_I,size1);
cudaMemcpy(I.GetPointer(),d_I,size2,cudaMemcpyDeviceToHost);
cudaFree(d_I);
}
And here is the header file that #include "Matrix.cu"
Element.h
#pragma once
#include "Matrix.cu"
#include <vector>
using namespace std;
class Element
{
public:
Element(void);
~Element(void);
Element(int iD, float k, vector<int> nodes);
Element(int iD, vector<int> nodes, int pId);
void SetElementType(DOF type);
DOF GetElementType();
int GetNodeId(int index);
int GetNodesPerElement();
int GetPartId();
void CalculateShapeFunctions(Matrix<int> spaceCoordinates);
void CalculateSShapeDerivative(Matrix<int> spaceCoordinates);
void CalculateTShapeDerivative(Matrix<int> spaceCoordinates);
Matrix<float> GetShapeFunctions();
float GetSShapeDerivative(int row, int column);
float GetTShapeDerivative(int row, int column);
void SetStrainDisplacement(Matrix<float> B);
Matrix<float> GetStrainDisplacement();
private:
int elementId;
float stiffness;
vector<int> nodeIds;
DOF elementType;
int partId;
Matrix<float> shapeFunctions;
Matrix<float> sShapeDerivative;
Matrix<float> tShapeDerivative;
Matrix<float> strainDisplacement;
};
EDIT:
So I have been directed to try and separate the template class member functions implementing cuda into a .cu file while keeping the template class definition and any template member functions not using cuda in the original header file. This does seem on the right path, c++ compiler compiles the .h file while the cuda compiler does the .cu, but I am having trouble getting rid of link errors. I understand that I need to explicitly instantiate my template class for the types I need in the .cu file to avoid link errors, but I seem to still get them.
I instantiated my template class at the end of the .cu file as follows:
template class Matrix<float>;
template class Matrix<int>;
template class Matrix<string>;
I am now getting link errors to the template member functions using cuda.
Answer: .cu files cannot be used as #include "file.cu" like header files because they will be compiled with the C++ compiler not cuda. The solution was to move anything implementing cuda into a separate .cu file while still keeping the definitions of the template functions inside the template class definition in the header, and adding an #include "file.h" in the file.cu. To solve any link errors with the template function declarations that were moved to a .cu file, an explicit instantiation of the template class was added to the bottom of the header file. Since only float types were used in the template functions using cuda, only an instantiation of type float was added: template class Matrix. The above solution compiled and ran perfectly.
I am trying to create a vector of custom objects defined in a header file and then initialize them in the actual cpp file. I'm getting the following errors in Visual Studio:
error C2976: 'std::vector' : too few template arguments
error C2065: 'Particle' : undeclared identifier
error C2059: syntax error : '>'
In the code below, the vector is defined in Explosion.h.
Particle.h:
#pragma once
class Particle : public sf::CircleShape {
public:
float speed;
bool alive;
float vx;
float vy;
Particle(float x, float y, float vx, float vy, sf::Color color);
~Particle();
};
Particle.cpp:
#include <SFML/Graphics.hpp>
#include "Particle.h"
Particle::Particle(float x, float y, float vx, float vy, sf::Color color) {
// Inherited
this->setPosition(x, y);
this->setRadius(5);
this->setFillColor(color);
// Player Defined Variables
this->speed = (float).05;
this->alive = true;
this->vx = vx;
this->vy = vy;
}
Particle::~Particle() {
}
Explosion.h:
static const int NUM_PARTICLES = 6;
#pragma once
class Explosion {
public:
std::vector<Particle*> particles;
bool alive;
Explosion();
~Explosion();
};
Explosion.cpp:
#include <SFML/Graphics.hpp>
#include "Particle.h"
#include "Explosion.h"
Explosion::Explosion() {
this->alive = true;
// Add Particles to vector
for (int i = 0; i < NUM_PARTICLES; i++) {
this->particles.push_back(new Particle(0, 0, 0, 0, sf::Color::Red));
}
}
Explosion::~Explosion() {
}
I'm sure there is something fundamentally wrong here since C++ is fairly new to me.
You need to tell Explosion.h what a Particle is.
In this case, Explosion.h is using Particle*, so a forward declartion will suffice.
Explosion.h
class Particle; // forward declaration of Particle
class Explosion {
// ...
};
You could also simply #include "Particle.h, however as your projects increase using forward declarations (instead of direct includes) can significantly reduce your build times.
#pragma once
#include "LudoCore/Singleton.h"
class LudoTimer : public Singleton<LudoTimer>
{
friend class Singleton<LudoTimer>;
public:
void Update();
void ShortenDay();
void LengthenDay();
UINT64 GetDeltaTime() const;
float GetPercentageOfDayElapsed() const;
private:
LudoTimer();
~LudoTimer();
UINT64 GetTickCount64() const;
UINT64 GetElapsedSeconds() const;
UINT64 m_DeltaTime;
// Tick Count
UINT64 m_CurrFrameTick;
UINT64 m_LastFrameTick;
int m_SecondsInADay;
static const int SHORTEST_POSSIBLE_DAY = 60;
static const int LONGEST_POSSIBLE_DAY = 86400;
static const int CHANGING_INTERVAL = 600;
};
To me, the above code looks normal. However, I'm new to C++ so I may be missing some nuance. I'm getting a bunch of compiler errors from it, such as:
error C2447: '{' : missing function header (old-style formal list?)
and
error C2236: unexpected 'class'
'LudoTimer'. Did you forget a ';'?
What gives!
Have a look in the other header (LudoCore/Singleton.h). The second error implies that the error is before the class LudoTimer declaration at the top.
My guess is that Singleton.h defines a class, and there's a missing ';' after that class definition.
The error is probably in LudoCore/Singleton.h or something else included earlier. Make sure your class definitions have ; semicolons after them and all that.
Quick test: comment out the #include and stick a template<class C> class Singleton; predeclaration there instead. If the compiler now complains about incomplete types, I'm right, and if not, post more details.
Well, the following compiles fine for me, so the error is very likely not in the code you showed us. I suggest you have a second look at Mike's suggestion that there is an error in Singleton.h.
//#include "LudoCore/Singleton.h"
#include <windows.h>
template< typename T >
class Singleton {};
class LudoTimer : public Singleton<LudoTimer>
{
friend class Singleton<LudoTimer>;
public:
void Update();
void ShortenDay();
void LengthenDay();
UINT64 GetDeltaTime() const;
float GetPercentageOfDayElapsed() const;
private:
LudoTimer();
~LudoTimer();
UINT64 GetTickCount64() const;
UINT64 GetElapsedSeconds() const;
UINT64 m_DeltaTime;
// Tick Count
UINT64 m_CurrFrameTick;
UINT64 m_LastFrameTick;
int m_SecondsInADay;
static const int SHORTEST_POSSIBLE_DAY = 60;
static const int LONGEST_POSSIBLE_DAY = 86400;
static const int CHANGING_INTERVAL = 600;
};
I was wondering if LudoTimer is declared at the point that it is used by Singleton and if a forward declaration would help? I didn't need one in VisualStudio 2005 and like sbi I could compile the code by supplying a declaration of Singleton. If I added a simplistic implementation I could even do:
LudoTimer* timer = Singleton<LudoTimer>::instance();
One more thing:
error C2236: unexpected 'class' 'LudoTimer'. Did you forget a ';'?
You could try adding a semicolon on a blank line after the #include to answer this question. If it helps then you can show that there is a problem in the header file without needing to edit it.