Jump to content

  • Log In with Google      Sign In   
  • Create Account

Passing an object to another class


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
17 replies to this topic

#1 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 01:29 PM

Hey gamedev,
I am extremely rusty with my C++ skills. I want to pass my camera object to the terrain class, so I can cull some subgrids from my view frustrum.
So, my initial idea was to pass the camera in the terrain constructor.
I have my camera declared like this:
Camera	 g_Camera;
and after I initialize the camera I call the constructor for my terrain.
I am really unsure how I should accomplish this, but I would save a "Camera &" in my terrain class and just pass over the reference in the constructor. But I get these errors:

1>c:\***\thegame\terrain.cpp(13): error C2758: 'Terrain::mCamera' : must be initialized in constructor base/member initializer list
1>		  c:\***\thegame\terrain.h(72) : see declaration of 'Terrain::mCamera'
1>c:\***\thegame\terrain.cpp(128): error C2327: 'Terrain::mCamera' : is not a type name, static, or enumerator
1>c:\***\thegame\terrain.cpp(128): error C2065: 'mCamera' : undeclared identifier
1>c:\***\thegame\terrain.cpp(128): error C2228: left of '.getPos' must have class/struct/union
1>		  type is ''unknown-type''

Can anyone outline the correct way to do this? [Full code below]

Sponsor:

#2 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 01:36 PM

References must be initialized when defined, however this doesn't work for non-static members, thus you must initialize the reference in the class initializer list.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#3 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 01:58 PM

References must be initialized when defined, however this doesn't work for non-static members, thus you must initialize the reference in the class initializer list.


Let's say I have :
Terrain::Terrain(****, Camera & cam) //terrain.cpp
and I call it this way:
g_Terrain = new Terrain(****, &g_Camera); //main.cpp

Changing it to:
Terrain::Terrain(****, Camera & cam):m_Camera(cam) // terrain.cpp
does not help, where m_Camera is declared like this
Camera & m_Camera; // terrain.h


#4 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 02:01 PM

Well, seeing as how you havent really posted much code, I can't tell you what's wrong. Although the error messages do suggest that it doesn't know what a "Camera" is, perhaps you're missing a header include.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#5 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 02:17 PM

// main.cpp
#include "Camera.h"
#include "Terrain.h"
//declarations
Camera g_Camera;		
Terrain* g_Terrain;
// before the game loop in the main function...
g_Camera = Camera(tbVector3(0.0f,30.0f,0.0f));
g_Terrain = new Terrain(/*uninteresting stuff*/ g_Camera);

// camera.h
// contains uninteresting stuff..

// terrain.h
#ifndef TERRAIN_H
#define TERRAIN_H
#include "Heightmap.h"
#include "d3dUtil.h"
#include "Vertex.h"
class Camera;
class Terrain
{
public:
Terrain(/*uninteresting*/ Camera & cam);
~Terrain();
private:
Camera & g_Camera;
};
#endif // TERRAIN_H

//terrain.cpp
#include "Terrain.h"
#include "d3dUtil.h"
#include <list>
Terrain::Terrain(*/uninteresting*/ Camera & cam)
{
g_Camera = cam;
}


#6 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 02:19 PM

You didn't include camera in your terain.cpp. The definition of the incomplete type of Camera is required by then.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#7 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 02:39 PM

You didn't include camera in your terain.cpp. The definition of the incomplete type of Camera is required by then.

I don't need to include the camera because of the forward declaration: terrain is not a parent of camera and it does not contain a camera object, but a reference.
Nevertheless, I switched to '#include "Camera.h"' and I get the exact same error.

#8 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 02:43 PM

You need the definition of the camera class at the time of construction because incomplete types (which is what a forward decleration is) cannot be constructed.

Regardless of that, this line:
g_Camera = cam;

Is incorrect.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#9 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 02:52 PM

1>c:\***\thegame\terrain.cpp(13): error C2758: 'Terrain::mCamera' : must be initialized in constructor base/member initializer list
1>                c:\***\thegame\terrain.h(72) : see declaration of 'Terrain::mCamera'
This tells you that you need to initialize the reference in the initializer list of the constructor.
1>c:\***\thegame\terrain.cpp(128): error C2327: 'Terrain::mCamera' : is not a type name, static, or enumerator
1>c:\***\thegame\terrain.cpp(128): error C2065: 'mCamera' : undeclared identifier
1>c:\***\thegame\terrain.cpp(128): error C2228: left of '.getPos' must have class/struct/union
1>                type is ''unknown-type''
Without seeing the code here, I can't tell you exactly what's going on here, however it basically is just telling you that it has no idea what mCamera is, its not encountered it within the current name scope. The code you pasted is, pretty much, useless.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#10 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 03:19 PM

Well I took out everything that is not part of the problem. Here's the complete source code of terrain:

#ifndef TERRAIN_H
#define TERRAIN_H
#include "Heightmap.h"
#include "d3dUtil.h"
#include "Vertex.h"
#include "Camera.h"
class Terrain
{
public:
Terrain(UINT vertRows, UINT vertCols, float dx, float dz,
  char * heightmap, char * tex0, char *tex1,
  char * tex2, char * blendMap, float heightScale,
  float yOffset, Camera & cam);
~Terrain();
DWORD getNumTriangles();
DWORD getNumVertices();
float getWidth();
float getDepth();
void onLostDevice();
void onResetDevice();
// (x, z) relative to terrain's local space.
float getHeight(float x, float z);

void setDirToSunW(const D3DXVECTOR3& d);
void draw(D3DXMATRIX& view, D3DXMATRIX& proj);
private:
void buildGeometry();
void buildSubGridMesh(RECT& R, VertexPNT* gridVerts);
void buildEffect();

Camera & mCamera;
struct SubGrid
{
  ID3DXMesh* mesh;
  AABB box;
  // For sorting.
  bool operator<(const SubGrid& rhs)const;
  const static int NUM_ROWS  = 33;
  const static int NUM_COLS  = 33;
  const static int NUM_TRIS  = (NUM_ROWS-1)*(NUM_COLS-1)*2;
  const static int NUM_VERTS = NUM_ROWS*NUM_COLS;
};
private:
Heightmap mHeightmap;
std::vector<SubGrid> mSubGrids;
DWORD mVertRows;
DWORD mVertCols;
float mWidth;
float mDepth;
float mDX;
float mDZ;
IDirect3DTexture9* mTex0;
IDirect3DTexture9* mTex1;
IDirect3DTexture9* mTex2;
IDirect3DTexture9* mBlendMap;
ID3DXEffect*	   mFX;
D3DXHANDLE		 mhTech;
D3DXHANDLE		 mhViewProj;
D3DXHANDLE		 mhDirToSunW;
D3DXHANDLE		 mhTex0;
D3DXHANDLE		 mhTex1;
D3DXHANDLE		 mhTex2;
D3DXHANDLE		 mhBlendMap;
};
#endif // TERRAIN_H

