путаница заголовка.Компилятор не распознает типы данных - PullRequest
1 голос
/ 24 мая 2010

Я запутался, почему компилятор не распознает мои классы. Так что я просто покажу вам свой код и пусть вы, ребята, решите. Моя ошибка в этом

error C2653: 'RenderEngine' : is not a class or namespace name

и он указывает на эту строку

std::vector<RenderEngine::rDefaultVertex> m_verts;

Вот код для rModel в полном объеме. Он содержит переменную. класс, который его держит, находится ниже.

#ifndef _MODEL_H
#define _MODEL_H
#include "stdafx.h"
#include <vector>
#include <string>
//#include "RenderEngine.h"
#include "rTri.h"

class rModel {
public:

    typedef tri<WORD> sTri;

    std::vector<sTri> m_tris;
    std::vector<RenderEngine::rDefaultVertex> m_verts;

    std::wstring m_name;

    ID3D10Buffer *m_pVertexBuffer;
    ID3D10Buffer *m_pIndexBuffer;

    rModel( const TCHAR *filename );
    rModel( const TCHAR *name, int nVerts, int nTris );

    ~rModel();

    float GenRadius();
    void Scale( float amt );
    void Draw();

    //------------------------------------ Access functions.
    int NumVerts(){ return m_verts.size(); }
    int NumTris(){ return m_tris.size(); }
    const TCHAR *Name(){ return m_name.c_str(); }

    RenderEngine::cDefaultVertex *VertData(){ return &m_verts[0]; }
    sTri *TriData(){ return &m_tris[0]; }

};

#endif

в самом верху кода находится заголовочный файл

#include "stdafx.h"

, который включает это

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include "resource.h"
#include "d3d10.h"
#include "d3dx10.h"
#include "dinput.h"
#include "RenderEngine.h"
#include "rModel.h"


// TODO: reference additional headers your program requires here

Как видите, RenderEngine.h предшествует rModel.h

#include "RenderEngine.h"
    #include "rModel.h"

Насколько мне известно, оно должно это признать. Но с другой стороны, я не очень хорош в организации заголовков. Вот моя декларация RenderEngine.

#pragma once
#include "stdafx.h"



#define MAX_LOADSTRING 100
#define MAX_LIGHTS 10

class RenderEngine {
public:
    class rDefaultVertex
    {
    public:
        D3DXVECTOR3 m_vPosition;  
        D3DXVECTOR3 m_vNormal;
        D3DXCOLOR m_vColor;
        D3DXVECTOR2 m_TexCoords;
    };

    class rLight
    {
    public:
        rLight()
        {

        }
        D3DXCOLOR m_vColor;
        D3DXVECTOR3 m_vDirection;
    };

    static HINSTANCE m_hInst;
    HWND m_hWnd;
    int m_nCmdShow;
    TCHAR m_szTitle[MAX_LOADSTRING];                    // The title bar text
    TCHAR m_szWindowClass[MAX_LOADSTRING];          // the main window class name

    void DrawTextString(int x, int y, D3DXCOLOR color, const TCHAR *strOutput);

    //static functions
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

    bool InitWindow();
    bool InitDirectX();
    bool InitInstance();
    int Run();
    void ShutDown();

    void AddLight(D3DCOLOR color, D3DXVECTOR3 pos);

    RenderEngine()
    {
        m_screenRect.right = 800;
        m_screenRect.bottom = 600;
        m_iNumLights = 0;
    }
protected:

    RECT m_screenRect;

    //direct3d Members
    ID3D10Device *m_pDevice; // The IDirect3DDevice10
    // interface
    ID3D10Texture2D *m_pBackBuffer; // Pointer to the back buffer
    ID3D10RenderTargetView *m_pRenderTargetView; // Pointer to render target view
    IDXGISwapChain *m_pSwapChain; // Pointer to the swap chain
    RECT m_rcScreenRect; // The dimensions of the screen

    ID3D10Texture2D *m_pDepthStencilBuffer;
    ID3D10DepthStencilState *m_pDepthStencilState;
    ID3D10DepthStencilView *m_pDepthStencilView;

    //transformation matrixs system
    D3DXMATRIX m_mtxWorld;
    D3DXMATRIX m_mtxView;
    D3DXMATRIX m_mtxProj;

    //pointers to shaders matrix varibles
    ID3D10EffectMatrixVariable* m_pmtxWorldVar;
    ID3D10EffectMatrixVariable* m_pmtxViewVar;
    ID3D10EffectMatrixVariable* m_pmtxProjVar;

    //Application Lights
    rLight m_aLights[MAX_LIGHTS]; // Light array
    int m_iNumLights; // Number of active lights

    //light pointers from shader
    ID3D10EffectVectorVariable* m_pLightDirVar;
    ID3D10EffectVectorVariable* m_pLightColorVar;
    ID3D10EffectVectorVariable* m_pNumLightsVar;

