Model class fails to initialize in DirectX 10

79 views Asked by At

My project uses DirectX 10 and some of its boilerplate to render a scene, however, it crashes with an error message "Could not initialize the model object." As far as I understand, making it up to this point means that, at the very least, the model has been successfully created, so the error must be in one of the files below, which is fortunate as the most difficult tasks are handled by the FallBodyClass.cpp that hosts OpenCL API interactions. If needed, I can try attaching parts of it in a later edit.

During debug, my IDE shows that all components of m_Model (m_vertexBuffer, m_indexBuffer etc) are shown as with _vfptr . I do not know what to make of it, but it does seem to confirm that modelclass.cpp is the point of failure.

graphicsclass.cpp

GraphicsClass::GraphicsClass()
{
    m_Direct3D = 0;
    m_Model = 0;
    m_ColorShader = 0;

    m_bodies = BODIES;
}
GraphicsClass::GraphicsClass(const GraphicsClass& other)
{}
GraphicsClass::~GraphicsClass()
{}
bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
{
    bool result;
    // Create the Direct3D object.
    m_Direct3D = new D3DClass;
    if (!m_Direct3D)
    {
        return false;
    }
    // Initialize the Direct3D object.
    result = m_Direct3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);
    if (!result)
    {
        MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK);
        return false;
    }
    // Create the model object.
    m_Model = new ModelClass(m_bodies);
    if (!m_Model)
    {
        return false;
    }

    // Initialize the model object.
    result = m_Model->Initialize(m_Direct3D->GetDevice());
    if (!result)
    {
        MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK);
        return false;
    }

modelclass.cpp

ModelClass::ModelClass(int bodies)
{
    m_vertexBuffer = 0;
    m_indexBuffer = 0;

    m_positions = 0;
    m_velocities = 0;
    m_bodySystem = 0;

    m_bodies = bodies;
}
ModelClass::ModelClass(const ModelClass& other)
{}
ModelClass::~ModelClass()
{}
bool ModelClass::Initialize(ID3D10Device* device)
{
    bool result;
  TwoLines twoLinesConstants = CalculateLinesConstants(M_PI_4);
    m_positions = new float[COORD_DIM * m_bodies];
    m_velocities = new float[VEL_DIM * m_bodies];
    m_bodySystem = new class FallBodyClass(m_bodies, &m_positions, &m_velocities, twoLinesConstants, result);
    if (!result) {
        return false;
    }
    // Initialize the vertex and index buffer that hold the geometry for the triangle.
    result = InitializeBuffers(device, twoLinesConstants);
    if(!result)
    {
        return false;
    }
    return true;
}

