DirectX Hallucinagen?

Started by
13 comments, last by luke2 17 years, 8 months ago
Alrighty, I've recently started up with Direct X and Ive run into a problem (go figure). I wrote a class as a wrapper for the Vertex/Index buffers and when It didn't work; I went and basically copied the source out of my book into my code and when I ran that code I got some really weird stuff, flashing green and semi pink across the screen in sorta strips that jiggled around a bit. It was supposed to be an indexed cube. I should also note that I get absolutely no debug errors or warnings!
#define WIN32_LEAN_AND_MEAN
#define VC_LEANMEAN

#include<d3dx9.h>
#include"DXUtil.h"
//#include"DXGeomBuffer.h"

using namespace Util; 

// Our vertex stucture define.
#define D3DFVF_D3DVertex (D3DFVF_XYZ|D3DFVF_DIFFUSE)


// Function Prototypes...
void RenderScence(DXGeomBuffer GB);


// Direct3D objects.
//LPDIRECT3D9 Direct3D_Object = NULL;
//LPDIRECT3DDEVICE9 D3D_Device = NULL;
//LPDIRECT3DVERTEXBUFFER9 Vertex_Buffer = NULL;



// Vertex stucture with xyz position and color.
struct Vertex
{
   FLOAT x, y, z;
   //DWORD color;
};

Vertex Vs [8]; 
	
IDirect3DVertexBuffer9* vb;
IDirect3DIndexBuffer9* ib; 

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
       {
		   case WM_KEYUP:
            // If the user presses the escape key then exit the application.
            if(wParam == VK_ESCAPE)
               PostQuitMessage(0);
            break;

         case WM_DESTROY:
         case WM_CLOSE:
            PostQuitMessage(0);
            break;

            default:
               break;
       }

    return DefWindowProc( hwnd, message, wParam, lParam );
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
   MSG msg;                                           // Message object.
   HWND hwnd;                                         // Handle to the window.
   WNDCLASSEX windowClass;                            // Window class object.
   bool done = false;                                 // True then exit.

   // This is the Window class.
   windowClass.cbSize = sizeof(WNDCLASSEX);           // size of the WNDCLASSEX structure.
   windowClass.style = CS_HREDRAW | CS_VREDRAW;       // style of the window.
   windowClass.lpfnWndProc = WndProc;                 // Address to the windows procedure.
   windowClass.cbClsExtra = 0;                        // Extra class information.
   windowClass.cbWndExtra = 0;                        // Extra window information.
   windowClass.hInstance = hInstance;                 // Handle of application Instance.
   windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);// Window Icon.
   windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Load mouse cursor.
   windowClass.hbrBackground = NULL;                  // Background color.
   windowClass.lpszMenuName = NULL;                   // Menu.
   windowClass.lpszClassName = "UGPClass";            // Name of the window class.
   windowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);// Minimized window icon.

   // You must register you class with Windows.
   if(!RegisterClassEx(&windowClass)) return 0;

   // Create the window.
   hwnd = CreateWindowEx(NULL,                                       // The extended style.
                         "UGPClass",                                 // Window class.
                         "Direct3D Matrices Demo - by The Programming Ace",// Window name.
                          WS_OVERLAPPEDWINDOW | WS_VISIBLE |         // Window style.
                          WS_SYSMENU |WS_CLIPCHILDREN |              // Window style.
                          WS_CLIPSIBLINGS,                           // Window style.
                          100, 100,                                  // X, Y coords.
                          640, 480,                                  // Window size.
                          NULL,                                      // Handle to parent window.
                          NULL,                                      // Menu.
                          hInstance,                                 // Handle to app instance.
                          NULL);                                     // Pointer to window.

   // If there was an error with creating the window, then close the program.
   if(!hwnd) return 0;

   ShowWindow(hwnd, SW_SHOW);    // Show the window.
   UpdateWindow(hwnd);           // Update its display.

   done = false;  // false = run program, true means stop.

   // Initialize Direct3D.  If fails then we don't want to run the application.
   if(!Util::DXInit(hwnd, false)) done = true;

   // Application loop.
   DXGeomBuffer GB;
   while(!done)
      {
         if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
            {
               // If a quit message is received then stop rendering and quit the app.
               if(msg.message == WM_QUIT)
                  {
                     done = true;
                  }

               TranslateMessage(&msg);
               DispatchMessage(&msg);
            }
         else
            {
               RenderScence(GB);
            }
      }

    // Here we shutdown Direct 3D.
	  Util::DXShutDown();
	  vb->Release();
	  ib->Release();

   // Here we unregister the window class with the OS.
   UnregisterClass("UGPClass", windowClass.hInstance);

   return (int)msg.wParam;
}

