top of page

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;
}

  • Facebook Social Icon
  • LinkedIn Social Icon
  • YouTube Social  Icon

© 2018 by Daniel Lynham. Proudly created with Wix.com

bottom of page