I marked the errors down below.

#include "Terrain.h"
#include <list>
Terrain::Terrain(UINT vertRows, UINT vertCols, float dx, float dz,
  char * heightmap, char *tex0, char *tex1,
  char * tex2, char *blendMap, float heightScale,
  float yOffset, Camera & cam):mCamera(cam) // <--- Like this?
{
mVertRows = vertRows;
mVertCols = vertCols;
mDX = dx;
mDZ = dz;
mWidth = (mVertCols-1)*mDX;
mDepth = (mVertRows-1)*mDZ;
mHeightmap.loadRAW(vertRows, vertCols, heightmap, heightScale, yOffset);
tbTextureManager& tm = tbTextureManager::Instance();
mBlendMap = tm.GetTexture(blendMap);
mTex0 = tm.GetTexture(tex0);
mTex1 = tm.GetTexture(tex1);
mTex2 = tm.GetTexture(tex2);
buildGeometry();
buildEffect();
}
Terrain::~Terrain()
{
for(UINT i = 0; i < mSubGrids.size(); ++i)
  ReleaseCOM(mSubGrids[i].mesh);
ReleaseCOM(mFX);
ReleaseCOM(mTex0);
ReleaseCOM(mTex1);
ReleaseCOM(mTex2);
ReleaseCOM(mBlendMap);
}
DWORD Terrain::getNumTriangles()
{
return (DWORD)mSubGrids.size()*mSubGrids[0].mesh->GetNumFaces();
}
DWORD Terrain::getNumVertices()
{
return (DWORD)mSubGrids.size()*mSubGrids[0].mesh->GetNumVertices();
}
float Terrain::getWidth()
{
return mWidth;
}
float Terrain::getDepth()
{
return mDepth;
}
void Terrain::onLostDevice()
{
HR(mFX->OnLostDevice());
}
void Terrain::onResetDevice()
{
HR(mFX->OnResetDevice());
}
float Terrain::getHeight(float x, float z)
{
// Transform from terrain local space to "cell" space.
float c = (x + 0.5f*mWidth) /  mDX;
float d = (z - 0.5f*mDepth) / -mDZ;
// Get the row and column we are in.
int row = (int)floorf(d);
int col = (int)floorf(c);
// Grab the heights of the cell we are in.
// A*--*B
//  | /|
//  |/ |
// C*--*D
float A = mHeightmap(row, col);
float B = mHeightmap(row, col+1);
float C = mHeightmap(row+1, col);
float D = mHeightmap(row+1, col+1);
// Where we are relative to the cell.
float s = c - (float)col;
float t = d - (float)row;
// If upper triangle ABC.
if(t < 1.0f - s)
{
  float uy = B - A;
  float vy = C - A;
  return A + s*uy + t*vy;
}
else // lower triangle DCB.
{
  float uy = C - D;
  float vy = B - D;
  return D + (1.0f-s)*uy + (1.0f-t)*vy;
}
}
void Terrain::setDirToSunW(const D3DXVECTOR3& d)
{
HR(mFX->SetValue(mhDirToSunW, &d, sizeof(D3DXVECTOR3)));
}