void RenderScence(DXGeomBuffer GB)
{
	IDirect3DDevice9* device =	DXDevice();
	//GB.DXCreateVertBuffer(3 * sizeof(Vertex), 0, D3DFVF_XYZ, D3DPOOL_MANAGED);
if(vb == 0)
{
	
	device->CreateVertexBuffer(	8 * sizeof(Vertex), D3DUSAGE_WRITEONLY, D3DFVF_XYZ,D3DPOOL_MANAGED,&vb ,0);       
	device->CreateIndexBuffer(36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,D3DPOOL_MANAGED, &ib, 0); 
	vb->Lock(0,0, (void**)&Vs,0);

	
	Vs[0].x = -1.0;
	Vs[0].y = -1.0;
	Vs[0].z = -1.0;
	//Vs[0].color = D3DCOLOR_XRGB(255,0,0);

	Vs[1].x = -1.0;
	Vs[1].y = 1.0;
	Vs[1].z = -1.0;
	//Vs[1].color = D3DCOLOR_XRGB(255,0,0);

	Vs[2].x = 1.0;
	Vs[2].y = 1.0;
	Vs[2].z = -1.0;
	//Vs[2].color = D3DCOLOR_XRGB(255,0,0);
	
	Vs[3].x = 1.0;
	Vs[3].y = -1.0;
	Vs[3].z = -1.0;

	Vs[4].x = -1.0;
	Vs[4].y = -1.0;
	Vs[4].z = 1.0;

	Vs[5].x = -1.0;
	Vs[5].y = 1.0;
	Vs[5].z = 1.0;

	Vs[6].x = 1.0;
	Vs[6].y = 1.0;
	Vs[6].z = 1.0;

	Vs[7].x = 1.0;
	Vs[7].y = -1.0;
	Vs[7].z = 1.0;
	vb->Unlock(); 

	WORD* indices = 0;
	ib->Lock(0,0, (void**)&indices,0);

	indices[0] = 0; indices[1]=1;indices[2] = 2;
	indices[3] = 0; indices[4]=2;indices[5] = 3;

	indices[6] = 4; indices[7]=6; indices[8] = 5;
	indices[9] = 4; indices[10]=7; indices[11] = 6;

	indices[12] = 4; indices[13] = 5; indices[14] = 1;
	indices[15] = 4; indices[16] = 1; indices[17] = 0;

	indices[18] = 3; indices[19] = 2; indices[20] = 6;
	indices[21] = 3; indices[22] = 6; indices[23] = 7;

	indices[24] = 1; indices[25] = 5; indices[26] = 6;
	indices[27] = 1; indices[28] = 6; indices[29] = 2;

	indices[30] = 4; indices[31] = 0; indices[32] = 3;
	indices[33] = 4; indices[34] = 3; indices[35] = 7;

	ib->Unlock();

	
	D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	D3DXMATRIX v;
	D3DXMatrixLookAtLH(&v,&position, &target, &up);

	device->SetTransform(D3DTS_VIEW, &v);


	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(
			&proj,                        // result
			D3DX_PI * 0.5f,               // 90 - degrees
			(float)1024 / (float)768, // aspect ratio
			1.0f,                         // near plane
			1000.0f);                     // far plane
	device->SetTransform(D3DTS_PROJECTION, &proj);

	device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
	
	//device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
		device->BeginScene();

		device->SetStreamSource(0, vb, 0, sizeof(Vertex));
		device->SetIndices(ib);

		device->SetFVF(D3DFVF_XYZ);

		// Draw one triangle.
		device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);

		device->EndScene();
		device->Present(0, 0, 0, 0);

	//GB.DXUpdateVertBuffer((void*)Vs, (UINT)sizeof(Vs));
	//GB.DXDrawGeomBuffer();
};
DXUTil has only standard dx shutdown and init and a 'getdxobject' type method. DXUtil.h

