2010-05-24 2 views
1

Я смущаюсь, почему компилятор не распознает мои классы. Поэтому я просто покажу вам свой код и дам ребятам решать. Моя ошибка этоЗаголовок путаницы. Компилятор не распознает типы данных

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 

ответ

1

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

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

Самое простое в вашем случае будет заключаться в следующем:

  • удалить renderengine.h & rmodel.h из stdafx.h
  • rmodel.h включает renderengine.h
  • ... сделано
0

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

В любом случае, в этом случае попробуйте разложить детали приложения и различать их. В вашем случае один из возможных подходов означал бы размещение всех объектов-объектов-объектов, таких как 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 { (...) }; 
+0

Ну, мое приложение не так сложно. Он состоит только из 2 классов. RenderEngine (с rLight и rDefaultVertex) и rMdodel. Вот и все. Конечно, есть документ WinMain, но также имеет заголовочный файл stdafx. Вкратце, все мои документы имеют заголовок stdafx. Нет прямого способа взглянуть на это и сказать, что правильно, а что не так? – numerical25

+0

Запустите «Пустой проект», добавьте все заголовки и избавьтесь от предварительно скомпилированного заголовка 'stdafx.h'. После этого решение проблемы с файлом станет простой задачей. –

0

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

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

Смежные вопросы