bool Terrain::SubGrid::operator<(const SubGrid& rhs) const
{
D3DXVECTOR3 d1 = box.center() - mCamera->getPos().vD3DVector;  // ERROR
D3DXVECTOR3 d2 = rhs.box.center() - mCamera->getPos().vD3DVector; // ERROR
return D3DXVec3LengthSq(&d1) < D3DXVec3LengthSq(&d2);
}
void Terrain::draw(D3DXMATRIX& view, D3DXMATRIX& proj)
{
// Frustum cull sub-grids.
std::list<SubGrid> visibleSubGrids;
for(UINT i = 0; i < mSubGrids.size(); ++i)
{
  if( mCamera->isVisible(mSubGrids[i].box) ) // ERROR
   visibleSubGrids.push_back(mSubGrids[i]);
}
// Sort front-to-back from camera.
visibleSubGrids.sort();
HR(mFX->SetMatrix(mhViewProj, &(view*proj)));
HR(mFX->SetTechnique(mhTech));
UINT numPasses = 0;
HR(mFX->Begin(&numPasses, 0));
HR(mFX->BeginPass(0));
for(std::list<SubGrid>::iterator iter = visibleSubGrids.begin(); iter != visibleSubGrids.end(); ++iter)
  HR(iter->mesh->DrawSubset(0));
HR(mFX->EndPass());
HR(mFX->End());
}
void Terrain::buildGeometry()
{
//===============================================================
// Create one large mesh for the grid in system memory.
DWORD numTris  = (mVertRows-1)*(mVertCols-1)*2;
DWORD numVerts = mVertRows*mVertCols;
ID3DXMesh* mesh = 0;
D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
UINT numElems = 0;
HR(VertexPNT::Decl->GetDeclaration(elems, &numElems));
// Use Scratch pool since we are using this mesh purely for some CPU work,
// which will be used to create the sub-grids that the graphics card
// will actually draw.
HR(D3DXCreateMesh(numTris, numVerts,
  D3DPOOL_SCRATCH|D3DXMESH_32BIT, elems, tbDirect3D::Instance().GetDevice(), &mesh));

//===============================================================
// Write the grid vertices and triangles to the mesh.
VertexPNT* v = 0;
HR(mesh->LockVertexBuffer(0, (void**)&v));

std::vector<D3DXVECTOR3> verts;
std::vector<DWORD> indices;
GenTriGrid(mVertRows, mVertCols, mDX, mDZ, D3DXVECTOR3(0.0f, 0.0f, 0.0f), verts, indices);
float w = mWidth;
float d = mDepth;
for(UINT i = 0; i < mesh->GetNumVertices(); ++i)
{
  // We store the grid vertices in a linear array, but we can
  // convert the linear array index to an (r, c) matrix index.
  int r = i / mVertCols;
  int c = i % mVertCols;
  v[i].pos   = verts[i];
  v[i].pos.y = mHeightmap(r, c);
  v[i].tex0.x = (v[i].pos.x + (0.5f*w)) / w;
  v[i].tex0.y = (v[i].pos.z - (0.5f*d)) / -d;
}
// Write triangle data so we can compute normals.
DWORD* indexBuffPtr = 0;
HR(mesh->LockIndexBuffer(0, (void**)&indexBuffPtr));
for(UINT i = 0; i < mesh->GetNumFaces(); ++i)
{
  indexBuffPtr[i*3+0] = indices[i*3+0];
  indexBuffPtr[i*3+1] = indices[i*3+1];
  indexBuffPtr[i*3+2] = indices[i*3+2];
}
HR(mesh->UnlockIndexBuffer());
// Compute Vertex Normals.
HR(D3DXComputeNormals(mesh, 0));

//===============================================================
// Now break the grid up into subgrid meshes.
// Find out the number of subgrids we'll have.  For example, if
// m = 513, n = 257, SUBGRID_VERT_ROWS = SUBGRID_VERT_COLS = 33,
// then subGridRows = 512/32 = 16 and sibGridCols = 256/32 = 8.
int subGridRows = (mVertRows-1) / (SubGrid::NUM_ROWS-1);
int subGridCols = (mVertCols-1) / (SubGrid::NUM_COLS-1);
for(int r = 0; r < subGridRows; ++r)
{
  for(int c = 0; c < subGridCols; ++c)
  {
   // Rectangle that indicates (via matrix indices ij) the
   // portion of grid vertices to use for this subgrid.
   RECT R =
   {
	 c * (SubGrid::NUM_COLS-1),
	 r * (SubGrid::NUM_ROWS-1),
	(c+1) * (SubGrid::NUM_COLS-1),
	(r+1) * (SubGrid::NUM_ROWS-1)
   };
   buildSubGridMesh(R, v);
  }
}
HR(mesh->UnlockVertexBuffer());
ReleaseCOM(mesh); // Done with global mesh.
}
void Terrain::buildSubGridMesh(RECT& R, VertexPNT* gridVerts)
{
//===============================================================
// Get indices for subgrid (we don't use the verts here--the verts
// are given by the parameter gridVerts).
std::vector<D3DXVECTOR3> tempVerts;
std::vector<DWORD> tempIndices;
GenTriGrid(SubGrid::NUM_ROWS, SubGrid::NUM_COLS, mDX, mDZ,
  D3DXVECTOR3(0.0f, 0.0f, 0.0f), tempVerts, tempIndices);
ID3DXMesh* subMesh = 0;
D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
UINT numElems = 0;
HR(VertexPNT::Decl->GetDeclaration(elems, &numElems));
HR(D3DXCreateMesh(SubGrid::NUM_TRIS, SubGrid::NUM_VERTS,
  D3DXMESH_MANAGED, elems, tbDirect3D::Instance().GetDevice(), &subMesh));

//===============================================================
// Build Vertex Buffer.  Copy rectangle of vertices from the
// grid into the subgrid structure.
VertexPNT* v = 0;
HR(subMesh->LockVertexBuffer(0, (void**)&v));
int k = 0;
for(int i = R.top; i <= R.bottom; ++i)
{
  for(int j = R.left; j <= R.right; ++j)
  {
   v[k++] = gridVerts[i*mVertCols+j];
  }
}
//===============================================================
// Compute the bounding box before unlocking the vertex buffer.
AABB bndBox;
HR(D3DXComputeBoundingBox((D3DXVECTOR3*)v, subMesh->GetNumVertices(),
  sizeof(VertexPNT), &bndBox.minPt, &bndBox.maxPt));
HR(subMesh->UnlockVertexBuffer());

//===============================================================
// Build Index and Attribute Buffer.
WORD* indices  = 0;
DWORD* attBuff = 0;
HR(subMesh->LockIndexBuffer(0, (void**)&indices));
HR(subMesh->LockAttributeBuffer(0, &attBuff));
for(int i = 0; i < SubGrid::NUM_TRIS; ++i)
{
  indices[i*3+0] = (WORD)tempIndices[i*3+0];
  indices[i*3+1] = (WORD)tempIndices[i*3+1];
  indices[i*3+2] = (WORD)tempIndices[i*3+2];
  attBuff[i] = 0; // All in subset 0.
}
HR(subMesh->UnlockIndexBuffer());
HR(subMesh->UnlockAttributeBuffer());

//===============================================================
// Optimize for the vertex cache and build attribute table.
DWORD* adj = new DWORD[subMesh->GetNumFaces()*3];
HR(subMesh->GenerateAdjacency(EPSILON, adj));
HR(subMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE|D3DXMESHOPT_ATTRSORT,
  adj, 0, 0, 0));
delete[] adj;

