void SDLWindow::handleWindowEvent() { switch (m_sdlEvent.window.event) { case SDL_WINDOWEVENT_MOVED: onMove(m_sdlEvent.window.data1, m_sdlEvent.window.data2); break; case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_SIZE_CHANGED: onResize(m_sdlEvent.window.data1, m_sdlEvent.window.data2); break; case SDL_WINDOWEVENT_MINIMIZED: onMinimize(); break; case SDL_WINDOWEVENT_MAXIMIZED: onMaximize(); break; case SDL_WINDOWEVENT_RESTORED: onRestore(); break; case SDL_WINDOWEVENT_SHOWN: onDisplay(); break; default: break; } }
static void onDisplay(ThreadData* data, bool running) { uint32_t idx = data->idx; int32_t begin = data->begin; int32_t end = data->end; auto world = data->world; auto cam = data->cam; g_eventWorker[idx].Wait(); onDisplay(world, cam, idx, begin, end, running); g_eventWorker[idx].Reset(); g_eventMain[idx].Set(); }
void display(hitable* world, camera& cam) { CALL_GL_API(::glClearColor(0.0f, 0.5f, 1.0f, 1.0f)); CALL_GL_API(::glClearDepthf(1.0f)); CALL_GL_API(::glClearStencil(0)); CALL_GL_API(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); CALL_GL_API(::glUseProgram(g_program)); GLfloat invScreen[4] = { 1.0f / WIDTH, 1.0f / HEIGHT, 0.0f, 0.0f }; auto hInvScreen = GetHandle(g_program, "invScreen"); CALL_GL_API(::glUniform4fv(hInvScreen, 1, invScreen)); CALL_GL_API(::glActiveTexture(GL_TEXTURE0)); CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, g_tex)); auto hImage = GetHandle(g_program, "image"); CALL_GL_API(glUniform1i(hImage, 0)); float lum = 0.0f; float maxlum = 0.0f; timer time; time.begin(); #ifdef ENABLE_MULTI_THREAD int step = ny / thread_num; int begin = 0; for (int i = 0; i < thread_num; i++) { g_threadData[i].idx = i; g_threadData[i].begin = begin; begin += step; g_threadData[i].end = begin + step; g_threadData[i].end = (g_threadData[i].end > HEIGHT ? HEIGHT : g_threadData[i].end); g_threadData[i].world = world; g_threadData[i].cam = &cam; g_eventWorker[i].Set(); g_threads[i].Start([&](void* userData, bool running) { ThreadData* data = (ThreadData*)userData; onDisplay(data, running); }, &g_threadData[i]); } for (int i = 0; i < thread_num; i++) { g_eventMain[i].Wait(); g_eventMain[i].Reset(); } for (int i = 0; i < thread_num; i++) { lum += g_sumY[i]; maxlum = math::CMath::Max(g_maxLum[i], maxlum); } lum /= thread_num; #else onDisplay(world, &cam, 0, 0, ny, true); lum = g_sumY[0]; maxlum = g_maxLum[0]; #endif auto elapsed = time.end(); printf("Elapsed[%f]\n", elapsed); static uint8_t s_color[HEIGHT][WIDTH][4]; static float fMiddleGrey = 0.18f; static const vec3 RGB2Y(+0.29900f, +0.58700f, +0.11400f); static const vec3 RGB2Cb(-0.16874f, -0.33126f, +0.50000f); static const vec3 RGB2Cr(+0.50000f, -0.41869f, -0.08131f); static const vec3 YCbCr2R(+1.00000f, +0.00000f, +1.40200f); static const vec3 YCbCr2G(+1.00000f, -0.34414f, -0.71414f); static const vec3 YCbCr2B(+1.00000f, +1.77200f, +0.00000f); // NOTE // HDR // http://t-pot.com/program/123_ToneMapping/index.html float coeff = 0.18f / exp(lum); float l_max = coeff * maxlum; for (int j = 0; j < ny; j++) { for (int i = 0; i < nx; i++) { #if 1 vec3 col(g_color[j][i][0], g_color[j][i][1], g_color[j][i][2]); float y = dot(RGB2Y, col); float cb = dot(RGB2Cb, col); float cr = dot(RGB2Cr, col); y = coeff * y; y = y * (1.0f + y / (l_max * l_max)) / (1.0f + y); vec3 ycbcr(y, cb, cr); float r = dot(YCbCr2R, ycbcr); float g = dot(YCbCr2G, ycbcr); float b = dot(YCbCr2B, ycbcr); int ir = int(255.9f * r); int ig = int(255.9f * g); int ib = int(255.9f * b); s_color[j][i][0] = math::CMath::Clamp(ir, 0, 255); s_color[j][i][1] = math::CMath::Clamp(ig, 0, 255); s_color[j][i][2] = math::CMath::Clamp(ib, 0, 255); #else auto r = 2 * int(255.9f * g_color[j][i][0] * div[0]); auto g = 2 * int(255.9f * g_color[j][i][1] * div[1]); auto b = 2 * int(255.9f * g_color[j][i][2] * div[2]); s_color[j][i][0] = math::CMath::Clamp(r, 0, 255); s_color[j][i][1] = math::CMath::Clamp(g, 0, 255); s_color[j][i][2] = math::CMath::Clamp(b, 0, 255); #endif } } CALL_GL_API(::glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, s_color)); CALL_GL_API(::glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); }