Пример #1
0
bool               P3DGLWindowContext::Create
                                      (unsigned int        Width,
                                       unsigned int        Height)
 {
  bool                  Result;
  PIXELFORMATDESCRIPTOR PixelFormatDesc;
  int                   PixelFormat;
  HDC                   DeviceContext;

  DeviceContext = NULL;

  Result = GLWindowClassRegister();

  if (Result)
   {
    Result = GLWindowCreate(&WindowHandle,Width,Height);
   }

  if (Result)
   {
    DeviceContext = GetDC(WindowHandle);

    if (DeviceContext == NULL)
     {
      Result = false;
     }
   }

  if (Result)
   {
    memset(&PixelFormatDesc,0,sizeof(PixelFormatDesc));

    PixelFormatDesc.nSize      = sizeof(PixelFormatDesc);
    PixelFormatDesc.nVersion   = 1;
    PixelFormatDesc.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
    PixelFormatDesc.cColorBits = 24;

    PixelFormat = ChoosePixelFormat(DeviceContext,&PixelFormatDesc);

    if (PixelFormat == 0)
     {
      Result = false;
     }
   }

  if (Result)
   {
    if (!SetPixelFormat(DeviceContext,PixelFormat,&PixelFormatDesc))
     {
      Result = false;
     }
   }

  if (Result)
   {
    GLContext = wglCreateContext(DeviceContext);

    if (GLContext == NULL)
     {
      Result = false;
     }
   }

  if (wglMakeCurrent(DeviceContext,GLContext))
   {
    Result = P3DGLExtInit();
   }
  else
   {
    Result = false;
   }

  if (DeviceContext != NULL)
   {
    ReleaseDC(WindowHandle,DeviceContext);
   }

  return(Result);
 }