//===============================================================
// Save the mesh and bounding box.
SubGrid g;
g.mesh = subMesh;
g.box  = bndBox;
mSubGrids.push_back(g);
}
void Terrain::buildEffect()
{
ID3DXBuffer* errors = 0;
HR(D3DXCreateEffectFromFile(tbDirect3D::Instance().GetDevice(), "Terrain.fx",
  0, 0, D3DXSHADER_DEBUG, 0, &mFX, &errors));
if( errors )
  MessageBox(0, (char*)errors->GetBufferPointer(), 0, 0);
mhTech	  = mFX->GetTechniqueByName("TerrainTech");
mhViewProj  = mFX->GetParameterByName(0, "gViewProj");
mhDirToSunW = mFX->GetParameterByName(0, "gDirToSunW");
mhTex0	  = mFX->GetParameterByName(0, "gTex0");
mhTex1	  = mFX->GetParameterByName(0, "gTex1");
mhTex2	  = mFX->GetParameterByName(0, "gTex2");
mhBlendMap  = mFX->GetParameterByName(0, "gBlendMap");
HR(mFX->SetTexture(mhTex0, mTex0));
HR(mFX->SetTexture(mhTex1, mTex1));
HR(mFX->SetTexture(mhTex2, mTex2));
HR(mFX->SetTexture(mhBlendMap, mBlendMap));
}

Main (beware of German commentary! InitTerrain plays a key role here.)
// ===================
// Hier werden die Direct3D-Klassen der TriBase-Engine angewandt.
#include <TriBase.h>
#include "Resource.h"
#include "Config.h"
#include "Vertex.h"
#include "Camera.h"
#include "GameObject.h"
#include "Terrain.h"
// ******************************************************************
// Globale Variablen
tbConfig	g_Config;	 // Konfigurationsstruktur
PDIRECT3DCUBETEXTURE9 g_pEnvMap = NULL;   // Umgebungstextur
tbEffect*	g_pSkyBoxEffect = NULL;  // Sky-Box-Effekt
tbVertexBuffer*   g_pSkyBoxVB = NULL;   // Sky-Box-Vertex-Buffer
tbIndexBuffer*   g_pSkyBoxIB = NULL;   // Sky-Box-Index-Buffer
tbFont*	 g_pFont1 = NULL;   // Erste Schriftart
float	 g_fTime = 0.0f;	// Globaler Zeitzähler
Camera	 g_Camera;	  /// Kamera
GameObject*	g_Cube;	   /// Würfel
Terrain*	g_Terrain;	  /// Landschaft
tbModel*	g_pDuckModel;	 /// Platzhaltermodell
// ******************************************************************
// Die Move-Funktion
tbResult MoveProc(float fNumSecsPassed)
{
tbVector3 vCameraDir;
// Den Zeitzähler aktualisieren
g_fTime += fNumSecsPassed;
// Input
//---------------------------------------------------------------
g_Cube->UpdateInput(fNumSecsPassed);
g_Camera.moveCamera(g_Cube->Position, fNumSecsPassed);
// Physics
// --------------------------------------------------------------
//g_Terrain->setDirToSunW(D3DXVECTOR3(cos(fNumSecsPassed), sin(fNumSecsPassed) , 0.0f)); // looks nice
g_Cube->UpdatePhysics(g_Terrain, fNumSecsPassed);

return TB_OK;
}
// ******************************************************************
// Die Render-Funktion
tbResult RenderProc(float fNumSecsPassed)
{
tbMatrix mWorld;
int   iNumPasses;

tbDirect3D& D3D = tbDirect3D::Instance();

//Z-Buffer clearen, Skybox überschreibt das Bild
D3D->Clear(0,NULL, D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0, 0,0), 1.0f, 0);
// Die Szene beginnen
D3D->BeginScene();
// ------------------------------------------------------------------
g_Camera.setUpCamera();
// ------------------------------------------------------------------

