   Skybox Problems - Revisited
  My starfield skybox did not look right, so I decided to debug further by creating an image with the axi labels and arrows pointing to the edges of each face.Now several problems are apparent:1) The +X face is not rendered at all.2) I have horrible purple or brown triangles appearing on all faces as I rotate, except for my z faces.3) The arrows are expected to align at the edges of my screen, but each face is slightly wider than the screen.I have played with depth testing, the perspective matrix, and verified my geomety data several times over.Anyone have ideas on how to solve these problems?#include "SkyBox.h"// Common Lib Includes#include "StringUtil.h"#include "BaseException.h"// Standard Includes#include <vector>#include <string>using namespace common_lib_cpisz;//---------------------------------------------------------------------------SkyBox::SkyBox(ID3D10Device & device, TextureManager & textureManager, EffectManager & effectManager, InputLayoutManager & inputLayoutManager,const std::string & textureFileName_cubeFaces)   :   m_device(device),   m_effectManager(effectManager),   m_inputLayout(NULL){   BaseException exception("Not Set",  "SkyBox::SkyBox(ID3D10Device & device, TextureManager & textureManager, EffectManager & effectManager, InputLayoutManager & inputLayoutManager, const std::string & textureFileName_cubeFaces)",  "SkyBox.cpp");   // Create geometry to render   //   // Geometry will be inward facing quads that are renderable as triangle strips   std::vector<Position>   positions;   std::vector<TexCoord2D> texCoords;   // Pos Xpositions.push_back(Position(  1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position(  1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.16666666666666666666666666666667f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.16666666666666666666666666666667f, 0.0f ));   // Neg Xpositions.push_back(Position( -1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.16666666666666666666666666666667f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.16666666666666666666666666666667f, 0.0f ));positions.push_back(Position( -1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.33333333333333333333333333333333f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.33333333333333333333333333333333f, 0.0f )); // Pos Ypositions.push_back(Position( -1.0f,  1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 0.33333333333333333333333333333333f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 0.33333333333333333333333333333333f, 0.0f ));positions.push_back(Position(  1.0f,  1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 0.5f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 0.5f, 0.0f ));// Neg Ypositions.push_back(Position( -1.0f, -1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 0.5f, 1.0f ));positions.push_back(Position( -1.0f, -1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 0.5f, 0.0f ));positions.push_back(Position(  1.0f, -1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 0.66666666666666666666666666666667f, 1.0f ));positions.push_back(Position(  1.0f, -1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 0.66666666666666666666666666666667f, 0.0f ));   // Pos Zpositions.push_back(Position( -1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.66666666666666666666666666666667f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.66666666666666666666666666666667f, 0.0f ));positions.push_back(Position(  1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.83333333333333333333333333333333f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.83333333333333333333333333333333f, 0.0f ));   // Neg Zpositions.push_back(Position(  1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.83333333333333333333333333333333f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.83333333333333333333333333333333f, 0.0f ));positions.push_back(Position( -1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 0.0f ));   // Create Buffers   Buffer::SharedPtr bufPositions(new Buffer(device, POSITION, positions));   Buffer::SharedPtr bufTexCoords(new Buffer(device, TEXCOORD2D, texCoords));   m_buffers.push_back(bufPositions);   m_buffers.push_back(bufTexCoords);   // Remove extension from the texture filename   RemoveExtFromFilename(textureFileName_cubeFaces, m_cubeFacesTextureName); // Load the textures   try   { textureManager.CreateTextureFromFile(m_cubeFacesTextureName, textureFileName_cubeFaces);   }   catch(BaseException & e)   { throw e;   }   // Load an effect to use   try   { effectManager.CreateChildEffect("skybox", "skybox.fx");   }   catch(BaseException & e)   { throw e;   }   // Create and store the input layout   Effect &    effect    = effectManager.GetChildEffect("skybox");   Technique & technique = effect.GetTechnique("RenderDefault");   Pass & pass = technique.GetPass(0);   std::vector<InputElementDescription> inputElementDescs;   for(std::vector<Buffer::SharedPtr>::size_type i = 0; i < m_buffers.size(); ++i)   { std::vector<InputElementDescription> elementDesc; InputElementDescription::GetInputElementDesc(elementDesc, m_buffers->GetContentType(), 0, i, false); inputElementDescs.insert(inputElementDescs.end(), elementDesc.begin(), elementDesc.end());   }   m_inputLayout = inputLayoutManager.GetInputLayout(inputElementDescs, pass);   // Store the offsets for the buffers   for(unsigned i = 0; i < m_buffers.size(); ++i)   { m_offsets.push_back(0);   }   // Store the strides for the buffers   for(unsigned i = 0; i < m_buffers.size(); ++i)   { unsigned stride = GetStride(m_buffers->GetContentType()); m_strides.push_back(stride);   }}//---------------------------------------------------------------------------SkyBox::SkyBox(ID3D10Device & device, TextureManager & textureManager, EffectManager & effectManager, InputLayoutManager & inputLayoutManager,const std::string & textureFileName_posX,const std::string & textureFileName_negX,const std::string & textureFileName_posY,const std::string & textureFileName_negY,const std::string & textureFileName_posZ,const std::string & textureFileName_negZ)   :   m_device(device),   m_effectManager(effectManager),   m_inputLayout(NULL){   BaseException exception("Not Set",  "SkyBox::SkyBox(ID3D10Device & device, TextureManager & textureManager, EffectManager & effectManager, InputLayoutManager & inputLayoutManager, const std::string & textureFileName_negX, const std::string & textureFileName_posX, const std::string & textureFileName_negY, const std::string & textureFileName_posY, const std::string & textureFileName_negZ, const std::string & textureFileName_posZ)",  "SkyBox.cpp");   // Create geometry to render   //   // Geometry will be inward facing quads that are renderable as triangle strips   std::vector<Position>   positions;   std::vector<TexCoord2D> texCoords;   // Pos Xpositions.push_back(Position(  1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position(  1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 0.0f ));   // Neg Xpositions.push_back(Position( -1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position( -1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 0.0f )); // Pos Ypositions.push_back(Position( -1.0f,  1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position(  1.0f,  1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 1.0f, 0.0f ));// Neg Ypositions.push_back(Position( -1.0f, -1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position( -1.0f, -1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position(  1.0f, -1.0f, -1.0f));  texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position(  1.0f, -1.0f,  1.0f));  texCoords.push_back(TexCoord2D( 1.0f, 0.0f ));   // Pos Zpositions.push_back(Position( -1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position(  1.0f, -1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f,  1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 0.0f ));   // Neg Zpositions.push_back(Position(  1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 1.0f ));positions.push_back(Position(  1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 0.0f, 0.0f ));positions.push_back(Position( -1.0f, -1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 1.0f ));positions.push_back(Position( -1.0f,  1.0f, -1.0f )); texCoords.push_back(TexCoord2D( 1.0f, 0.0f ));// Create Buffers   Buffer::SharedPtr bufPositions(new Buffer(device, POSITION, positions));   Buffer::SharedPtr bufTexCoords(new Buffer(device, TEXCOORD2D, texCoords));   m_buffers.push_back(bufPositions);   m_buffers.push_back(bufTexCoords);   // Remove extension from the texture filenames   RemoveExtFromFilename(textureFileName_posX, m_perSideTextureNames[0]);   RemoveExtFromFilename(textureFileName_negX, m_perSideTextureNames[1]);   RemoveExtFromFilename(textureFileName_posY, m_perSideTextureNames[2]);   RemoveExtFromFilename(textureFileName_negY, m_perSideTextureNames[3]);   RemoveExtFromFilename(textureFileName_posZ, m_perSideTextureNames[4]);   RemoveExtFromFilename(textureFileName_negZ, m_perSideTextureNames[5]); // Load the textures   try   { textureManager.CreateTextureFromFile(m_perSideTextureNames[0], textureFileName_posX); textureManager.CreateTextureFromFile(m_perSideTextureNames[1], textureFileName_negX);  textureManager.CreateTextureFromFile(m_perSideTextureNames[2], textureFileName_posY); textureManager.CreateTextureFromFile(m_perSideTextureNames[3], textureFileName_negY); textureManager.CreateTextureFromFile(m_perSideTextureNames[4], textureFileName_posZ); textureManager.CreateTextureFromFile(m_perSideTextureNames[5], textureFileName_negZ);   }   catch(BaseException & e)   { throw e;   }   // Load an effect to use   try   { effectManager.CreateChildEffect("skybox", "skybox.fx");   }   catch(BaseException & e)   { throw e;   }   // Create and store the input layout   Effect &    effect    = effectManager.GetChildEffect("skybox");   Technique & technique = effect.GetTechnique("RenderDefault");   Pass & pass = technique.GetPass(0);   std::vector<InputElementDescription> inputElementDescs;   for(std::vector<Buffer::SharedPtr>::size_type i = 0; i < m_buffers.size(); ++i)   { std::vector<InputElementDescription> elementDesc; InputElementDescription::GetInputElementDesc(elementDesc, m_buffers->GetContentType(), 0, i, false); inputElementDescs.insert(inputElementDescs.end(), elementDesc.begin(), elementDesc.end());   }   m_inputLayout = inputLayoutManager.GetInputLayout(inputElementDescs, pass);   // Store the offsets for the buffers   for(unsigned i = 0; i < m_buffers.size(); ++i)   { m_offsets.push_back(0);   }   // Store the strides for the buffers   for(unsigned i = 0; i < m_buffers.size(); ++i)   { unsigned stride = GetStride(m_buffers->GetContentType()); m_strides.push_back(stride);   }}//---------------------------------------------------------------------------SkyBox::~SkyBox(){}//---------------------------------------------------------------------------void SkyBox::Render(){   Effect &    effect    = m_effectManager.GetChildEffect("skybox");   Technique & technique = effect.GetTechnique("RenderDefault");   Pass & pass = technique.GetPass(0);   Material    material  = effect.GetMaterial();   // Get the current projection and view matrices   D3DXMATRIX origView;   D3DXMATRIX origProjection; m_effectManager.GetViewMatrix(origView);   m_effectManager.GetProjectionMatrix(origProjection);   // Create matrices for rendering the skybox   D3DXMATRIX newWorld;   D3DXMATRIX newView  = origView;   D3DXMATRIX newProjection = origProjection;   D3DXMatrixIdentity(&newWorld);   // Adjust the view matrix such that it has no translation   newView._41 = 0.0f;   newView._42 = 0.0f;   newView._43 = 0.0f;   // Adjust the perspective matrix such that the near and far clip are 2 units apart   float nearPlane = 0.01f;   float farPlane  = 2.0f;   float q    = farPlane / (farPlane - nearPlane);   newProjection._33 = q;   newProjection._43 = -q * nearPlane;    // Bind the matrices for rendering the skybox   effect.SetWorldMatrix(newWorld);   m_effectManager.SetViewMatrix(newView);   m_effectManager.SetProjectionMatrix(newProjection);   // Get the current depth stancil state   ID3D10DepthStencilState * origDepthStencilState;   UINT  stencilRef = 1; // TODO - I don't know what the heck this is! m_device.OMGetDepthStencilState(&origDepthStencilState, &stencilRef);    // Set a new depth stencil state with depth testing disabled   ID3D10DepthStencilState * newDepthStencilState = NULL;   D3D10_DEPTH_STENCIL_DESC  depthStencilDesc;   origDepthStencilState->GetDesc(&depthStencilDesc);   depthStencilDesc.DepthEnable    = true;   depthStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ZERO;   depthStencilDesc.DepthFunc = D3D10_COMPARISON_LESS_EQUAL;   if( FAILED(m_device.CreateDepthStencilState(&depthStencilDesc, &newDepthStencilState)) )   { BaseException exception; exception.m_msg = "Failed to create D3D depth stencil state"; throw exception;   }   m_device.OMSetDepthStencilState(newDepthStencilState, stencilRef);   // Bind the input layout   m_device.IASetInputLayout(m_inputLayout);   // Bind the vertex buffers   //   // Since we are using shared pointers, we unfortunatly have to copy the D3D buffer interfaces they point to   // into a seperate vector to pass to D3D when we bind them std::vector<ID3D10Buffer *> vertexBuffers;   for(std::vector<Buffer::SharedPtr>::iterator it = m_buffers.begin(); it != m_buffers.end(); ++it)   { vertexBuffers.push_back((*it)->GetD3DBuffer());   }   m_device.IASetVertexBuffers(0, static_cast<UINT>(m_buffers.size()), &vertexBuffers[0], &m_strides[0], &m_offsets[0]); // Tell the input assembler how to assemble the vertices into primitives   m_device.IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);   // If one texture is used for all faces   if( !m_cubeFacesTextureName.empty() )   { // Set the texture material.SetTextureName("textureDiffuse", m_cubeFacesTextureName); effect.SetMaterial(material); // Apply pass pass.Apply(); // Render the face (one strip per face from the vertex buffer)  There are 2 primitives per face. m_device.Draw(24, 0);   }   // Otherwise render one face at a time with seperate textures for each   else   { // Draw one quad at a time for( unsigned i = 0; i < 6; ++i ) {    // Set the texture for this primitive    material.SetTextureName("textureDiffuse", m_perSideTextureNames);    effect.SetMaterial(material);    // Apply pass    pass.Apply();    // Render the face (one strip per face from the vertex buffer)  There are 2 primitives per face.    m_device.Draw(4, i * 4); }   }   // Restore the original view and projection matrices   m_effectManager.SetViewMatrix(origView);   m_effectManager.SetProjectionMatrix(origProjection); // Restore the original depth stencil state   m_device.OMSetDepthStencilState(origDepthStencilState, stencilRef);   origDepthStencilState->Release();   newDepthStencilState->Release();}//--------------------------------------------------------------------------------------// File: skybox.fx////--------------------------------------------------------------------------------------#include "EffectPool.fxh"matrix world : World;    // Not currently used, only here to comply with application requirementsTexture2D textureDiffuse;SamplerState samplerLinear{   Filter   = MIN_MAG_MIP_LINEAR;   AddressU = Clamp;   AddressV = Clamp;};//////// CONNECTOR DATA STRUCTURES ////////////* Data from application vertex buffer */struct VS_INPUT{   float4   position  : POSITION;   float2   uv   : TEXCOORD;};/* Data passed from vertex shader to pixel shader */struct PS_INPUT{   float4 position : SV_POSITION;   float2 uv  : TEXCOORD;};//DepthStencilState NoDepthState//{//   DepthEnable = false;//};//--------------------------------------------------------------------------------------// Vertex Shader//--------------------------------------------------------------------------------------PS_INPUT VS( VS_INPUT input ){   PS_INPUT output = (PS_INPUT)0; // Transform the position   matrix viewProjection = mul(view, projection);   output.position = mul(input.position.xyz, viewProjection).xyww; // Copy the UV   output.uv = input.uv; return output;}//--------------------------------------------------------------------------------------// Pixel Shaders//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------// Simply shades an object at 100% opacity, with no lights or shadows//float4 PS( PS_INPUT input ) : SV_Target{// Sample the color   float4 finalColor = textureDiffuse.Sample(samplerLinear, input.uv);   finalColor.a = 1; return finalColor;}//--------------------------------------------------------------------------------------// Techniques//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------// Renders an object at 100% opacity, with no lights or shadows//technique10 RenderDefault{   pass P0   { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS() ) );   //    SetDepthStencilState(NoDepthState, 0);   }}
  I know, these days, we all have three 1680x1050 screens on our desks, and editors with code folding, but ...   ;  I resized them to 800x600 for ya.;  Would 256 not be enough? I still have to scroll so much.Also, your code doesn't fit on my widescreen screens, so I must scroll horizontally so much.   ;  Have you tried doing a PIX capture so you can see what's going on more easily?   ;  I've stayed up for about 20 hours and am ready to pass out, but I managed to fix most of my problems.I was outside smoking a cigarette and God put it in my head that I was using a trianglestrip. It suddenly hit me that my method of rendering the skybox with one texture made a single draw call with all 24 vertices. I had forgotten that a triangle strip is going to use the previous 2 vertices everytime. So, I changed it to draw 1 face at a time as was done in the other method.That fixes the tearing.It also hit me that a projection matrix has a field of view. I sat there with my arms out and measured my own to be about 90 degrees. Then it hit me that if I want to see an entire side of the skybox, of course the fov should be 90 degrees! 4*9=360 duh. So, I checked my projection matrix's FOV and sure enough it was not 90 degrees.I changed that and now the arrows line up correctly on the top and bottom of the screen.My only remaining problem is:The left and right arrows are now in just a bit from the edge of the screen. Shouldn't they line up perfectly with the edge of the screen?;  I got to thinking, maybe the problem with the width of the face not lining up with the edge of the screen has to do with aspect ratio.Here is a pic of the app facing dead center on the positive Z axis:Here is a pic of the app in windowed mode, where I stretched the window horizontally as much as possible.My projection matrices are correct. I adjust them with a new client width / height, when the screen is resized. You can see that by the way the ship in the center is correctly rendered.There are two things I can think of that I might adjust:1) The aspect ratio of the image used as the skybox texture. I could adjust the image to be as wide as the sceen and as tall as the screen instead of a perfect square. However, I doubt this will have any effect if the user stretches the screen to a different aspect ratio. This would also require I keep a seperate set of all textures used in my game for each possible aspect ratio. I'd probably have to make sure that in windowed mode, aspect ratio is kept as well. yuck.2) The width, height of the unit cube that is the skybox. Perhaps this unit cube should be scaled to match the width and height of the screen somehow? I suppose I could have a callback when the screen is resized and scale my cube. I am not sure how scaling will affect it though.Or perhaps I need to do both?Both of these options are a bit of work to just try and see. Anyone care to give a definitive answer before I begin another night of coding?;  couldnt you just make life easier and render a dds file onto an imported cube with the normals inverted?  you can make dds skyboxes with the directx texture tool.doing that surely leaves much less to go wrong?   ;  That is no different. I'd just be storing the cube elsewhere and have another file to load. It would still be a unit cube textured exactly the way I textured it, with the same image file. The problems would persist.I'm not talking out my butt, because I've already done that. The data still matches exactly. That's where I got the values to define my geometry with to begin with.I'd still have the previous two questions, because I'd still be using the same projection matrix and the same unit cube. I just would have loaded them differently.