Класс модели не может быть инициализирован в DirectX 10 - PullRequest
0 голосов
/ 28 февраля 2019

Мой проект использует DirectX 10 и некоторые его шаблоны для рендеринга сцены, однако он вылетает с сообщением об ошибке «Не удалось инициализировать объект модели».Насколько я понимаю, доведение до этого момента означает, что, по крайней мере, модель была успешно создана, поэтому ошибка должна быть в одном из файлов ниже, что является удачей, поскольку самые сложные задачи выполняютсяFallBodyClass.cpp, в котором размещаются взаимодействия OpenCL API.При необходимости я могу попробовать прикрепить его части в более поздней редакции.

Во время отладки моя IDE показывает, что все компоненты m_Model (m_vertexBuffer, m_indexBuffer и т. Д.) Отображаются так же, как и _vfptr.Я не знаю, что с этим делать, но, похоже, он подтверждает, что modelclass.cpp является точкой отказа.

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

}
...