    //Effect members
    ID3D10Effect *m_pDefaultEffect;
    ID3D10EffectTechnique *m_pDefaultTechnique;
    ID3D10InputLayout* m_pDefaultInputLayout;

    ID3DX10Font *m_pFont; // The font used for rendering text
    // Sprites used to hold font characters
    ID3DX10Sprite *m_pFontSprite;

    ATOM RegisterEngineClass();
    void DoFrame(float);
    bool LoadEffects();
    void UpdateMatrices();
    void UpdateLights();

};

Классы определены в классе

class rDefaultVertex
        {
        public:
            D3DXVECTOR3 m_vPosition;  
            D3DXVECTOR3 m_vNormal;
            D3DXCOLOR m_vColor;
            D3DXVECTOR2 m_TexCoords;
        };

        class rLight
        {
        public:
            rLight()
            {

            }
            D3DXCOLOR m_vColor;
            D3DXVECTOR3 m_vDirection;
        };

Не уверен, что это хорошая практика, но я просто иду по книге.

В конце мне просто нужен хороший способ организовать его так, чтобы rModel распознал RenderEngine. и если возможно, наоборот.

[править]

Я могу буквально указать на класс движка рендеринга, и он все равно не распознает

#ifndef _MODEL_H
#define _MODEL_H
//#include "stdafx.h"
#include <vector>
#include <string>
#include "RenderEngine.h"  //<-------pointing to render engine. still does not recognize.
#include "rTri.h"

class rModel {
public:

    typedef tri<WORD> sTri;

    std::vector<sTri> m_tris;
    std::vector<RenderEngine::rDefaultVertex> m_verts;

    std::wstring m_name;

    ID3D10Buffer *m_pVertexBuffer;
    ID3D10Buffer *m_pIndexBuffer;

    rModel( const TCHAR *filename );
    rModel( const TCHAR *name, int nVerts, int nTris );

    ~rModel();

    float GenRadius();
    void Scale( float amt );
    void Draw();

    //------------------------------------ Access functions.
    int NumVerts(){ return m_verts.size(); }
    int NumTris(){ return m_tris.size(); }
    const TCHAR *Name(){ return m_name.c_str(); }

    RenderEngine::cDefaultVertex *VertData(){ return &m_verts[0]; }
    sTri *TriData(){ return &m_tris[0]; }

};

#endif

Ответы [ 3 ]

1 голос
/ 24 мая 2010

Как уже упоминалось, здесь происходит разделение / рефакторинг - stdafx.h не предназначен для хранения всех заголовочных файлов , которые есть в вашем приложении.

Ваша проблема в том, что renderengine.h также включает stdafx.h.На этот раз включение renderengine.h игнорируется из-за #pragma once, а затем включается rmodel.h - наверху renderengine.h.

В вашем случае проще всего было бы:

  • удалить renderengine.h & rmodel.h из stdafx.h
  • rmodel.h включает renderengine.h
  • ... выполнено
0 голосов
/ 24 мая 2010

Не могу сказать точно, но RenderEngine.h, вероятно, включает rModel.h.Затем, когда вы включаете stdafx.h, он вводит RenderEngine.h, но перед тем, как полностью обработать этот заголовок, он включает rModel.h.Затем внутри rModel.h охранники включения не позволяют ему снова включить stdafx.h, и он продолжает компилировать rModel.h без полного знания чего-либо в RenderEngine.h.

Не понимая полного отношения ваших различных классов, егочрезвычайно трудно предложить исправить.Скорее всего, вы захотите тщательно продумать, какие классы определены, в каких заголовках и использовать предварительные объявления для удаления циклической зависимости.

0 голосов
/ 24 мая 2010

Довольно сложно понять все ваши зависимости, и я думаю, что ваш код требует рефакторинга (если не переписать).Кроме того, спешка в разработку движка рендеринга без какого-либо опыта построения архитектуры (как я полагаю) обычно приводит к дрянному ненадежному коду, хаки «заставить его работать» и другим злым вещам.

В любом случае, в этом случае попробуйтеразложить части вашего приложения и выделить их.В вашем случае один из возможных подходов будет означать помещение всех объектов / структур рендеринга, таких как Vertex, Light, Model, в другой заголовок (вы можете назвать его render.types.h или render.objects.h или что-то в этом роде).

Тогда вы просто должны заставить свой движок рендеринга работать с этими объектами рендеринга .Как только вы закончите с этим, вам не понадобятся операторы типа std::vector<RenderEngine::rDefaultVertex> m_verts; или RenderEngine::cDefaultVertex *VertData().

Обратите внимание, что это также решит ваши круговые зависимости, потому что ваш движок должен знать только о моделях,модели - только про вершины и тд.

Если вы все еще сталкиваетесь с проблемами зависимости, используйте предварительные объявления.Google для полного описания, и просто образец для вас, чтобы понять, что я имею в виду:

class ForwardDeclared;

class Object {
    ForwardDeclared* member;
    void Method(const ForwardDeclared& fd) { (...) }
};

// This could also resude in another file
class ForwardDeclared { (...) };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...