![](https://static.wixstatic.com/media/11062b_d2398715eb2e43348e6907b6b3383815f000.jpg/v1/fill/w_1920,h_1080,al_c,q_90,enc_avif,quality_auto/11062b_d2398715eb2e43348e6907b6b3383815f000.jpg)
C++ DirectX11 Project, Image processing
void Game::LoadMap()
{
//get the image
int x, y, n;
unsigned char *data = stbi_load("../bin/data/prettyMap.jpg", &x, &y, &n, 0); // needs to be a nice looking map
assert(n == 3);
//promote to 32bit, DX11 textures are RedGreenBlueAlpha (8bit per channel)
//but the image was RGB 8bit which is annoying
unsigned char *data32 = new unsigned char[4 * x*y];
unsigned char* pSource = data, *pDest = data32;
for (int i = 0; i < (x*y); ++i)
{
for (int ii = 0; ii < 3; ii++)
{
*pDest = *pSource;
pDest++;
pSource++;
}
*pDest = 255;
pDest++;
}
//create a texture to match, yuck, this M$ code is nasty looking
D3D11_TEXTURE2D_DESC desc;
desc.Width = x;
desc.Height = y;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.ArraySize = 1;
ID3D11Texture2D *pTexture = NULL;
HR(gd3dDevice->CreateTexture2D(&desc, NULL, &pTexture));
//grab it to write into
D3D11_MAPPED_SUBRESOURCE mappedResource;
ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
HR(gd3dImmediateContext->Map(pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
//copy the image data across
memcpy(mappedResource.pData, data32, sizeof(unsigned char)*x*y * 4);
gd3dImmediateContext->Unmap(pTexture, 0);
//free our data, DX has it now
stbi_image_free(data);
delete[] data32;
//convert the texture into a shader resource we can use
D3D11_SHADER_RESOURCE_VIEW_DESC resViewDesc;
ZeroMemory(&resViewDesc, sizeof(resViewDesc));
resViewDesc.Format = desc.Format;
resViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
resViewDesc.Texture2D.MostDetailedMip = 0;
resViewDesc.Texture2D.MipLevels = 1;
MaterialExt *pMat = &mQuad.GetMesh().GetSubMesh(0).material;
HR(gd3dDevice->CreateShaderResourceView(pTexture, &resViewDesc, &pMat->pTextureRV));
//we should really tell the texture cache about this or it won't get deleted :)
//load the map and convert to a 2d array
data = stbi_load("../bin/data/TrackMapMain.jpg", &x, &y, &n, 0); // load the dots map
assert(n == 3);
assert(x == MAP_WIDTH && y == MAP_WIDTH);
for (int xi = 0; xi < MAP_WIDTH; ++xi)
for (int yi = 0; yi < MAP_WIDTH; ++yi)
{
MapData& d = mTrack[MAP_WIDTH - 1 - yi][xi]; //invert it so it's orientated with the world coordinate system
d.track = (data[yi*y * 3 + xi * 3] > 200 && d.obstacle == false) ? true : false; //red
d.gravel = (data[yi*y * 3 + xi * 3 + 1] > 200) ? true : false; //green
d.checkpoint = (data[yi*y * 3 + xi * 3 + 2] > 200) ? true : false; //blue
if ((data[yi*y * 3 + xi * 3] > 200) && (data[yi*y * 3 + xi * 3 + 1] > 200))
{
d.obstacle = true;
mObstacles.insert(mObstacles.end(), 1, Obstacle());
}
else d.obstacle = false;
if ((data[yi*y * 3 + xi * 3 + 1] < 200) && (data[yi*y * 3 + xi * 3 + 1] > 100) && (data[yi*y * 3 + xi * 3 + 2] < 200) && (data[yi*y * 3 + xi * 3 + 2] > 100))
{
d.pickUp = true;
mPickUps.insert(mPickUps.end(), 1, PickUp());
}
else d.pickUp = false;
}
stbi_image_free(data);
}
void Game::Load()
{
FX::SetupDirectionalLight(0, true, Vector3(-0.7f, -0.7f, 0.7f), Vector3(0.8f, 0.8f, 0.8f), Vector3(0.15f, 0.15f, 0.15f), Vector3(0.25f, 0.25f, 0.25f));
mpMenu->Load();
mpSpriteBatch = new SpriteBatch(gd3dImmediateContext);
assert(mpSpriteBatch);
mpFont = new SpriteFont(gd3dDevice, L"../bin/data/comicSansMS.spritefont");
assert(mpFont);
mpFont2 = new SpriteFont(gd3dDevice, L"../bin/data/algerian.spritefont");
assert(mpFont2);
mCube.Initialise(BuildCube(mMeshMgr));
mLoadData.loadedSoFar++;
Mesh& sb = mMeshMgr.CreateMesh("skybox");
sb.CreateFrom("data/skybox.fbx", gd3dDevice, mFX.mCache);
Setup(mSkybox, sb, 300.f, Vector3(0, 0, 0), Vector3(270, 225, 300));
mLoadData.loadedSoFar++;
for (int i = 0; i < 4; i++)
{
cameras[i].Initialise(FPScamPos(), cars[i].GetRotation(), gViews[i]);
cameras[i].LockMovementAxis(FPSCamera::UNLOCK, -4.5f, FPSCamera::UNLOCK);
}
mSphere.Initialise(BuildSphere(mMeshMgr, 16, 16));
for (int i = 0; i < mPickUps.size(); i++)
{
mPickUps.at(i).Initialise(mMeshMgr);
mLoadData.loadedSoFar++;
}
for (int i = 0; i < mObstacles.size(); i++)
{
mObstacles.at(i).Initialise(mMeshMgr, false); // set bool to true if you want the blocks to move up and down
mLoadData.loadedSoFar++;
}
int x = 0; // counter for pickups
int y = 0; // counter for obstacles
vector<CheckPoint> allCheckPoints;
for (int i = 0; i < MAP_WIDTH; i++)
{
for (int j = 0; j < MAP_WIDTH; j++) // loop over map, decide what's there and place objects accordingly
{
if (mTrack[j][i].obstacle)
{
mObstacles.at(y).mCube.GetScale() = Vector3(1, 1, 1);
mObstacles.at(y).mCube.GetPosition() = Vector3(i, 0.5f, j);
y++;
}
if (mTrack[j][i].pickUp)
{
float pickUpScale = 0.005f;
mPickUps.at(x).mCube.GetScale() = Vector3(pickUpScale, pickUpScale, pickUpScale);
mPickUps.at(x).mCube.GetPosition() = Vector3(i, pickUpScale, j); // moves it off the floor
mPickUps.at(x).SetActivity(true); // start off visible
x++;
}
if (mTrack[j][i].checkpoint)
{
allCheckPoints.push_back(CheckPoint());
allCheckPoints.at(allCheckPoints.size() - 1).x = i; // set position
allCheckPoints.at(allCheckPoints.size() - 1).y = j;
}
}
}
vector<CheckPoint> aCPList; // create a vector to store all the points from the map that make a checkpoint
checkpoints.push_back(aCPList);
checkpoints.at(0).push_back(allCheckPoints.at(0)); // insert the first checkpoint as a start point
for (int i = 0; i < allCheckPoints.size(); i++) // for every checkpoint point on the map
{
if (allCheckPoints.at(i).used == false) // if it isn't already put into a checkpoint vector
{
CheckPointsConnectedCheck(allCheckPoints.at(i), allCheckPoints); // check if point is connected to a checkpoint
allCheckPoints.at(i).used = true; // it's been collected by a checkpoint vector now so don't check it again
vector<CheckPoint> CPList;
checkpoints.push_back(CPList);
}
mMKInput.Initialise(GetMainWnd());
mGamepad.Initialise();
}
mLoadData.loadedSoFar++;
for (int i = 0; i < 4; i++) // Initialise players
{
cars[i].Initialise(mMeshMgr, i);
mLoadData.loadedSoFar++;
int CP = 4; // decides which checkpoint to spawn players at
int pPosx = checkpoints.at(CP).at((checkpoints.at(CP).size() / 6) * (i + 2)).x; // seperates the players out nicely on checkpoint
int pPosy = checkpoints.at(CP).at((checkpoints.at(CP).size() / 6) * (i + 2)).y;
cars[i].mCar.GetPosition() = Vector3(pPosx, 0.2, pPosy);
}
for (int i = 0; i < checkpoints.size(); i++) // creates a vector<bool> which tracks the checkpoints for each car
{
for (int y = 0; y < 4; y++)
{
bool pushable = false;
cars[y].GetCheckPointsPassed().push_back(pushable);
}
}
mLoadData.running = false;
}