Пример #2
0
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int)
{
	// константы

	// максимальное число сфер - для выделения буффера памяти
	long MAX_NUM_SPHERES = 100000000;
	// реальное число - определяется при считывании из файла или используется в рандомной генерации.
	long REAL_NUM_SPHERES = 10000000;
	// количество миров сфер, когда мы убираем сферы лежащие в других сферах - нужно разделять все сферы по разным мирам - там добавления новых сфер происходит быстрее.
	int SPHERE_WORLD_NUMBER = 128;
	// количество сфер которое мы обрабатываем полностью, то есть убираем все сферы содержащиеся в других сферах. Так мы бъем все сферы на такие группы и обрабатываем полностью.
	// после этого мы просто склеиваем все такие группы. Это сделано для того что, обрабатывать все 100M долго по времени (>1h), из за этого нам придется отрисовывать на 30% 
	// cфер больше.
	long SPHERES_PROCESSING_STEP = 10000000;

	// имена файлов
	std::string inputFileName = "input2.txt";
    std::string outputTxtFileName = "balabok2.txt";
    std::string outputBmpFileName = "balabok2.bmp";
    std::string fullOutputTxtFileName = "tmp_balabok/spheres_fullOutput.txt";

	CreateDirectory (L"tmp_balabok", NULL);
	LoggerCreate("tmp_balabok/spheres.log");
	// установим зерно генератора случайных чисел
	srand((unsigned int)time(NULL));

	/// create window, start main loop, etc.
	int windowWidht = 1024;
	int windowHeight = 1024;

	if (!GLWindowCreate(L"Spheres", windowWidht, windowHeight))
		return 1;
	/// 
	SphereKoords *allSpheres = new SphereKoords[MAX_NUM_SPHERES];
	/// считывание сфер из файла
	REAL_NUM_SPHERES = readSpheresDataFromFile(inputFileName, allSpheres, MAX_NUM_SPHERES);
	//generateRandomSpheres(allSpheres, REAL_NUM_SPHERES);
	
	SphereWorld * sphereWorlds = new SphereWorld[SPHERE_WORLD_NUMBER];
	SphereWorld finalWorld;
	
	LOG_DEBUG ("Please, be patient. There is a quite long data preprocessing before rendering.\n");
	LOG_DEBUG ("It can take up to 20 minutes for 100M spheres.\n");
	LOG_DEBUG ("Take into account, that time for preprocessing wasn't limited.\n");
	LOG_DEBUG ("By the way, you can see the progress in this file\n");
	auto beginTime = GetTickCount();
	/// вычисление сфер внутри других сфер в несколько потоков по блокам (мирам)
	for (int spheresInitialNumber = 0; spheresInitialNumber < REAL_NUM_SPHERES; spheresInitialNumber += SPHERES_PROCESSING_STEP) {
		long spheresToProcess = spheresInitialNumber + SPHERES_PROCESSING_STEP >= REAL_NUM_SPHERES ? REAL_NUM_SPHERES - spheresInitialNumber : SPHERES_PROCESSING_STEP;
		LOG_DEBUG ("processing spheres from %i to %i, time: %i\n", spheresInitialNumber, spheresInitialNumber + spheresToProcess , GetTickCount() - beginTime);	
		int worldsPerThread = SPHERE_WORLD_NUMBER/THREADS_COUNT;
		SphereWorldWorkerData workersData[THREADS_COUNT];
		HANDLE hHandles[THREADS_COUNT];
		for (int threadNumber = 0; threadNumber < THREADS_COUNT; ++threadNumber) {
			long spheresPerThread = spheresToProcess/THREADS_COUNT;
			workersData[threadNumber] = SphereWorldWorkerData(worldsPerThread, 
				sphereWorlds + threadNumber * worldsPerThread, 
				threadNumber == THREADS_COUNT - 1 ? spheresToProcess - spheresPerThread * (THREADS_COUNT - 1) : spheresPerThread,
				allSpheres + spheresInitialNumber + spheresPerThread * threadNumber);
			DWORD ThreadId;
			hHandles[threadNumber] = CreateThread(NULL, 0, SphereWorldWorker, workersData + threadNumber, 0, &ThreadId);
		}

		for (int i = 0; i < THREADS_COUNT; i++) {
			WaitForSingleObject(hHandles[i],INFINITE);
		}
		/// склейка миров из разных потоков
		for (int degree = (int)(log((double)worldsPerThread) / log(2.0)); degree < log((double)SPHERE_WORLD_NUMBER) / log(2.0); ++degree) {
			int step = (int) pow(2.0f, (int)degree);
			for (int worldNumber = 0; worldNumber < SPHERE_WORLD_NUMBER; worldNumber += step * 2) {
				sphereWorlds[worldNumber].AddSphereWorldInSeveralThreads(sphereWorlds[worldNumber + step], THREADS_COUNT);
			}
		}
		/// простое (без вычислений) добавление сфер из разных миров к финальному миру - сделано для увеличение скорости предобработки.
		finalWorld.SimpleAddSphereWorld(sphereWorlds[0]);
		clearWorlds(sphereWorlds, SPHERE_WORLD_NUMBER);
	}

	LOG_DEBUG("sphere amount after removing the spheres located insides others: %i, time %i\n", finalWorld.GetCurrentSize(), GetTickCount() - beginTime);
	LOG_DEBUG("started checking how spheres cover cube (0,0,0 - 1,1,1)\n");
	/// проверка насколько сферы покрывают все стороны каждой ячейки
	finalWorld.GenerateCover(coverBuilder);
	LOG_DEBUG("covering finished, time %i\n", GetTickCount() - beginTime);
	LOG_DEBUG("creating the main window, etc, and started rendering\n");

	/// generate matrix in cells;
	REDUCED_NUM_SPHERES = finalWorld.GetCurrentSize();
	spheres = new mat4[REDUCED_NUM_SPHERES];
	finalWorld.GenerateMatrixInCells(matrixInCells, spheres);

	/// вектор со временами отрисовки фремов
	std::vector<double> msecsPerFrameList;

	int nSize = windowWidht * windowHeight * 3;
	GLubyte *pixels = new GLubyte [nSize];
	/// старт петли сообщений
	int result = GLWindowMainLoop(msecsPerFrameList, pixels);

	/// сохранение всех данных в файлы
	if (pixels) {
		SaveBMP(pixels, windowWidht, windowHeight, nSize, outputBmpFileName.c_str());	
	}

	double performance = 0;
	double medianeMsecsPerFrame = 0;

	std::ofstream fullResultStream(fullOutputTxtFileName);
	std::ofstream resultStream(outputTxtFileName);

	fullResultStream << "msecs per frame: ";
	for (auto msecsValue = msecsPerFrameList.begin(); msecsValue != msecsPerFrameList.end(); ++msecsValue) {
		medianeMsecsPerFrame += *msecsValue;
		fullResultStream << *msecsValue << " ";
	}
	medianeMsecsPerFrame /= 10.0f;
	fullResultStream << std::endl << "average msecs per frame: " << medianeMsecsPerFrame ;
	performance = REAL_NUM_SPHERES / (1000 * medianeMsecsPerFrame);
	fullResultStream << std::endl << "Mspheres per second: " << performance;
	resultStream << performance << std::endl;

	GLWindowDestroy();
	LoggerDestroy();
	/// TODO: kill all windows handlers and free all the memory.
	return result;
}