// Z-Buffer deaktivieren, Dithering aktivieren
D3D.SetRS(D3DRS_ZENABLE, FALSE);
D3D.SetRS(D3DRS_DITHERENABLE, TRUE);
// Die Umgebungstextur setzen
D3D.SetTexture(0, g_pEnvMap);
D3D.SetTSS(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
// Weltmatrix erstellen, die die Sky-Box zur Kamera hin schiebt
mWorld = tbMatrixTranslation(g_Camera.getPos());
D3D.SetTransform(D3DTS_WORLD, mWorld);
// Vertex- und Index-Buffer aktivieren und das Vertexformat setzen
D3D->SetStreamSource(0, g_pSkyBoxVB->GetVB(), 0, sizeof(SSkyBoxVertex));
D3D->SetIndices(g_pSkyBoxIB->GetIB());
D3D.SetFVF(SSkyBoxVertex::dwFVF);
// Zeichnen!
iNumPasses = g_pSkyBoxEffect->Begin();
for(int iPass = 0; iPass < iNumPasses; iPass++)
{
  g_pSkyBoxEffect->Pass(iPass);
  D3D->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
}
g_pSkyBoxEffect->End();
//-------------------------------------------------------------------
D3D.SetRS(D3DRS_ZENABLE, TRUE);
g_Terrain->draw((D3DXMATRIX&) g_Camera.getViewMatrix(), (D3DXMATRIX&) g_Camera.getProjMatrix() );
//-------------------------------------------------------------------
g_Cube->UpdateGraphics(g_fTime);
//-------------------------------------------------------------------
///ENTE
D3DLIGHT9 Light;
// Ein Richtungslicht erstellen mit der Richtung der Kamera
ZeroMemory(&Light, sizeof(D3DLIGHT9));
Light.Type = D3DLIGHT_DIRECTIONAL;
Light.Diffuse = tbColor(0.5f, 0.5f, 0.5f);
Light.Ambient = tbColor(0.5f, 0.5f, 0.5f);
Light.Specular = tbColor(0.5f, 0.5f, 0.5f);
Light.Direction = g_Camera.getTarget();
D3D->SetLight(0, &Light);
D3D->LightEnable(0, TRUE);
// Weltmatrix zurücksetzen
D3D.SetTransform(D3DTS_WORLD, tbMatrixIdentity());
D3D.SetRS(D3DRS_LIGHTING, TRUE);
g_pDuckModel->Render(-1, -1, TRUE, FALSE);
//-------------------------------------------------------------------
// Debug-Hilfen
char acText[256]; // Speichert die Nachricht
tbVector3 camPos = g_Camera.getPos();
g_pFont1->Begin();
sprintf(acText, "Camera: %.2f | %.2f | %.2f", camPos.x, camPos.y, camPos.z);
g_pFont1->DrawTextA(tbVector2(10.0f,10.0f), acText);
sprintf(acText, "Player: %.2f | %.2f | %.2f", g_Cube->Position.x, g_Cube->Position.y, g_Cube->Position.z);
g_pFont1->DrawTextA(tbVector2(10.0f,30.0f), acText);

switch(g_Camera.getMode())
{
case FREE_FLYING: {sprintf(acText, "Camera mode: Free flying"); break;}  
case BIRDS_EYE_PLAYER: {sprintf(acText, "Camera mode: Bird's eye on player"); break;}
case FOLLOW_PLAYER: {sprintf(acText, "Camera mode: Follow player"); break;}  
case FOLLOW_PLAYER_LEFT: {sprintf(acText, "Camera mode: Follow left of player"); break;}	
case FOLLOW_PLAYER_RIGHT: {sprintf(acText, "Camera mode: Follow Right of player"); break;}
}
g_pFont1->DrawTextA(tbVector2(10.0f,50.0f), acText);
g_pFont1->End();
// ------------------------------------------------------------------
// Szene beenden
D3D->EndScene();
return TB_OK;
}
// ******************************************************************
// Initialisierung der Sky-Box
tbResult InitSkyBox()
{
SSkyBoxVertex aVertex[8];
// Vertex- und Index-Buffer erstellen. 8 Vertizes, 36 Indizes.
g_pSkyBoxVB = new tbVertexBuffer;
if(g_pSkyBoxVB->Init(8 * sizeof(SSkyBoxVertex), sizeof(SSkyBoxVertex), SSkyBoxVertex::dwFVF,
				   D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT))
{
  // Fehler!
  return TB_ERROR;
}
// Nun der Index-Buffer (16 Bits pro Index)
g_pSkyBoxIB = new tbIndexBuffer;
if(g_pSkyBoxIB->Init(36 * sizeof(WORD), sizeof(WORD), D3DFMT_INDEX16))
{
  // Fehler!
  return TB_ERROR;
}
// ------------------------------------------------------------------
// Die Vertizes erstellen
aVertex[0].vPosition = tbVector3(-1.0f,  1.0f,  1.0f);
aVertex[1].vPosition = tbVector3( 1.0f,  1.0f,  1.0f);
aVertex[2].vPosition = tbVector3( 1.0f,  1.0f, -1.0f);
aVertex[3].vPosition = tbVector3(-1.0f,  1.0f, -1.0f);
aVertex[4].vPosition = tbVector3(-1.0f, -1.0f,  1.0f);
aVertex[5].vPosition = tbVector3( 1.0f, -1.0f,  1.0f);
aVertex[6].vPosition = tbVector3( 1.0f, -1.0f, -1.0f);
aVertex[7].vPosition = tbVector3(-1.0f, -1.0f, -1.0f);
// Die Texturkoordinaten entsprechen den Vertexpositionen
for(int iVertex = 0; iVertex < 8; iVertex++)
{
  // Texturkoordinate eintragen
  aVertex[iVertex].vTexture = aVertex[iVertex].vPosition;
}
// Alle Vertizes eintragen und den Vertex-Buffer aktualisieren
g_pSkyBoxVB->AddVertices(8, aVertex);
if(g_pSkyBoxVB->Update()) return TB_ERROR;
// ------------------------------------------------------------------
// Den Index-Buffer ausfüllen
WORD awIndex[36] = {7, 3, 0,   4, 7, 0,  // Vorderseite
	  5, 1, 2,   6, 5, 2,  // Hinterseite
	  4, 0, 1,   5, 4, 1,  // Linke Seite
	  6, 2, 3,   7, 6, 3,  // Rechte Seite
	  2, 1, 0,   3, 2, 0,  // Oberseite
	  4, 5, 6,   7, 4, 6}; // Unterseite
g_pSkyBoxIB->AddIndices(36, awIndex);
if(g_pSkyBoxIB->Update()) return TB_ERROR;
// ------------------------------------------------------------------
// Die Textur der Sky-Box laden
g_pEnvMap = tbTextureManager::Instance().GetCubeTexture("_GRAPHICS/EnvMap.dds");
if(g_pEnvMap == NULL) return TB_ERROR;
// Effekt laden
g_pSkyBoxEffect = new tbEffect;
if(g_pSkyBoxEffect == NULL) return TB_ERROR;
if(g_pSkyBoxEffect->Init("_GRAPHICS/SkyBox.fx")) return TB_ERROR;
return TB_OK;
}
// ******************************************************************
// Initialisierung der Schriftarten
tbResult InitFonts()
{
// Erste Schriftart...
g_pFont1 = new tbFont;
if(g_pFont1->Init("_GRAPHICS/Futura_8_22.tga", "_GRAPHICS/Futura_8_22.tbf"))
{
  // Fehler...
  return TB_ERROR;
}
return TB_OK;
}
// ******************************************************************
// Initialisierung des Terrains
tbResult InitTerrain()
{
InitVertexDeclaration();
g_Terrain = new Terrain(257, 257, 0.5f, 0.5f,
  "heightmap17_257.raw",
  "_GRAPHICS/grass.dds",
  "_GRAPHICS/dirt.dds",
  "_GRAPHICS/stone.dds",
  "_GRAPHICS/blend_hm17.dds",
  0.2f, 0.0f, g_Camera);
g_Terrain->setDirToSunW(D3DXVECTOR3(0.0f, 1.0f, 0.0f));

if (g_Terrain == NULL)
  return TB_ERROR;
else
  return TB_OK;
}
// ******************************************************************
// Aufräumen
tbResult CleanUp()
{
///
tbDirect3D& D3D = tbDirect3D::Instance();

// Textur deaktivieren und löschen
D3D->SetTexture(0, NULL);
// Vertex- und Index-Buffer deaktivieren und löschen
D3D->SetStreamSource(0, NULL, 0, 0);
D3D->SetIndices(NULL);

// Terrain benutzt Declaration anstatt FVF
DestroyVertexDeclaration();
g_Terrain->~Terrain();
// Alles löschen
tbDirect3D::Instance().Exit();
tbTextureManager::Instance().Exit();
tbDirectInput::Instance().Exit();
TB_SAFE_DELETE(g_pDuckModel);
TB_SAFE_DELETE(g_pSkyBoxEffect);
TB_SAFE_DELETE(g_pSkyBoxVB);
TB_SAFE_DELETE(g_pSkyBoxIB);
TB_SAFE_DELETE(g_pFont1);
delete g_Cube;
// Die TriBase-Engine herunterfahren
tbExit();
return TB_OK;
}
// ******************************************************************
// Windows-Hauptfunktion
int WINAPI WinMain(HINSTANCE hInstance,
	   HINSTANCE hPrevInstance,
	   char* pcCommandLine,
	   int iShowCommand)
{
// TriBase-Engine initialisieren
tbInit();
tbResult r;
// Konfiguration abfragen
if (tbFileExists("Config.txt"))
{
  if (r = loadConfig(&g_Config, "Config.txt"))
  {
   // Fehler!
   MessageBox(NULL, "Fehler beim Laden der Konfiguration!", "Fehler",
		   MB_OK | MB_ICONEXCLAMATION);
   return 1;
  }
}
else
{
  if(r = tbDoConfigDialog(&g_Config)) // Hier wird der Dialog gestartet.
  {
   if(r == TB_CANCELED) return 0;
   else
   {
	// Fehler!
	MessageBox(NULL, "Fehler im Konfigurationsdialog!", "Fehler",
		 MB_OK | MB_ICONEXCLAMATION);
	return 1;
   }
  }
  if (r = saveConfig(&g_Config, "Config.txt")) // ausgewählte Config wird automatisch gespeichert.
  {
   // Fehler!
	MessageBox(NULL, "Fehler beim Speichern der Konfiguration!", "Fehler",
		 MB_OK | MB_ICONEXCLAMATION);
	return 1;
  }
}

// Direct3D initialisieren
if(tbDirect3D::Instance().Init(&g_Config, // Hier wird die Konfiguration weitergegeben.
		   "Game. Work in progress.",
		   NULL,
		   LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1))))
{
  // Fehler!
  MessageBox(NULL, "Fehler bei der Direct3D-Initialisierung!", "Fehler",
		  MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}
// Den Texturmanager initialisieren
if(tbDirectInput::Instance().Init())
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren von tbDirectInput!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}
// Den Texturmanager initialisieren
if(tbTextureManager::Instance().Init())
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren des Texturmanagers!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}
// Die Sky-Box initialisieren
if(InitSkyBox())
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren der Sky-Box!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}

