DirectX 10 will Dreieck nicht rendern
-
Hallo!
Ich hab' ein Problem, und zwar hatte ich mir nach den ersten paar Tutorials vorgenommen eine Fenster-, Device- und eine Grafikklasse zu schreiben, die ein Fenster und ein Device erstellt, und die Grafikklasse dieses Device nutzt um Verticen zu rendern (Buffer und Layout erstellen, verwalten und darstellen).
Nun ist alles geschrieben und er will irgendwie das Dreieck nicht darstellen.
Er ruft alle Methoden einwandfrei, d.h. ohne Fehlermeldungen o.Ä., auf und kommt auch letztendlich zum ID3D10Device::Draw().
Ich hatte die Shader schon mehrmals überarbeitet (Auch mal ohne Farbe, dann mit vorgegebenen Werten (Konstante Farbe per Pixel-Shader). Auch den Vertex hatte ich ohne die Methoden geschrieben, bzw. diese weggelassen - Leider kein Erfolg.
Ebenfalls hatte ich den Call Graphic::Render() auseinander genommen und vor dem eigentlichem Rendern der Klasse Device den Vertex-Buffer und -Layout setzen lassen - auch kein Erfolg.
Hier einmal der Code:
Main.cpp
#include "Window.h" #include "Device.h" #include "Graphic.h" Vertex test_vertices[] = { /* POS COLOR */ Vertex( 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.2f, 1.0f), Vertex( 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.2f, 1.0f), Vertex( 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.2f, 1.0f), }; size_t test_vertices_size = sizeof(test_vertices)/sizeof(test_vertices[0]); INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nShowCmd) { Window test_window; Device test_device; Graphic test_graphic; if(!test_window.Create(hInstance, "Test Window")) { return 0; } if(!test_device.Create(test_window.Handle(), hInstance, test_window.Width(), test_window.Height())) { return 0; } test_graphic.SetDevice(&test_device); test_graphic.DrawTriangle2D(test_vertices, test_vertices_size); while(test_window.Active()) { if(!test_window.ProcessNextMessage()) { test_graphic.PreRender(); test_device.RTClear(.2f, .3f, .5f); test_graphic.Render(); test_device.Render(); } } test_device.Destroy(); test_window.Destroy(); return 0; }
Device.h
#ifndef DEVICE_H_ #define DEVICE_H_ #include <D3DX10.h> #include <D3D10.h> #include <DXGI.h> #define RELEASE(x) if(x != 0){ x->Release(); x = 0; } class Device { private: ID3D10Device* pDevice; ID3D10RenderTargetView* pRenderTargetView; ID3D10DepthStencilView* pDepthStencilView; IDXGISwapChain* pSwapChain; BOOL bDeviceActive; struct _states { BOOL bCleared; } sStates; public: Device ( void ); ~Device ( void ); void Invalidate ( void ); bool Create ( HWND hOutput, HINSTANCE hInstance, unsigned uiWidth, unsigned uiHeight ); void Destroy ( void ); void Render ( void ); bool LoadShader ( const char* filename, ID3D10Effect** ppEffect ); bool CreateVertexBuffer ( ID3D10InputLayout* pLayout, void* data, size_t size, ID3D10Buffer** ppBuffer ); bool CreateVertexLayout ( D3D10_INPUT_ELEMENT_DESC *layout, size_t n, D3D10_PASS_DESC pass_desc, ID3D10InputLayout** ppLayout ); /* RENDER TARGET OPTIONS */ void RTClear ( float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 0.0f ); void RTSetLayout ( ID3D10InputLayout* pLayout ); void RTSetVertexBuffer ( ID3D10Buffer** ppBuffer, unsigned uiStride, unsigned uiOffsets, D3D10_PRIMITIVE_TOPOLOGY pt ); void RTRenderVB ( ID3D10EffectTechnique* pTechnique ); void RTPresent ( void ); protected: bool CreateDS ( void ); bool CreateRT ( void ); void SetViewport ( float min_depth, float max_depth, unsigned uiWidth, unsigned uiHeight ); } /* class Device */; #endif /* DEVICE_H_ */
Device.cpp
#include "Device.h" Device::Device( void ) { Invalidate(); } Device::~Device( void ) { Destroy(); } void Device::Invalidate( void ) { pDevice = 0; pRenderTargetView = 0; pDepthStencilView = 0; pSwapChain = 0; bDeviceActive = FALSE; memset(&sStates, 0, sizeof(_states)); } bool Device::Create( HWND hOutput, HINSTANCE hInstance, unsigned uiWidth, unsigned uiHeight ) { unsigned flags = 0; # ifdef DEBUG flags = D3D10_CREATE_DEVICE_DEBUG; # endif hInstance = hInstance; /* SWAP CHAIN DESCRIPTION (WINDOW MODE) */ DXGI_SWAP_CHAIN_DESC sw_desc = {0}; sw_desc.BufferCount = 1; /* BackBuffer count */ sw_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; /* Use for */ sw_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; /* Format for */ sw_desc.BufferDesc.Width = uiWidth; /* width and .. */ sw_desc.BufferDesc.Height = uiHeight; /* height of the backbuffer */ sw_desc.BufferDesc.RefreshRate.Numerator = 60; /* refreshrate */ sw_desc.BufferDesc.RefreshRate.Denominator = 1; sw_desc.Windowed = TRUE; sw_desc.OutputWindow = hOutput; sw_desc.SampleDesc.Count = 1; /* Anti-Aliasing */ sw_desc.SampleDesc.Quality = 0; /* CREATING SWAP CHAIN AND DEVICE */ HRESULT hr = D3D10CreateDeviceAndSwapChain(0, D3D10_DRIVER_TYPE_HARDWARE, 0, flags, D3D10_SDK_VERSION, &sw_desc, &pSwapChain, &pDevice); if(FAILED(hr)) { return false; } else { bDeviceActive = TRUE; } if(CreateDS() == false) { return false; } if(CreateRT() == false) { return false; } SetViewport(0.0f, 1.0f, uiWidth, uiHeight); // Fensterbreite und -Höhe return true; } bool Device::CreateRT( void ) { if(bDeviceActive == FALSE) { return false; } ID3D10Texture2D *pBackBuffer = 0; HRESULT hr = pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&pBackBuffer); if(FAILED(hr)) { return false; } D3D10_RENDER_TARGET_VIEW_DESC rtv_desc; rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; rtv_desc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D; rtv_desc.Texture2D.MipSlice = 0; hr = pDevice->CreateRenderTargetView(pBackBuffer, /*&rtv_desc*/0, &pRenderTargetView); pBackBuffer->Release(); if(FAILED(hr)) { return false; } pDevice->OMSetRenderTargets(0, &pRenderTargetView, (pDepthStencilView?pDepthStencilView:0)); return true; } bool Device::CreateDS( void ) { /* not needed yet */ return true; } void Device::SetViewport( float min_depth, float max_depth, unsigned uiWidth, unsigned uiHeight ) { if(bDeviceActive == FALSE) { false; } D3D10_VIEWPORT viewport; viewport.Width = uiWidth; viewport.Height = uiHeight; viewport.MaxDepth = max_depth; viewport.MinDepth = min_depth; viewport.TopLeftX = 0; viewport.TopLeftY = 0; pDevice->RSSetViewports(1, &viewport); } void Device::Destroy( void ) { RELEASE(pRenderTargetView); RELEASE(pDepthStencilView); RELEASE(pSwapChain); RELEASE(pDevice); bDeviceActive = false; } void Device::Render( void ) { if(bDeviceActive == FALSE) { return; } if(sStates.bCleared == FALSE) { RTClear(); } RTPresent(); } bool Device::LoadShader( const char* filename, ID3D10Effect** ppEffect ) { if(bDeviceActive == FALSE || filename == 0 || ppEffect == 0) { return false; } HRESULT hr = D3DX10CreateEffectFromFile(filename, 0, 0, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS|D3D10_SHADER_DEBUG, 0, pDevice, 0, 0, ppEffect, 0, 0); if(FAILED(hr)) { return false; } return true; } bool Device::CreateVertexBuffer( ID3D10InputLayout* pLayout, void *data, size_t size, ID3D10Buffer **ppBuffer ) { if(bDeviceActive == FALSE || pLayout == 0 || data == 0 || ppBuffer == 0) { return false; } D3D10_BUFFER_DESC buffer_desc = {0}; D3D10_SUBRESOURCE_DATA buffer_data = {0}; buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_desc.ByteWidth = size; buffer_desc.CPUAccessFlags = 0; buffer_desc.MiscFlags = 0; buffer_desc.Usage = D3D10_USAGE_DEFAULT; buffer_data.pSysMem = data; if(FAILED(pDevice->CreateBuffer(&buffer_desc, &buffer_data, ppBuffer))) { return false; } return true; } bool Device::CreateVertexLayout( D3D10_INPUT_ELEMENT_DESC *layout, size_t n, D3D10_PASS_DESC pass_desc, ID3D10InputLayout **ppLayout ) { if(bDeviceActive == FALSE || layout == 0 || ppLayout == 0) { return false; } HRESULT hr = pDevice->CreateInputLayout(layout, n, pass_desc.pIAInputSignature, pass_desc.IAInputSignatureSize, ppLayout); if(FAILED(hr)) { return false; } return true; } void Device::RTClear( float r, float g, float b, float a ) { if(bDeviceActive == FALSE) { return; } float colorRGBA[] = {r, g, b, a}; pDevice->ClearRenderTargetView(pRenderTargetView, colorRGBA); /* SET STATE CLEARED */ sStates.bCleared = TRUE; } void Device::RTSetLayout( ID3D10InputLayout *pLayout ) { if(bDeviceActive == FALSE || !pLayout) { return; } pDevice->IASetInputLayout(pLayout); } void Device::RTSetVertexBuffer( ID3D10Buffer **ppBuffer, unsigned uiStride, unsigned uiOffsets, D3D10_PRIMITIVE_TOPOLOGY pt ) { if(bDeviceActive == FALSE || !ppBuffer) { return; } unsigned Stride = uiStride; unsigned Offsets = uiOffsets; pDevice->IASetVertexBuffers(0, 1, ppBuffer, &Stride, &Offsets); pDevice->IASetPrimitiveTopology(pt); } void Device::RTRenderVB( ID3D10EffectTechnique* pTechnique ) { if(bDeviceActive == FALSE || !pTechnique) { return; } D3D10_TECHNIQUE_DESC tech_desc; HRESULT hr = pTechnique->GetDesc(&tech_desc); if(FAILED(hr)) { return; } for(unsigned p=0; p<tech_desc.Passes; ++p) { hr = pTechnique->GetPassByIndex(p)->Apply(0); if(SUCCEEDED(hr)) { pDevice->Draw(3, 0); } } } void Device::RTPresent( void ) { if(bDeviceActive == FALSE) { return; } pSwapChain->Present(0, 0); /* CLEAR STATES */ memset(&sStates, 0, sizeof(_states)); }
Graphic.h
#ifndef GRAPHIC_H_ #define GRAPHIC_H_ #include "Device.h" #include <vector> using std::vector; #define LAYOUT_SIZE(x) sizeof(x)/sizeof(x[0]) /* VERTEX DEFINITIONS */ struct Vertex { public: D3DXVECTOR3 Pos; D3DXVECTOR4 Color; Vertex( void ) { SetPosition(D3DXVECTOR3()); SetColor(D3DXVECTOR4()); } Vertex( D3DXVECTOR3 Pos, D3DXVECTOR4 Color ) { SetPosition(Pos); SetColor(Color); } Vertex( float x, float y, float z = 0.0f, float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 0.0f ) { SetPosition(x, y, z); SetColor(r, g, b, a); } void SetPosition( D3DXVECTOR3 Pos ) { this->Pos = Pos; } void SetPosition( float x = 0.0f, float y = 0.0f, float z = 0.0f ) { Pos = D3DXVECTOR3(x, y, z); } void SetColor( D3DXVECTOR4 Color ) { this->Color = Color; } void SetColor( float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 0.0f ) { Color = D3DXVECTOR4(r, g, b, a); } bool operator == ( Vertex& op ) { if(memcmp(&Pos, &(op.Pos), sizeof(D3DXVECTOR3))) { return false; } if(memcmp(&Color, &(op.Color), sizeof(D3DXVECTOR3))) { return false; } } bool operator != ( Vertex& op ) { return !((*this) == op); } Vertex operator = ( const Vertex& op ) { memcpy(this, &op, sizeof(Vertex)); return (*this); } Vertex operator *= ( Vertex& op ) { Pos.x *= op.Pos.x; Pos.y *= op.Pos.y; Pos.z *= op.Pos.z; return (*this); } }; static D3D10_INPUT_ELEMENT_DESC Layout2D[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; /* VERTEX INFORMATION NODE */ struct VertexInfo { vector<Vertex> Vertices; ID3D10Buffer* pVertexBuffer; ID3D10InputLayout* pVertexLayout; ID3D10Effect* pEffect; D3D10_PRIMITIVE_TOPOLOGY PrimitiveType; VertexInfo( void ) { pVertexBuffer = 0; pVertexLayout = 0; pEffect = 0; PrimitiveType = D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED; } ~VertexInfo( void ) { RELEASE(pVertexBuffer); RELEASE(pVertexLayout); RELEASE(pEffect); } }; /* GRAPHIC CLASS DEFINITION */ class Graphic { private: Device *pDevice; vector<VertexInfo> VertexContainer; public: Graphic ( void ); ~Graphic ( void ); void Invalidate ( void ); void SetDevice ( Device *pDevice ); void DrawTriangle2D ( Vertex* vertices, size_t n ); void Render ( void ); protected: // bool VCAdd ( VertexInfo& info ); void VCRelease ( void ); } /* class Graphic */; #endif /* GRAPHIC_H_ */
Graphic.cpp
#include "Graphic.h" Graphic::Graphic( void ) { Invalidate(); } Graphic::~Graphic( void ) { VCRelease(); } void Graphic::Invalidate( void ) { pDevice = 0; } void Graphic::SetDevice( Device *pDevice ) { if(pDevice != 0) { this->pDevice = pDevice; } } void Graphic::DrawTriangle2D( Vertex* vertices, size_t n ) { VertexInfo info; if(n < 3 || !pDevice) { return; } /* set vertex- and indexbuffer */ D3D10_PASS_DESC pd; ID3D10Effect *effect = 0; ID3D10EffectTechnique *technique = 0; if(false == pDevice->LoadShader("shader_2d.fx", &effect)) { return; } technique = effect->GetTechniqueByName("Render"); technique->GetPassByIndex(0)->GetDesc(&pd); if(false == pDevice->CreateVertexLayout(Layout2D, LAYOUT_SIZE(Layout2D), pd, &(info.pVertexLayout))) { return; } if(false == pDevice->CreateVertexBuffer((info.pVertexLayout), vertices, n*sizeof(Vertex), &(info.pVertexBuffer))) { return; } /* pack vertices into vector */ info.Vertices.push_back(vertices[0]); info.Vertices.push_back(vertices[1]); info.Vertices.push_back(vertices[2]); info.PrimitiveType = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST; info.pEffect = effect; /* Members will automatically deleted on destructor (Vertex), so increment the ref. counter */ info.pEffect->AddRef(); info.pVertexBuffer->AddRef(); info.pVertexLayout->AddRef(); VertexContainer.push_back(info); } void Graphic::Render( void ) { vector<VertexInfo>::iterator i; for(i = VertexContainer.begin(); i != VertexContainer.end(); i++) { ID3D10EffectTechnique *pTechnique = (*i).pEffect->GetTechniqueByName("Render"); pDevice->RTSetLayout((*i).pVertexLayout); pDevice->RTSetVertexBuffer(&((*i).pVertexBuffer), sizeof(Vertex), 0, (*i).PrimitiveType); pDevice->RTRenderVB(pTechnique); } } void Graphic::VCRelease( void ) { while(VertexContainer.empty() == false) { VertexContainer.pop_back(); } }
Die Window.h/.cpp lasse ich mal weg, denn damit hat das ganze ja nichts zu tun. Falls erwünscht kann ich diese aber gerne dazu editieren.
Ich hoffe ihr könnt mir helfen!
PS: Wer die Visual C++ Dateien haben will, der findet sie hier (übersichtlicher als im Forum): http://www.xup.in/dl,17273085/PingPongDX10.rar/
Liebe, und hoffnungsvolle, Grüße!
// Edit:
Sorry, hier noch die shader_2d.fx (HLSL):
struct PS_INPUT { float4 Pos : SV_POSITION; float4 Color : COLOR; }; // // Vertex Shader // PS_INPUT VS( float4 Pos : POSITION, float4 Color : COLOR ) { PS_INPUT Output; Output.Pos = Pos; Output.Color = Color; return Output; } // // Pixel Shader // float4 PS( PS_INPUT input ) : SV_Target { return input.Color; } technique10 Render { pass P0 { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); } }
-
Es ist nicht so ganz einfach einen fremden Code zu lesen ohne genaue Hinweise.
Auch wenn Du keine Fehlermeldungen zurück erhälst (ich kann aber nicht überall Fehlerabfragen erkennen!), kannst Du vielleicht die wichtigsten Stationen per Debugger überprüfen. Ist nach Rückgabe beim Erstellen des Devicezeigers wirklich ein Wert vorhanden (häufig 1.Fehler)? Das gleiche gilt beim VertexBuffer.
Mir fällt auf, dass Du die Werte für Deine Bildschirmeinstellungen nicht abfragst und sie mit 32Bit im Format ansetzt. Auch uiwidth kann ich nicht erkennen (finden). Versuche es noch einmal mit einer Auflösung von 800x600 und eventuell 24 Bit (je nach Einstellung Deiner Grafikkarte).
Gruß
-
Backface Culling ist aus?
Wenn du den Backbuffer mit einer Farbe clearst, wird dir dann wenigstens ein Fenster mit dieser Farbe angezeigt?
-
shurehand schrieb:
Es ist nicht so ganz einfach einen fremden Code zu lesen ohne genaue Hinweise.
Auch wenn Du keine Fehlermeldungen zurück erhälst (ich kann aber nicht überall Fehlerabfragen erkennen!), kannst Du vielleicht die wichtigsten Stationen per Debugger überprüfen. Ist nach Rückgabe beim Erstellen des Devicezeigers wirklich ein Wert vorhanden (häufig 1.Fehler)? Das gleiche gilt beim VertexBuffer.
Mir fällt auf, dass Du die Werte für Deine Bildschirmeinstellungen nicht abfragst und sie mit 32Bit im Format ansetzt. Auch uiwidth kann ich nicht erkennen (finden). Versuche es noch einmal mit einer Auflösung von 800x600 und eventuell 24 Bit (je nach Einstellung Deiner Grafikkarte).
Gruß
Naja, ich werd nacher nochmal genau nachschauen, wo keine Fehler abgefragt werden.
Das Device ist erstellt worden. Ich kann ja auch die anderen Objekte mit dem Device erstellen.
Wegen den Einstellungen: Ich hab die Einstellungen gewählt, da sie bei mir zutreffen, sie im Tutorial verwendet wurden, welches zuvor auch lief.
Ich werd's trotzdem mal mit 24 Bit versuchen.
this->that schrieb:
Backface Culling ist aus?
Wenn du den Backbuffer mit einer Farbe clearst, wird dir dann wenigstens ein Fenster mit dieser Farbe angezeigt?
Uhm, ich werd gleich mal nachschauen, was du damit meinst. *g*
Zum 2.: Jap.
(main.cpp) test_device.RTClear( r, g, b, a )
(device.cpp) pDevice->ClearRenderTargetView(pRenderTargetView, colorRGBA);// Edit:
Ah. Backface Culling per Default.Hab's gerade manuell deaktiviert und den Wireframe-Modi aktiviert, nichts.
D3D10_RASTERIZER_DESC rs_desc; rs_desc.FillMode = D3D10_FILL_WIREFRAME; rs_desc.CullMode = D3D10_CULL_NONE; pDevice->CreateRasterizerState(&rs_desc, &pState); pDevice->RSSetState(pState);
// Edit:
shurehand: Wo fällt dir auf das ich keine Fehler überprüfe? Ich seh gerade keine Stelle wo ich nicht überprüfen würde (Im Device.cpp jedenfalls)
-
Ok. Es geht!
Es lag an:
pDevice->OMSetRenderTargets( 0, 0, &pRenderTargetViews );
Der erste Parameter erwartete eine Anzahl der RTV's, und dieser war auf 0 gesetzt, somit konnte ich zwar den BB des SwapChain's clearen, aber nicht auf den BB vom RTV zeichnen, da ja keiner Angegeben war. *gg*
-
Sorry,
ich hatte mich falsch ausgedrückt. Ich meinte nicht abfangen, sondern auswerten. Die verschiedenen Rückgaben sagen meist viel mehr als man ahnt...Nur bei Failed ein return, sagt Dir erst einmal gar nichts.
Trotzdem schön das Du den Fehler gefunden und gepostet hast, dass tun leider nicht alle.
-
Richtig, aber bei einem so kleinem Programm kann man bei einem fehlerhaften Verhalten auch einfach Breakpoints setzen (so wie ich es mache :P) und dann den Fehlercode abfangen (Meistens gibt's vom Debug-Layer auch noch 'ne Nachricht).
Und wegen dem Fehler: Ja, ich hasse es, wenn ich Leute mit dem selben Problem finde, diese dann behoben sind, aber nicht erklärt wird wodurch diese behoben wurden.
// Edit:
Ich hätte da noch ein paar kleine Fragen, die mal immer auftauchen. Ich möchte aber nicht für jedes klitzekleines Problem einen Thread erstellen und bin auch meisten's eher der Forscher-Typ, suche mir also meistens einen Weg. Dennoch wäre es nicht schlecht, wenn ich jemanden kontaktieren könnte, der mir wohl die ein oder andere Frage beantworten könnte.
Wäre super wenn sich jemand per Mail melden könnte, da hier ja leider keine
PN's 'erlaubt' sind.Mail: avonarret@gmx.net
Liebe Grüße.