#ifndef DXUTIL_H
#define DXUTIL_H


#include <d3dx9.h>
 
//Our Global Device and Object
extern	IDirect3DDevice9*	dx3DDevice;
extern	IDirect3D9*			dx3DObject;



namespace Util
{
	
 
	
	bool DXInit(HWND hwnd, bool windowed);
	bool DXShutDown();

	IDirect3DDevice9* DXDevice(); 
}; 



#endif //EOF DXUtil.h
	
DXUtil.cpp


#include "DXUtil.h" 

IDirect3DDevice9*	dx3DDevice;
IDirect3D9*			dx3DObject;




bool Util::DXShutDown()
{
	if(dx3DObject != NULL)
		dx3DObject->Release();
	dx3DObject = NULL;
	
	if(dx3DDevice != NULL)
		dx3DDevice->Release();
	dx3DDevice = NULL;

    return true; 
}

bool Util::DXInit(HWND hwnd, bool windowed)
{
	D3DDISPLAYMODE			DisplayMode;		//DisplayMode Format

	D3DPRESENT_PARAMETERS	PresParams;			//Presentation Parameters

	D3DCAPS9				Capabilities;		//Device Capabilities

	

	//Initialize Everything Now:

	dx3DObject = Direct3DCreate9(D3D_SDK_VERSION); 

	//Check For Success:
	if(dx3DObject == NULL)
    {
       MessageBox(NULL, "Error, couldn't initialize DirectX!?!",
                  "Error!", MB_OK);
       return false;
    }

	//Set the DisplayMode Data With the Current DisplayMode:
    if(FAILED(dx3DObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode)))
	{
		MessageBox(NULL, "Error setting the display mode.", "Error!", MB_OK);
         return false;
	}

	if(FAILED(dx3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Capabilities)))
	{
		MessageBox(NULL, "Error retrieving Device Caps", "Error!", MB_OK);
		return false;
	}
	
	//Decide if We'll have software or hardware vertex processing:
	DWORD VertexProcessing = 0;

	if(Capabilities.VertexProcessingCaps != 0)
		VertexProcessing |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		VertexProcessing |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	//Set the PresentationParams based on fullscreen true/false:
	ZeroMemory(&PresParams, sizeof(PresParams)); 
	if(windowed == true)
      {
         PresParams.Windowed = FALSE;               // Window mode (fullscreen).
         PresParams.BackBufferWidth = 640;
         PresParams.BackBufferHeight = 480;
      }
    else
       PresParams.Windowed = TRUE;                   // Window mode (notfullscreen)
    PresParams.SwapEffect = D3DSWAPEFFECT_DISCARD;   // ation (see doc)
    PresParams.BackBufferFormat = DisplayMode.Format;// he area of the screen.
    PresParams.BackBufferCount = 1;                  // Number of back buffers.
    PresParams.EnableAutoDepthStencil = TRUE;        // Check documentation.
    PresParams.AutoDepthStencilFormat = D3DFMT_D16;  // Check documentation.
	PresParams.BackBufferHeight = 800;


	HRESULT hresult; 
	//Create the DX Device:
	if(FAILED(dx3DObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
                                           VertexProcessing,
                                           &PresParams, &dx3DDevice)))
	{
		
		hresult = dx3DObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, VertexProcessing,
			&PresParams, &dx3DDevice); 
		switch(hresult)
		{
		case D3DERR_INVALIDCALL:
			MessageBox(NULL, "Invalid Call", "Error!", MB_OK);
			break;
		case D3DERR_NOTAVAILABLE:
			MessageBox(NULL, "Not Available", "Error!", MB_OK);
			break;
		case D3DERR_DEVICELOST:
			MessageBox(NULL, "Device Lost", "Error!", MB_OK);
			break; 
		}
		hresult; 
	} 

	// SetRenderState() will set a parameter for the rendering.  Here we turn off lighting.
    dx3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

   // Disable culling.  This will render the front and back of the triangles.
   dx3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);


	return true; 

}