FallBodyclass.cpp

    FallBodyClass::FallBodyClass(int bodies, float ** positionsCPU, float ** velocitiesCPU, TwoLines twoLines, bool & success)
        :bodies(bodies)
    {
        cl_int ret;

        // getting the first available platform
        cl_platform_id clPlatformID[2];
        cl_platform_id GPUplatform;
        cl_uint num_platforms;
        //char str[1024];

        ret = clGetPlatformIDs(2, clPlatformID, &num_platforms);

        GPUplatform = clPlatformID[0]; //choose GPU platform
        //error |= clGetPlatformInfo(GPUplatform, CL_PLATFORM_NAME, 0, NULL, NULL);
        //clGetPlatformInfo(GPUplatform, CL_PLATFORM_VENDOR, sizeof(str), str, NULL);

        // getting the first GPU device
        ret |= clGetDeviceIDs(GPUplatform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);

        if (ret != CL_SUCCESS)
        {
            success = false;
            return;
        }

        //clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(str), str, NULL);
        // creating the context
        context = clCreateContext(0, 1, &device, NULL, NULL, &ret);
        if (ret != CL_SUCCESS)
        {
            success = false;
            return;
        }

        cl_queue_properties props[] = {
            CL_QUEUE_PROFILING_ENABLE
        };

        // creating the command queue 
        queue = clCreateCommandQueueWithProperties(context, device, props, &ret);

        if (ret != CL_SUCCESS)
        {
            success = false;
            return;
        }

        // setting the local variables
        // (at the same time one of them supposed to be 0 and another to be 1)
        read = 0;
        write = 1;

        // reading the kernel
        FILE * f = NULL;
        char fileName[18] = "kernel.cl";

        f = fopen(fileName, "rb");
        if(f == NULL) 
        {   
            success = false;
            return;
        }
        // getting the length of the source code for the kernel
        fseek(f, 0, SEEK_END); 
        size_t codeLength = ftell(f);
        rewind(f); 

        char * code = (char *)malloc(codeLength + 1); 
        if (fread(code, codeLength, 1, f) != 1)
        {
            fclose(f);
            free(code);
            success = false;
            return;
        }

        // closing the file and 0-terminating the source code
        fclose(f);
        code[codeLength] = '\0';

        // creating the program
        program = clCreateProgramWithSource(context, 1, (const char **)&code, &codeLength, &ret);

        if (ret != CL_SUCCESS)
        {

            success = false;
            return;
        }


        // clearing the memory    
        free(code);

        // building the program
        ret |= clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

        // creating the kernel
        kernel = clCreateKernel(program, "impactManager", &ret);

        // setting the local size of the group the largest possible in order to load all computational units
        int numGroups;
        ret |= clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(numGroups), &numGroups, NULL);
        localSize = bodies / numGroups;

        // allocating pinned buffers for velocities and positions, and stuck
        positionsCPUBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, COORD_DIM * bodies * sizeof(float) , NULL, NULL);
        velocitiesCPUBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, VEL_DIM * bodies * sizeof(float) , NULL, NULL);
        linesCPUBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, 8 * sizeof(float), NULL, NULL);

        //  get pointers to arrays to operate with the buffers (array map buffers here (to program) as float-arrays)
        *positionsCPU = (float *)clEnqueueMapBuffer(queue, positionsCPUBuffer, CL_TRUE, CL_MAP_WRITE, 0, COORD_DIM * bodies * sizeof(float), 0, NULL, NULL, NULL);
        *velocitiesCPU = (float *)clEnqueueMapBuffer(queue, velocitiesCPUBuffer, CL_TRUE, CL_MAP_WRITE, 0, VEL_DIM * bodies * sizeof(float), 0, NULL, NULL, NULL);
        float * linesCPU = (float *)clEnqueueMapBuffer(queue, linesCPUBuffer, CL_TRUE, CL_MAP_WRITE, 0, 8 * sizeof(float), 0, NULL, NULL, NULL);

        // initialization of the bodies' positions and velocities, and stuck
        initBodies(*positionsCPU, *velocitiesCPU);
        initLines(twoLines, linesCPU);

        // unmapping the pointers to arrays (invalidates array pointers)
        clEnqueueUnmapMemObject(queue, positionsCPUBuffer, *positionsCPU, 0, NULL, NULL);
        clEnqueueUnmapMemObject(queue, velocitiesCPUBuffer, *velocitiesCPU, 0, NULL, NULL);
        clEnqueueUnmapMemObject(queue, linesCPUBuffer, linesCPU, 0, NULL, NULL);

        // allocate two arrays on GPU for positions and velocities
        for (int i = 0; i < 2; ++i) {
            positionsGPU[i] = clCreateBuffer(context, CL_MEM_READ_WRITE, COORD_DIM * bodies * sizeof(float), NULL, NULL);
            ret |= clEnqueueWriteBuffer(queue, positionsGPU[i], CL_TRUE, 0, COORD_DIM * bodies * sizeof(float), *positionsCPU, 0, NULL, NULL);
            velocitiesGPU[i] = clCreateBuffer(context, CL_MEM_READ_WRITE, VEL_DIM * bodies * sizeof(float), NULL, NULL);
            ret |= clEnqueueWriteBuffer(queue, velocitiesGPU[i], CL_TRUE, 0, VEL_DIM * bodies * sizeof(float), *velocitiesCPU, 0, NULL, NULL);
        }

        linesGPU = clCreateBuffer(context, CL_MEM_READ_WRITE, 8 * sizeof(float), NULL, NULL);
        ret |= clEnqueueWriteBuffer(queue, linesGPU, CL_TRUE, 0, 8 * sizeof(float), linesCPU, 0, NULL, NULL);

        if (ret != CL_SUCCESS)
        {
            success = false;
            return;
        }
    }


void FallBodyClass::initLines(IN TwoLines l, OUT float *linesCPU)
{
  linesCPU[0] = l.a1;
  linesCPU[1] = l.b1;
  linesCPU[2] = l.R1.x;
  linesCPU[3] = l.R1.y;

  linesCPU[4] = l.a2;
  linesCPU[5] = l.b2;
  linesCPU[6] = l.R2.x;
  linesCPU[7] = l.R2.y;
}