// Die Schriftarten initialisieren
if (InitFonts())
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren der Schriftarten!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}

g_Camera = Camera(tbVector3(0.0f,30.0f,0.0f));
// Das Terrain initialisieren
if (InitTerrain())
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren des Terrains!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}

// Das Stadtmodell laden
g_pDuckModel = new tbModel;
if(g_pDuckModel->Init("_GRAPHICS/Ente.tbm"))
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Laden der Entenmodelldatei!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}

/// GameObjects initialisieren
g_Cube = createCube(tbVector3(10.0f, 24.0f,0.0f));
if(tbDoMessageLoop(MoveProc, RenderProc))
{
  MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Zeichnen!",
		  "Fehler", MB_OK | MB_ICONEXCLAMATION);
  CleanUp();
  return 1;
}
// Aufräumen
CleanUp();
return 0;
}

#ifndef CAMERA_H
#define CAMERA_H
#include "TriBase.h"
#include "d3dUtil.h"
enum CameraMode {FREE_FLYING, FOLLOW_PLAYER, FOLLOW_PLAYER_LEFT, FOLLOW_PLAYER_RIGHT, BIRDS_EYE_PLAYER};
class Camera
{
private:
tbVector3 m_vCameraPos;  // Kameraposition
float  m_fCameraRot;  // Rotation der Kamera
float  m_fCameraUpDown; // Schaut die Kamera hoch oder runter?
tbVector3   m_vCameraDir;  // Wohin schaut die Kamera?
int   m_iCameraMode;   // Modus der Kamera

tbMatrix mProjection;	 // Für die Projektions-Matrix
tbMatrix mView;    // Für die View-Matrix

// Frustum Planes
D3DXPLANE mFrustumPlanes[6]; // [0] = near
							  // [1] = far
							  // [2] = left
							  // [3] = right
							  // [4] = top
							  // [5] = bottom
public:
Camera()
{
  m_vCameraPos = (0.0f, 30.0f, 0.0f);
  m_iCameraMode = FOLLOW_PLAYER;
  m_fCameraUpDown = 0.0f;
  m_fCameraRot = 0.0f;
  m_vCameraDir = tbVector3(sinf(m_fCameraRot) * cosf(m_fCameraUpDown),
					 sinf(m_fCameraUpDown),
		 cosf(m_fCameraRot) * cosf(m_fCameraUpDown));
}
Camera(tbVector3 pos)
{
  m_vCameraPos = pos;
  m_iCameraMode = FOLLOW_PLAYER;
  m_fCameraUpDown = 0.0f;
  m_fCameraRot = 0.0f;
  m_vCameraDir = tbVector3(sinf(m_fCameraRot) * cosf(m_fCameraUpDown),
					 sinf(m_fCameraUpDown),
		 cosf(m_fCameraRot) * cosf(m_fCameraUpDown));
}
tbVector3 getPos(){ return m_vCameraPos; }
tbVector3 getTarget() { return m_vCameraDir; }
int getMode(){ return m_iCameraMode; }
tbMatrix getProjMatrix() { return mProjection; }
tbMatrix getViewMatrix() { return mView; }
void moveCamera(tbVector3 vTarget, float fTime);
void setUpCamera();
void buildWorldFrustumPlanes();
// Box coordinates should be relative to world space.
bool isVisible(const AABB& box) const;
};
#endif CAMERA_H

