JonW

Members
  • Content count

    518
  • Joined

  • Last visited

Community Reputation

173 Neutral

About JonW

  • Rank
    Advanced Member
  1. Thanks for the quick responses. Actually the main process thread starts with the program, it starts the OLE drag-and-drop thread at the early onset, and when the user closes the program, the main process thread tells the OLE thread to close and waits for it to close before exiting. The drag-and-drop thread sits in its message pump just like the main thread (as required when existing in a single-threaded COM apartment) and dispatches messages to the invisible window that OLE creates for its own use. My question basically is whether or not it is okay to pass the main window's handle, which is "owned" by the process thread, to the OLE registration function in the drag-and-drop thread. OLE is then working with the main window, but from a second thread--I'm not sure if this is proper or not.
  2. What would the potential negative consequence be of both threads having the same priority? Some sort of deadlock situation?
  3. Hi, I've been using a multi-threaded COM apartment for my application's threads in order to achieve the best performance I can for anything that uses COM. However I recently wanted to add support for drag and drop to my program window. Windows uses OLE for this type of operation. According to MSDN, "applications that use the following functionality must call OleInitialize before calling any other function in the COM library: Clipboard Drag and drop Object linking and embedding (OLE) In-place activation" Okay fine, so I have to call OleInitialize. The problem is, OleInitialize wants to put the thread into a single-threaded apartment: "OleInitialize calls CoInitializeEx internally to initialize the COM library on the current apartment. Because OLE operations are not thread-safe, OleInitialize specifies the concurrency model as single-thread apartment." Since I want to be able to stick with an MTA for the rest of the application, I decided to create a separate thread running in an STA for the express purpose of handling drag and drop requests. The thread registers the main window as a drop target and then sits and pumps messages for OLE (which is required in a STA). When it gets the signal to quit, it removes drag and drop support from the main window and exits: ////////////////////////////////////////////////////////////////////////// // Thread procedure for running OLE drag and drop. We use a separate thread // because OLE's drag and drop feature requires a single-threaded COM // apartment, and we want our application to be able to use a multi-threaded // apartment. uint __stdcall ThreadProc(void *arguments) { // Applications that use drag and drop must call OleInitialize before calling any other function in the COM library. OleInitialize(NULL); CDropTarget *target; try { target = new CDropTarget(); } catch (bad_alloc) { StatusLog_ReportOutOfMemory(); OleUninitialize(); _endthreadex(0); return 0; } // The CoLockObjectExternal function prevents the reference count of an object // from going to zero, thereby "locking" it into existence until the lock is // released. CoLockObjectExternal(target, TRUE, FALSE); // Tell OLE that the window is a drop target. HRESULT hResult = RegisterDragDrop(g_hMainWnd, target); if (hResult != S_OK) StatusLog_ReportWarning(L"Drag and Drop", L"Unable to register drag and drop (error code %d).", hResult); // Each single-threaded apartment must have a message loop to handle calls from other // processes and apartments within the same process. If we didn't have this message loop, // we would hang other applications that are acting as drag-drop sources for us because // their message could not get handled. while (MsgWaitForMultipleObjects(1, &g_hEvtStopThread, FALSE, INFINITE, QS_ALLINPUT)) { MSG msg; if (GetMessage(&msg, NULL, NULL, NULL) <= 0) break; TranslateMessage(&msg); DispatchMessage(&msg); } // Remove drag and drop from the window. RevokeDragDrop(g_hMainWnd); // Remove the strong lock. CoLockObjectExternal(target, FALSE, TRUE); // Release our own reference. target->Release(); OleUninitialize(); // Calling end is not strictly necessary but according to MSDN is a good practice. _endthreadex(0); return 0; } My question is: Is it a bad practice to setup OLE on a dedicated thread like this and give it a handle to the main window running on the original thread? The application runs fine but I'm nervous that I've opened the door to some sort of concurrancy issue or other evil thing. I know this is probably a difficult question to answer because the RegisterDragDrop function's documentation doesn't include any details on this, but I'm curious as to whether anyone else is familiar with doing something like this as a general OLE practice. Thanks!!
  4. You both have some good points. I tend to overthink performance concerns like this way too much... As for the permissions issues, I *believe* you only need the administrator privileges to turn off file zeroing (as this is a requirement of C2 security). I haven't tried it, but you should be able to still preallocate with basic user privileges by using SetFilePointer and SetEndOfFile as mentioned. For SetLimit in .NET, I have no idea.
  5. Another useful technique for fast writing if anyone is curious, is to preallocate the file. A good explanation of the technique from http://www.pcreview.co.uk/forums/thread-1484343-2.php): Quote: > NTFS zeros the file whenever you extend it. If you just use WriteFile() > to extend the file, the same zero'ing occurs. This is for C2 security > requirements, to prevent folks from extending their files over other > peoples files and taking control of the data. > > If you extend a file a little at a time, then for every extension: > Seek to cluster location > Zero out enough space for the addition > Seek back to the start of the write > Write the file data > > (so, 2 seeks for the write) > > Also, if something else has written to the adjoining cluster in the > interim since the last write, then the file will fragment. This happens > all the time in logging applications. > > So, if you pre-allocate the file, you only pay for the zeroing 1 time. > This will prevent any other files from intruding on your nicely sequential > allocation and optimize write speeds. If you only pay the price once, > then the the runtime performance is the same as bypassing the zeroing. > The clusters do not get zero'd until you call SetEndOfFile(). So the > order is: > > CreateFile > SetFilePointer (size of file you intend to create) > SetEndOfFile (commit the file) > SetFilePointer(beginning) > start writing > > No more zeroing will occur unless you overrun the file size allocated. > Also, fragmentation will be minimized. The zeroing happens very, very > fast b/c there is no seeking. A single seek to the start of the file, > then sequential writes so the writes occur at the disk speed. You can use the SetLength() function in .NET for the same purpose.
  6. Quote:Original post by Antheus "There are only two hard problems in Computer Science: cache invalidation and naming things." -- Phil Karlton Yes, that is true, the second problem especially. In my case, I won't be doing much "caching", as I will be using an index to jump to a position in the 3D file and then do a sequential read of large blocks (64KB+) to extract some information from it. Once a block is processed in the sequence, it can be thrown out. As for the size of the entire dataset--maybe a few hundred MB to a couple GB. That's not that big anymore, right? ;)
  7. Thanks for the opinions everyone. Quote:Original post by samoth Maybe the Wiki wording is just a bit misleading insofar as some database systems (but not all) will avoid going through the filesystem cache, for various reasons. Maybe that is what they meant. I'm considering going the route of asking Windows not to cache my I/Os for me (unbuffered mode), because it is fairly simple to do your own caching (it only adds a few constraints on the sizes of buffers as well as their placement in memory and in the file). This Microsoft Research paper advocates turning off buffering when spreading the I/O operations across several drives -- unbuffered I/O was over 8x faster (there's some cool stuff in Microsoft Research by the way). Buffering doesn't make much of an I/O speed difference for a single drive, but CPU cycles per byte transferred drop to 1/10th of the amount with buffered I/O (the study used the .NET Framework). You all have confirmed my suspicion that custom low-level I/O is way more complicated than what I need. The reason a typical database doesn't suit my needs is because I need to look up 3D data with continuous levels of detail. Most RDBMS's today have quad tree support for spatial data of several dimensions, but the LOD aspect of my problem isn't well suited to records, and the data will be read-only in production. Also the data objects are really not that big, I just want to read them quickly :-) I will have to go through those systems in your link phresnel; I don't know that any of them will do what I want here, but it looks like good information! I think I have a direction now, but I still appreciate any comments on the matter.
  8. Your idea is sound. I just tried it out on Visual Studio 2005 by the following steps: 1.) Created a new solution 2.) Added two static lib projects and a Win32 executable project 3.) Added a single cpp file to each lib 3.) Placed a call to a function "MyFunction()" in the first lib 4.) Added the line: extern "C" void MyFunction(); To tell the compiler that "MyFunction" will be found at link time (i.e. it is "non-static"), with the "C" modifier to tell the compiler to leave off C++ symbol decoration. 5.) Created the function: extern "C" void MyFunction() {} In the cpp file of the second lib. The linker joined the two libs just fine. Can you provide some information on your setup: the development environment you're using, and how you are building and linking the files. Also: don't forget about your option of using a DLL for your intermediate library, if that may fit your deployment better.
  9. Hi everyone, I have some questions regarding fast disk reading on a Windows server. A lot of people who are working on MMO games or such that require a lot of data retrieval are probably using commercial database management systems. I'm interested however in retrieving large amounts of data using a custom format that would not fit well with a relational DBMS, therefore I want to roll my own high-speed data retrieval code. The information that I'm most interested in is how a modern DBMS, such as SQL Server or Oracle, performs its I/O on the Windows platform nowadays. I studied databases fairly heavily in college and I was always taught that for the most efficient disk reading, you store your data in disk blocks in the order that it will be read (as least as far as you can manage) so that the blocks can be sequentially read with minimal seek / rotational delays, in parallel with the CPU processing of the blocks being read. The Windows file system does not guarantee that anything you write will be in nice blocks (because the actual disk block has NTFS information on top of your written data), or that it will even be in sequential order because the file blocks may be scattered all over the disk, even when they are written in sequence by the program. According to Wikipedia, "Database management systems often use their own block I/O for improved performance and recoverability as compared to layering the DBMS on top of a file system." My question is, do modern Windows DBMS's perform direct block access, or do they go through the file system? Is direct I/O still beneficial in a multitasking operating system where several programs are all using the disk at once? Can it be performed without stepping all over the NTFS file system and corrupting data? These may be tough questions, but I appreciate any guidance that can be provided. Thank you very much!
  10. Nevermind, I realized that the problem was because I was passing the vertices in screen-space, so affine interpolation was being used. See http://en.wikipedia.org/wiki/Texture_mapping: Quote: If these texture coordinates are linearly interpolated across the screen, the result is affine texture mapping. This is a fast calculation, but there can be a noticeable discontinuity between adjacent triangles when these triangles are at an angle to the plane of the screen.
  11. Hey folks, In my Direct3D 9.0c application I am drawing a 2D quadrilateral using two triangles in a "triangle strip". I would like to assign a value to each of the four vertices of the quad that will get interpolated across the shape and fed to the pixel shader. The problem that I'm having is that, since the interpolation of the vertex values occurs across each of the two triangles seperately, the values are not smooth across the entire quad. There is a nasty "seam" in the values along the diagonal where the two triangles come together. My question is: Is there a good alternative or work-around in order to interpolate correctly across a 2D quadrilateral? The only thing I can think of is to create a giant triangle in place of the quad, and use the pixel shader to "hide" areas of the triangle that I don't want. I would also have to perform a complex calculation to come up with the proper values for the three triangle vertices that would result in an interpolation across the surface that is identical to the quad I want. I greatly appreciate any additional insight or words of wisdom; thank you!
  12. Erik, I really cannot thank you enough. That is exactly what I was looking for. I modified the shader resource view creation like so: D3DX10_IMAGE_INFO InfoFromFile; D3DX10_IMAGE_LOAD_INFO LoadImageInfo; // Read info from the file D3DX10GetImageInfoFromFile(L"shader.bmp", NULL, &InfoFromFile); LoadImageInfo.Width = InfoFromFile.Width; LoadImageInfo.Height = InfoFromFile.Height; LoadImageInfo.Depth = InfoFromFile.Depth; LoadImageInfo.FirstMipLevel = 0; LoadImageInfo.MipLevels = 1; LoadImageInfo.Usage = D3D10_USAGE_DEFAULT; LoadImageInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE ; LoadImageInfo.CpuAccessFlags = 0; LoadImageInfo.MiscFlags = 0; LoadImageInfo.Format = InfoFromFile.Format; LoadImageInfo.Filter = D3DX10_FILTER_NONE; LoadImageInfo.MipFilter = D3DX10_FILTER_NONE; LoadImageInfo.pSrcInfo = &InfoFromFile; // Formats supported by texture creation function: BMP, JPG, PNG, DDS, TIFF, GIF, WMP hr = D3DX10CreateShaderResourceViewFromFile(g_pd3dDevice, L"shader.bmp", &LoadImageInfo, NULL, &g_pTextureRV, NULL); if (FAILED(hr)) return hr; ...and the texture now samples correctly (I know, it's not good code... I'm beat down though.) You are a godsend!! And thanks also to everyone else who may have looked at this.
  13. Hey folks, I have an issue with a Direct3D 10 application that has had me tearing my hair out for many many hours. I have broken the problem down into it's near-bare essense in a small program based off of the Microsoft tutorials. This program consists of a simple pixel shader that draws a blue circle on a blue background using 2 samples from a 512x512 texture. The pixel shader code looks like this: Texture2D shdrTexture; SamplerState linearSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; }; // // Vertex Shader // float4 VS( float4 Pos : POSITION ) : SV_POSITION { return Pos; } // // Pixel Shader // float4 PS( float4 Pos : SV_POSITION ) : SV_Target { // Draw a circle at position 200,200 with radius of 100. Pos.x -= 200; Pos.y -= 200; float rad = sqrt(Pos.x*Pos.x + Pos.y*Pos.y); // Draw with one texture color or the other. float2 texCoord; if (rad > 100) texCoord = float2( 0.19921875f, 0.298828125f ); else texCoord = float2( 0.439453125f, 0.369140625f ); float4 clr = shdrTexture.Sample(linearSampler, texCoord); return clr; } technique10 Render { pass P0 { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); } } The image, however, turns out like this: As you can see, even though we are only sampling 2 pixels, the circle ends up with a white border. The remainder setup code for the program looks like this, in its entirety: #include <Windows.h> #include <d3d10.h> #include <d3dx10.h> //-------------------------------------------------------------------------------------- // Structures //-------------------------------------------------------------------------------------- struct SimpleVertex { D3DXVECTOR3 Pos; }; //-------------------------------------------------------------------------------------- // Forward declarations //-------------------------------------------------------------------------------------- HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow); HRESULT InitDevice(); HRESULT InitRender(); void Cleanup(); void Render(); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //-------------------------------------------------------------------------------------- // Global Variables //-------------------------------------------------------------------------------------- HINSTANCE g_hInst = NULL; HWND g_hWnd = NULL; D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL; ID3D10Device* g_pd3dDevice = NULL; IDXGISwapChain* g_pSwapChain = NULL; ID3D10RenderTargetView* g_pRenderTargetView = NULL; ID3D10Effect* g_pEffect = NULL; ID3D10EffectTechnique* g_pTechnique = NULL; ID3D10InputLayout* g_pVertexLayout = NULL; ID3D10Buffer* g_pVertexBuffer = NULL; ID3D10ShaderResourceView* g_pTextureRV = NULL; ID3D10EffectShaderResourceVariable* g_pTexture = NULL; //-------------------------------------------------------------------------------------- // Entry point to the program. Initializes everything and goes into a message processing // loop. Idle time is used to render the scene. //-------------------------------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); if(FAILED(InitWindow(hInstance, nCmdShow))) return 0; if(FAILED(InitDevice())) { Cleanup(); return 0; } if (FAILED(InitRender())) { Cleanup(); return 0; } // Main message loop MSG msg = {0}; while(WM_QUIT != msg.message) { // Give all messages that need to be processed priority over the rendering cycle. if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { Render(); } } Cleanup(); return (int)msg.wParam; } //-------------------------------------------------------------------------------------- // Register class and create window //-------------------------------------------------------------------------------------- HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ) { // Register class WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = L"SDRWINDOW"; wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION); if( !RegisterClassEx( &wc ) ) return E_FAIL; // Create window g_hInst = hInstance; RECT rc = { 0, 0, 400, 400 }; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); g_hWnd = CreateWindow( L"SDRWINDOW", L"Pixel Shader Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL ); if( !g_hWnd ) return E_FAIL; ShowWindow( g_hWnd, nCmdShow ); return S_OK; } //-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { // Create a device and a swap chain. The device object is used to perform rendering onto a buffer, // and also contains methods to create resources. The swap chain takes the buffer that the device // renders to an displays it on the monitor screen. It swaps the buffers so that there is always // one read-only buffer that is actually on the screen. HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG; #endif D3D10_DRIVER_TYPE driverTypes[] = { D3D10_DRIVER_TYPE_HARDWARE, D3D10_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] ); DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice ); if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Create a render target view ID3D10Texture2D* pBackBuffer; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBackBuffer ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL ); // Setup the viewport D3D10_VIEWPORT vp; vp.Width = width; vp.Height = height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pd3dDevice->RSSetViewports( 1, &vp ); return S_OK; } //-------------------------------------------------------------------------------------- // Create vertex buffers and shaders. //-------------------------------------------------------------------------------------- HRESULT InitRender() { HRESULT hr = S_OK; // Create the effect DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS; hr = D3DX10CreateEffectFromFile( L"Shader.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0, g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL ); if( FAILED( hr ) ) { MessageBox( NULL, L"Couldn't load the FX file!", L"Error", MB_OK ); return hr; } // Obtain the technique defined in the effect file g_pTechnique = g_pEffect->GetTechniqueByName( "Render" ); // Obtain the variables g_pTexture = g_pEffect->GetVariableByName("shdrTexture")->AsShaderResource(); // Define the input layout D3D10_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = sizeof( layout ) / sizeof( layout[0] ); // Create the input layout D3D10_PASS_DESC PassDesc; g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc ); hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &g_pVertexLayout ); if( FAILED( hr ) ) return hr; // Set the input layout g_pd3dDevice->IASetInputLayout( g_pVertexLayout ); // Create vertex buffer SimpleVertex vertices[] = { D3DXVECTOR3( -1, -1, 0 ), D3DXVECTOR3( -1, 1, 0 ), D3DXVECTOR3( 1, -1, 0 ), D3DXVECTOR3( 1, 1, 0) }; D3D10_BUFFER_DESC bd; bd.Usage = D3D10_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 4; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; D3D10_SUBRESOURCE_DATA InitData; InitData.pSysMem = vertices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ); if( FAILED( hr ) ) return hr; // Set vertex buffer UINT stride = sizeof( SimpleVertex ); UINT offset = 0; g_pd3dDevice->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset ); // Set primitive topology g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); // Formats supported by texture creation function: BMP, JPG, PNG, DDS, TIFF, GIF, WMP hr = D3DX10CreateShaderResourceViewFromFile(g_pd3dDevice, L"shader.bmp", NULL, NULL, &g_pTextureRV, NULL); if (FAILED(hr)) return hr; // Set the map texture variable hr = g_pTexture->SetResource(g_pTextureRV); if (FAILED(hr)) return hr; return S_OK; } //-------------------------------------------------------------------------------------- // Render the frame //-------------------------------------------------------------------------------------- void Render() { // Clear the back buffer float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; // red,green,blue,alpha g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor ); // Render a triangle D3D10_TECHNIQUE_DESC techDesc; g_pTechnique->GetDesc( &techDesc ); for( UINT p = 0; p < techDesc.Passes; ++p ) { // Bind the shaders for this pass to stages in the pipeline g_pTechnique->GetPassByIndex( p )->Apply( 0 ); // Process the vertex data passed into the pipeline g_pd3dDevice->Draw( 4, 0 ); } // Present the information rendered to the back buffer to the front buffer (the screen) g_pSwapChain->Present( 0, 0 ); } //-------------------------------------------------------------------------------------- // Clean up the objects we've created //-------------------------------------------------------------------------------------- void Cleanup() { if( g_pd3dDevice ) g_pd3dDevice->ClearState(); if( g_pVertexBuffer ) g_pVertexBuffer->Release(); if( g_pVertexLayout ) g_pVertexLayout->Release(); if (g_pTextureRV ) g_pTextureRV->Release(); if( g_pEffect ) g_pEffect->Release(); if( g_pRenderTargetView ) g_pRenderTargetView->Release(); if( g_pSwapChain ) g_pSwapChain->Release(); if( g_pd3dDevice ) g_pd3dDevice->Release(); } //-------------------------------------------------------------------------------------- // Called every time the application receives a message //-------------------------------------------------------------------------------------- LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps; HDC hdc; switch( message ) { case WM_PAINT: hdc = BeginPaint( hWnd, &ps ); EndPaint( hWnd, &ps ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; } Here is the test texture that I am using (use "Save Target As..."): shader.bmp The two colors are coming from the 2 dark regions of the texture. The circle's outline is still white even if the texture's white color is changed. So as you can see, the texture "Sample" function is returning a different color for the same texel depending on what pixels have already been drawn!! It is the weirdest thing, and I can't even theorize what might be going on here. I would greatly appreciate any insight that could be provided. If you have any idea at all at what might be wrong, that would be more information that I already have :-D Thanks!!
  14. Thanks for the great responses. I didn't realize that there were smartphones with USB input; are these the full-sized flat, wide USB ports? Those mini programmable boards are great, I might get one of those beagleboards even if it doesn't work out for this project :)
  15. Hey group, I'm trying to find a piece of equipment to solve a problem, and this is the best community that I know of to ask this sort of question. For a voice recognition project, I'd like to connect a basic USB microphone headset to a portable/wearable computing device. The only reason I need the computer device at all is to run the voice recognition and audio output algorithms, so I would like a device that has USB input and a small cheap screen or no screen at all (for my intention, the only input will be the microphone, and the only output will be the audio). I don't care if its Windows, Linux, or whatever, as long as it can be programmed. I'm not concerned with how much work is involved, so if anyone knows of a good microcontroller setup or something that can be interfaced to USB, I am open to that as well. I studied electrical engineering in college so I'm slightly comfortable with embedded stuff. I've considered a MID (mobile internet device) or ultra-mobile PC (http://en.wikipedia.org/wiki/Ultra-Mobile_PC), if anyone knows a good device in this category. Thanks folks!