IDirect3DDevice9* Util::DXDevice()
{
	return dx3DDevice;
} 

[Edited by - jollyjeffers on August 10, 2006 11:40:12 AM]
Advertisement
Alternating pink/green screens is a signal from the DX debug runtimes. It typically means that you're presenting an uncleared buffer - e.g. missing a call to Clear(). It's not technically an error, hence you might not get any debug warnings/errors reported.

Get familiar with PIX for Windows - capture a replayable stream or a single frame and step through it. See what happens and when, you should be able to find out whats going wrong that way.

P.S. Long code listings should be in 'source' tags, not 'code' ones. It'd also be appreciated if you cut out any irrelevant code (e.g. your MsgProc and WinMain functions probably aren't useful). I can also think of several much better subject lines (a good subject line will attract the right attention to your thread and help you get good answers).

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Im sorry about that, it won't happen again; and I didn't know about the green/pink signal. But the reason that I commented out my clear method was because I was getting an entirely clear screen (save the color specified in clear) and it was supposed to be rendering a cube. Since I get no errors in debug, (and I can't even figure out how to use PIX , yet) Im guessing that I've done something stupid ... like rendering it behind the camera or something.
Well if it works when your not clearing its not likely to do with the camera. I havn't looked at your code but the problem sounds to me like your calling Clear at the wrong time. If it only shows up when you dont clear then make sure your NOT clearing after you draw, or before you present.
I haven't done DX for awhile but shouldn't you clear first then draw the cube?
Well I do; It goes like this in psuedocode:

set up cube vertices and index data...

clear(...)
device->beginscene();
drawprimitive(...);
device->endscene();
device->present(...);
I believe you need to disable lighting. There might be some other render states that are missing, but that is one problem I have had a lot when starting up new projects.
It's possible that clear is failing and you're not getting debug output because you have an older SDK version (Your runtime version needs to be the same as the SDK version). What flags do you pass to Clear()? If you tell it to clear the Z-buffer or stencil buffer and there isn't one, it'll fail and not clear the backbuffer either.

EDIT: D'oh, just realised you posted your code in your original post. Ok, so that all looks fine, but my point about missing debug info still remains.
It's good practice to check all of your return values to make sure nothing goes wrong.
In my code, I check all non-trivial functions (A trivial function [IMO] is something like SetTextureStageState, where if it fails, the result might look a bit odd, but it's recognisable what the cause is to me) properly with the FAILED / SUCCEEDED macros, and report errors back to the user (Or log them and quit), and all trivial functions get checked an asserted that the return value SUCCEEDED. E.g., something like:
hResult = m_pDevice->SetTextureStageState(...); Assert(SUCCEEDED(hResult));

I'd advise you to check your return values, particularly of Clear(), Present() and SetStreamSource(). And you should definitely check the return values from CreateVertexBuffer() (And other create resource calls) and Lock(), since failing to notice an error there will just crash your application and will be very hard to debug from an error report.
wow - sounds like a good idea!
d3d drugs!
Thanks for the suggestions, consider them followed :) I've written code to check for a failure on any HRESULT and Im not getting anything, Im still looking fo now...

As for my versions, My SDK says only that its version :9.0 Update (October 2004)
and my Runtime is 9.0c. So do I have the right SDK version? Or should I go looking for SDK9.0c?

This topic is closed to new replies.

Advertisement