#include "Camera.h"
void Camera::moveCamera(tbVector3 vTarget, float fTime)
{
switch (m_iCameraMode)
{
  case FREE_FLYING:
  {
   // Tastatursteuerung...
   m_vCameraDir = tbVector3(sinf(m_fCameraRot) * cosf(m_fCameraUpDown),
		   sinf(m_fCameraUpDown),
		   cosf(m_fCameraRot) * cosf(m_fCameraUpDown));

   if(GetAsyncKeyState(VK_A))   m_fCameraRot -= 1.0f * fTime;
   if(GetAsyncKeyState(VK_D))   m_fCameraRot += 1.0f * fTime;
   if(GetAsyncKeyState(VK_UP))   m_fCameraUpDown -= 1.0f * fTime;
   if(GetAsyncKeyState(VK_DOWN))  m_fCameraUpDown += 1.0f * fTime;
   if(GetAsyncKeyState(VK_W))   m_vCameraPos += m_vCameraDir * 25.0f * fTime;
   if(GetAsyncKeyState(VK_S))   m_vCameraPos -= m_vCameraDir * 25.0f * fTime;
   break;
  }
  case BIRDS_EYE_PLAYER:
  {
   m_vCameraPos = vTarget + tbVector3(0.0f, 40.0f, 0.0f);
   m_fCameraRot = 0.0f;
   m_fCameraUpDown = -1.55f; //  ~90° da PI / 2
   break;
  }
  case FOLLOW_PLAYER:
  {
   m_vCameraPos = vTarget + tbVector3(0.0f, 20.0f, -20.0f);
   m_fCameraRot = 0.0f;
   m_fCameraUpDown = -0.78f; // ~45° da PI / 4
   break;
  }
  case FOLLOW_PLAYER_LEFT:
  {
   m_vCameraPos = vTarget + tbVector3(20.0f, 20.0f, 0.0f);
   m_fCameraRot = -1.55f;
   m_fCameraUpDown = -0.78f; // ~45° da PI / 4
   break;
  }
  case FOLLOW_PLAYER_RIGHT:
  {
   m_vCameraPos = vTarget + tbVector3(-20.0f, 20.0f, 0.0f);
   m_fCameraRot = 1.55f;
   m_fCameraUpDown = -0.78f; // ~45° da PI / 4
   break;
  }
}

// Kamera-Modus via NumPad
if(GetAsyncKeyState(VK_NUMPAD2)) m_iCameraMode = FOLLOW_PLAYER;
if(GetAsyncKeyState(VK_NUMPAD4)) m_iCameraMode = FOLLOW_PLAYER_LEFT;
if(GetAsyncKeyState(VK_NUMPAD6)) m_iCameraMode = FOLLOW_PLAYER_RIGHT;
if(GetAsyncKeyState(VK_NUMPAD5)) m_iCameraMode = FREE_FLYING;
if(GetAsyncKeyState(VK_NUMPAD8)) m_iCameraMode = BIRDS_EYE_PLAYER;
}
void Camera::setUpCamera()
{
tbDirect3D& D3D = tbDirect3D::Instance();

// Projektionsmatrix erstellen und einsetzen
mProjection = tbMatrixProjection(TB_DEG_TO_RAD(90.0f), D3D.GetAspect(), 0.1f, 100.0f);
D3D.SetTransform(D3DTS_PROJECTION, mProjection);

//switch (m_iCameraMode)
//{
// case FREE_FLYING:
// {
   // Kameramatrix erstellen und einsetzen
   m_vCameraDir = tbVector3(sinf(m_fCameraRot) * cosf(m_fCameraUpDown),
		   sinf(m_fCameraUpDown),
		   cosf(m_fCameraRot) * cosf(m_fCameraUpDown));
//  break;
// }
//}
mView = tbMatrixCamera(m_vCameraPos, m_vCameraPos + m_vCameraDir);
buildWorldFrustumPlanes();
D3D.SetTransform(D3DTS_VIEW, mView);
}
void Camera::buildWorldFrustumPlanes()
{
// Note: Extract the frustum planes in world space.
tbMatrix VP = mView * mProjection;
D3DXVECTOR4 col0(VP(0,0), VP(1,0), VP(2,0), VP(3,0));
D3DXVECTOR4 col1(VP(0,1), VP(1,1), VP(2,1), VP(3,1));
D3DXVECTOR4 col2(VP(0,2), VP(1,2), VP(2,2), VP(3,2));
D3DXVECTOR4 col3(VP(0,3), VP(1,3), VP(2,3), VP(3,3));
// Planes face inward.
mFrustumPlanes[0] = (D3DXPLANE)(col2);	    // near
mFrustumPlanes[1] = (D3DXPLANE)(col3 - col2); // far
mFrustumPlanes[2] = (D3DXPLANE)(col3 + col0); // left
mFrustumPlanes[3] = (D3DXPLANE)(col3 - col0); // right
mFrustumPlanes[4] = (D3DXPLANE)(col3 - col1); // top
mFrustumPlanes[5] = (D3DXPLANE)(col3 + col1); // bottom
for(int i = 0; i < 6; i++)
  D3DXPlaneNormalize(&mFrustumPlanes[i], &mFrustumPlanes[i]);
}
bool Camera::isVisible(const AABB& box)const
{
// Test assumes frustum planes face inward.
D3DXVECTOR3 P;
D3DXVECTOR3 Q;
//	  N  *Q				    *P
//	  | /					 /
//	  |/					 /
// -----/----- Plane	 -----/----- Plane   
//	 /					 / |
//    /					 /  |
//   *P				    *Q  N
//
// PQ forms diagonal most closely aligned with plane normal.
// For each frustum plane, find the box diagonal (there are four main
// diagonals that intersect the box center point) that points in the
// same direction as the normal along each axis (i.e., the diagonal
// that is most aligned with the plane normal).  Then test if the box
// is in front of the plane or not.
for(int i = 0; i < 6; ++i)
{
  // For each coordinate axis x, y, z...
  for(int j = 0; j < 3; ++j)
  {
   // Make PQ point in the same direction as the plane normal on this axis.
   if( mFrustumPlanes[i][j] >= 0.0f )
   {
    P[j] = box.minPt[j];
    Q[j] = box.maxPt[j];
   }
   else
   {
    P[j] = box.maxPt[j];
    Q[j] = box.minPt[j];
   }
  }
  // If box is in negative half space, it is behind the plane, and thus, completely
  // outside the frustum.  Note that because PQ points roughly in the direction of the
  // plane normal, we can deduce that if Q is outside then P is also outside--thus we
  // only need to test Q.
  if( D3DXPlaneDotCoord(&mFrustumPlanes[i], &Q) < 0.0f  ) // outside
   return false;
}
return true;
}

