• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Honas

Passing an object to another class

17 posts in this topic

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:
[code]Camera g_Camera; [/code]
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:

[code]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''[/code]

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

Share this post


Link to post
Share on other sites
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.
0

Share this post


Link to post
Share on other sites
[quote name='Washu' timestamp='1330630590' post='4918316']
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.
[/quote]

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

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

Share this post


Link to post
Share on other sites
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.
0

Share this post


Link to post
Share on other sites
[code]// 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);
[/code]

[code]// camera.h
// contains uninteresting stuff..[/code]

[code]// 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[/code]

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

Share this post


Link to post
Share on other sites
You didn't include camera in your terain.cpp. The definition of the incomplete type of Camera is required by then.
0

Share this post


Link to post
Share on other sites
[quote name='Washu' timestamp='1330633187' post='4918342']
You didn't include camera in your terain.cpp. The definition of the incomplete type of Camera is required by then.
[/quote]
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.
0

Share this post


Link to post
Share on other sites
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:
[code]
g_Camera = cam;
[/code]

Is incorrect.
0

Share this post


Link to post
Share on other sites
[code]
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'
[/code]
This tells you that you need to initialize the reference in the initializer list of the constructor.
[code]
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''
[/code]
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.
0

Share this post


Link to post
Share on other sites
Well I took out everything that is not part of the problem. Here's the complete source code of terrain:

[code]#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[/code]

I marked the errors down below.

[code]#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));
}[/code]

Main (beware of German commentary! InitTerrain plays a key role here.)
[code]
// ===================
// 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;
}
[/code]

[code]#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[/code]

[code]#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]

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

Share this post


Link to post
Share on other sites
mCamera is a reference, not a pointer. You don't use -> to access the members of a reference.
1

Share this post


Link to post
Share on other sites
Thanks, but these errors remain:
[code]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[/code]
0

Share this post


Link to post
Share on other sites
Look up the error code, it tells you [url="http://msdn.microsoft.com/en-us/library/ac27ea0d(v=vs.71).aspx"]EXACTLY [/url]what's wrong.
0

Share this post


Link to post
Share on other sites
[quote name='Washu' timestamp='1330638427' post='4918376']
Look up the error code, it tells you [url="http://msdn.microsoft.com/en-us/library/ac27ea0d%28v=vs.71%29.aspx"]EXACTLY [/url]what's wrong.
[/quote]

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.
0

Share this post


Link to post
Share on other sites
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."
0

Share this post


Link to post
Share on other sites
The reason my problem [b]actually exists[/b] is because I do not want to use my camera class globally, like in Luna's initial code example.
0

Share this post


Link to post
Share on other sites
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 [i]particular[/i] 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.

[quote]
Well I took out everything that is not part of the problem.
[/quote]
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:
[code]

#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()
{

}
[/code]
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.
1

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1330645783' post='4918420']
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 [i]particular[/i] 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.

[quote]
Well I took out everything that is not part of the problem.
[/quote]
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:
[code]

#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()
{

}
[/code]
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.
[/quote]

Thank you!
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0