// initialization of the bodies' positions and velocities
void FallBodyClass::initBodies(float * positionsCPU, float * velocitiesCPU)
{
    float scale = 0.20f;

    // initialization of the memory
    memset(positionsCPU, 0, COORD_DIM * bodies * sizeof(float));
    memset(velocitiesCPU, 0, VEL_DIM * bodies * sizeof(float));
    // for the randomization
    srand((unsigned int)time(NULL));

    for (int i = 0; i < bodies; i++)
    {
        positionsCPU[COORD_DIM * i] = 1.8*((rand() / (float)RAND_MAX) - 0.5);   //x axis
        positionsCPU[COORD_DIM * i + 1] = 0.9;  //y axis
        positionsCPU[COORD_DIM * i + 2] = 0.0f; //z axis
        positionsCPU[COORD_DIM * i + 3] = 0.0f; // stuck variable 


        // velocities are zeros
        velocitiesCPU[VEL_DIM* i] = 0.0;
        velocitiesCPU[VEL_DIM* i + 1] = -2 * (rand() / (float)RAND_MAX);
        velocitiesCPU[VEL_DIM* i + 2] = 0.0;

    }
}

// updating the bodies' positions and velocities. Stuck is updated inside too 
void FallBodyClass::update(float dt, float * positionsCPU, float * velocitiesCPU, bool & success)
{
    cl_int error = CL_SUCCESS;
    size_t global_work_size;
    size_t local_work_size;
    success = true;

    if (localSize > bodies)
        localSize = bodies;

    local_work_size = localSize;
    global_work_size = bodies;

    // passing the arguments
    // we write the new positions and velocities and read the previous ones
    error |= clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&positionsGPU[write]);
    error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&velocitiesGPU[write]);
    error |= clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&positionsGPU[read]);
    error |= clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&velocitiesGPU[read]);
    error |= clSetKernelArg(kernel, 4, sizeof(cl_float), (void *)&dt);
    error |= clSetKernelArg(kernel, 5, sizeof(cl_mem), (void *)&linesGPU);

    // just swap read and write in order not to copy the arrays
    int temp;
    temp = write;
    write = read;
    read = temp;

    // executing the kernel
    error |= clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_work_size, &local_work_size, 0, NULL, NULL);
    // synchronization 
    clFinish(queue);

    // asynchronously reading the updated values 
    error |= clEnqueueReadBuffer(queue, positionsGPU[read], CL_FALSE, 0, COORD_DIM * bodies * sizeof(float), positionsCPU, 0, NULL, NULL);
    if (error != CL_SUCCESS)
    {
        success = false;
    }

    error |= clEnqueueReadBuffer(queue, velocitiesGPU[read], CL_FALSE, 0, VEL_DIM * bodies * sizeof(float), velocitiesCPU, 0, NULL, NULL);
    if (error != CL_SUCCESS)
    {
        success = false;
    }

    ///////////
    bool toReboot = positionsCPU[3]; //fourth index of the [0] first element
  //bool toReboot = false;
    ////////////
    if (toReboot) {
        positionsCPU = (float *)clEnqueueMapBuffer(queue, positionsCPUBuffer, CL_TRUE, CL_MAP_WRITE, 0, COORD_DIM * bodies * sizeof(float), 0, NULL, NULL, NULL);
        velocitiesCPU = (float *)clEnqueueMapBuffer(queue, velocitiesCPUBuffer, CL_TRUE, CL_MAP_WRITE, 0, VEL_DIM * bodies * sizeof(float), 0, NULL, NULL, NULL);

        initBodies(positionsCPU, velocitiesCPU);

        // unmapping the pointers
        clEnqueueUnmapMemObject(queue, positionsCPUBuffer, positionsCPU, 0, NULL, NULL);
        clEnqueueUnmapMemObject(queue, velocitiesCPUBuffer, velocitiesCPU, 0, NULL, NULL);
        //update values on GPU side
        error |= clEnqueueWriteBuffer(queue, positionsGPU[read], CL_TRUE, 0, COORD_DIM * bodies * sizeof(float), positionsCPU, 0, NULL, NULL);
        error |= clEnqueueWriteBuffer(queue, velocitiesGPU[read], CL_TRUE, 0, VEL_DIM * bodies * sizeof(float), velocitiesCPU, 0, NULL, NULL);
    }

    return;
}


FallBodyClass::~FallBodyClass(void)
{
    // synchronization (if something has to be done) 
    clFinish(queue);
    // releasing all objects
    clReleaseMemObject(linesGPU);
    clReleaseMemObject(linesCPUBuffer);
    clReleaseMemObject(velocitiesGPU[0]);
    clReleaseMemObject(velocitiesGPU[1]);
    clReleaseMemObject(positionsGPU[0]);
    clReleaseMemObject(positionsGPU[1]);
    clReleaseMemObject(positionsCPUBuffer);
    clReleaseMemObject(velocitiesCPUBuffer);
    clReleaseKernel(kernel);
    clReleaseProgram(program);
    clReleaseCommandQueue(queue);
    clReleaseContext(context);

}
0

There are 0 answers