Code is originally (partly) from Frank D. Luna and David Scherfing.

#11 Washu   Senior Moderators   -  Reputation: 5199

Like
1Likes
Like

Posted 01 March 2012 - 03:31 PM

mCamera is a reference, not a pointer. You don't use -> to access the members of a reference.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#12 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 03:42 PM

Thanks, but these errors remain:
1>------ Build started: Project: TheGame, Configuration: Debug Win32 ------
1>  Terrain.cpp
1>c:\-\thegame\terrain.cpp(121): error C2327: 'Terrain::mCamera' : is not a type name, static, or enumerator
1>c:-\\thegame\terrain.cpp(121): error C2065: 'mCamera' : undeclared identifier
1>c:\-\thegame\terrain.cpp(121): error C2228: left of '.getPos' must have class/struct/union
1>		  type is ''unknown-type''
1>c:\-\thegame\terrain.cpp(121): error C2228: left of '.vD3DVector' must have class/struct/union
1>c:\-\thegame\terrain.cpp(122): error C2327: 'Terrain::mCamera' : is not a type name, static, or enumerator
1>c:\-\thegame\terrain.cpp(122): error C2065: 'mCamera' : undeclared identifier
1>c:\-\thegame\terrain.cpp(122): error C2228: left of '.getPos' must have class/struct/union
1>		  type is ''unknown-type''
1>c:\-\thegame\terrain.cpp(122): error C2228: left of '.vD3DVector' must have class/struct/union


#13 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 03:47 PM

Look up the error code, it tells you EXACTLY what's wrong.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#14 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 04:38 PM

Look up the error code, it tells you EXACTLY what's wrong.


I've looked into it before and I am still clueless.
SubGrid does not know mCamera. Using Terrain::mCamera does not work. Making mCamera static also. :/ Thanks for your help, though.
It says: "Camera & Terrain::mCamera Error: a nonstatic member reference must be relative to a specific object"
But this gets called after the constructor where I pass the specific object (the reference) to mCamera. I'm clueless.

#15 Washu   Senior Moderators   -  Reputation: 5199

Like
0Likes
Like

Posted 01 March 2012 - 05:03 PM

I would highly recommend learning the language before you start too far down the road with your game. Especially when your solution to problems is "damn, I don't understand why this is illegal, I'll just make it a global."

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#16 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 March 2012 - 05:20 PM

The reason my problem actually exists is because I do not want to use my camera class globally, like in Luna's initial code example.

#17 rip-off   Moderators   -  Reputation: 8223

Like
1Likes
Like

Posted 01 March 2012 - 05:49 PM

Your SubGrid type is an inner class of Terrain. However, it has no relationship with the parent class. That is, a SubGrid isn't associated with any particular Terrain instance. One solution is to put a pointer to Terrain in the SubGrid (intiialised in the constructor). The operator<() can use this pointer to access the camera.

As Washu correctly points out - this is a basic language issue.

Well I took out everything that is not part of the problem.

No, there is still a huge amount of code in that that is nothing to do with the problem. This is what the code would look like if you had taken everything out:

#ifndef CAMERA_H
#define CAMERA_H

class Camera
{
    bool example;
};

#endif

#ifndef TERRAIN_H
#define TERRAIN_H

class Terrain
{
public:
    Terrain(Camera &camera);

    class SubGrid
    {
        bool operator<(const SubGrid &other) const;
    };
private:
    Camera &camera;
};

#endif

#include "terrain.h"

Terrain::Terrain(Camera &camera) : camera(camera)
{
}

bool Terrain::SubGrid::operator<(const SubGrid &other) const
{
    return camera.example;
}

int main()
{

}
This code distils the essence of your problem - it should generate exactly the error you were looking at.

Also note that the code dump you gave is not properly indented, which makes it very difficult to decipher. Once again, having less code would make this less of an issue.

As an aside, it is usually a good idea to not use references as members. References have strange semantics as members because they are not reseatable. Instead, convert the reference to a pointer. The constructor can still take a reference, which neatly documents the intent of the class.

#18 Honas   Members   -  Reputation: 101

Like
0Likes
Like

Posted 02 March 2012 - 06:56 AM

Your SubGrid type is an inner class of Terrain. However, it has no relationship with the parent class. That is, a SubGrid isn't associated with any particular Terrain instance. One solution is to put a pointer to Terrain in the SubGrid (intiialised in the constructor). The operator<() can use this pointer to access the camera.

As Washu correctly points out - this is a basic language issue.


Well I took out everything that is not part of the problem.

No, there is still a huge amount of code in that that is nothing to do with the problem. This is what the code would look like if you had taken everything out:

#ifndef CAMERA_H
#define CAMERA_H

class Camera
{
	bool example;
};

#endif

#ifndef TERRAIN_H
#define TERRAIN_H

class Terrain
{
public:
	Terrain(Camera &camera);

	class SubGrid
	{
		bool operator<(const SubGrid &other) const;
	};
private:
	Camera &camera;
};

#endif

#include "terrain.h"

Terrain::Terrain(Camera &camera) : camera(camera)
{
}

bool Terrain::SubGrid::operator<(const SubGrid &other) const
{
	return camera.example;
}

int main()
{

}
This code distils the essence of your problem - it should generate exactly the error you were looking at.

Also note that the code dump you gave is not properly indented, which makes it very difficult to decipher. Once again, having less code would make this less of an issue.

As an aside, it is usually a good idea to not use references as members. References have strange semantics as members because they are not reseatable. Instead, convert the reference to a pointer. The constructor can still take a reference, which neatly documents the intent of the class.


Thank you!




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS