void window_default(bool center_size) { unsigned int xm = room_width, ym = room_height; if (view_enabled) { int tx = 0, ty = 0; for (int i = 0; i < 8; i++) if (view_visible[i]) { if (view_xport[i]+view_wport[i] > tx) tx = (int)(view_xport[i]+view_wport[i]); if (view_yport[i]+view_hport[i] > ty) ty = (int)(view_yport[i]+view_hport[i]); } if (tx and ty) xm = tx, ym = ty; } else { // By default if the room is too big instead of creating a gigantic ass window // make it not bigger than the screen to full screen it, this is what 8.1 and Studio // do, if the user wants to manually override this they can using // views/screen_set_viewport or window_set_size/window_set_region_size // We won't limit those functions like GM, just the default. Screen *screen = DefaultScreenOfDisplay(disp); if (xm > screen->width) xm = screen->width; if (ym > screen->height) ym = screen->height; } bool center = true; if (center_size) { center = (xm != window_get_width() || ym != window_get_height()); } window_set_size(xm, ym); if (center) { window_center(); } }
void EnableDrawing (HGLRC *hRC) { WindowResizedCallback = &WindowResized; d3dmgr = new ContextManager(); HRESULT hr; D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information d3dobj = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface D3DFORMAT format = D3DFMT_A8R8G8B8; //For simplicity we'll hard-code this for now. ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use d3dpp.Windowed = TRUE; // program windowed, not fullscreen int ww = window_get_width(), wh = window_get_height(); d3dpp.BackBufferWidth = ww <= 0 ? 1 : ww; d3dpp.BackBufferHeight = wh <= 0 ? 1 : wh; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; // 0 Levels of multi-sampling d3dpp.MultiSampleQuality = 0; //No multi-sampling d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Throw away previous frames, we don't need them d3dpp.hDeviceWindow = hWnd; // This is our main (and only) window d3dpp.Flags = NULL; // No flags to set d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; //Default Refresh Rate d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //Present the frame immediately d3dpp.BackBufferCount = 1; //We only need a single back buffer d3dpp.BackBufferFormat = format; //Display format d3dpp.EnableAutoDepthStencil = TRUE; // Automatic depth stencil buffer d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //32-bit zbuffer 24bits for depth 8 for stencil buffer // create a device class using this information and information from the d3dpp stuct DWORD behaviors = D3DCREATE_MIXED_VERTEXPROCESSING; if (forceSoftwareVertexProcessing) { behaviors = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } hr = d3dobj->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, behaviors, &d3dpp, &d3dmgr->device); if (FAILED(hr)) { MessageBox(hWnd, "Failed to create Direct3D 9.0 Device", DXGetErrorDescription9(hr), //DXGetErrorString9(hr) MB_ICONERROR | MB_OK); return; // should probably force the game closed } d3dmgr->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); enigma_user::display_aa = 0; for (int i = 16; i > 1; i--) { if (SUCCEEDED(d3dobj->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, format, TRUE, (D3DMULTISAMPLE_TYPE)((int)D3DMULTISAMPLE_NONE + i), NULL))) { enigma_user::display_aa += i; } } }
/* ...buffer allocation from frontal camera (object detection engine) */ static int objdet_input_alloc(void *data, GstBuffer *buffer) { app_data_t *app = data; vsink_meta_t *vmeta = gst_buffer_get_vsink_meta(buffer); int w = vmeta->width, h = vmeta->height; objdet_meta_t *ometa; if (app->f_width) { /* ...verify buffer dimensions are valid */ CHK_ERR(w == app->f_width && h == app->f_height, -EINVAL); } else { int W = window_get_width(app->window); int H = window_get_height(app->window); /* ...check dimensions are valid */ CHK_ERR(w && h, -EINVAL); /* ...set buffer dimensions */ app->f_width = w, app->f_height = h; /* ...initialize object detection engine */ CHK_ERR(app->od = objdet_engine_init(&objdet_callback, app, w, h, __pixfmt_yuv_bpp(vmeta->format), app->od_cfg), -errno); /* ...create a viewport for data visualization */ texture_scale_to_window(&app->view, app->window, w, h, &app->matrix); //texture_set_view_scale(&app->view, 0, 0, W, H, W, H, w, h); /* ...create transformation matrix */ if (0) { cairo_matrix_t *m = &app->matrix; m->xx = (double) W / w, m->xy = 0, m->x0 = 0; m->yx = 0, m->yy = (double) H / h, m->y0 = 0; } } /* ...allocate texture to wrap the buffer */ CHK_ERR(vmeta->priv = texture_create(w, h, vmeta->plane, vmeta->format), -errno); /* ...add custom buffer metadata */ CHK_ERR(ometa = gst_buffer_add_objdet_meta(buffer), -(errno = ENOMEM)); CHK_ERR(ometa->buf = texture_map(vmeta->priv, CL_MEM_READ_ONLY), -errno); GST_META_FLAG_SET(ometa, GST_META_FLAG_POOLED); /* ...add custom destructor to the buffer */ gst_mini_object_weak_ref(GST_MINI_OBJECT(buffer), __destroy_od_texture, app); TRACE(INFO, _b("front-camera input buffer %p allocated (%p)"), buffer, ometa->buf); return 0; }
int framebuffer_alloc(framebuffer** target, unsigned int width, unsigned int height) { if (!target) { debug_critical("[framebuffer_alloc] target cannot be NULL"); return 0; } if (*target) { debug_warning("[framebuffer_alloc] target points to non NULL handle, possible memory leak"); } if (!width && !height) { width = window_get_width(global_get(global_get_singleton(), GLOBAL_WINDOW)); height = window_get_height(global_get(global_get_singleton(), GLOBAL_WINDOW)); } framebuffer* output = h_malloc(sizeof(framebuffer)); glGenFramebuffers(1, &output->fb); glBindFramebuffer(GL_FRAMEBUFFER, output->fb); glGenTextures(1, &output->texture); glBindTexture(GL_TEXTURE_2D, output->texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glGenRenderbuffers(1, &output->renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, output->renderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, output->renderbuffer); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, output->texture, 0); GLenum buffers[] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, buffers); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { debug_critical("[framebuffer_alloc] failed to create framebuffer"); return 0; } *target = output; return 1; }
void WindowResized() { if (d3dmgr == NULL) { return; } IDirect3DSwapChain9 *sc; d3dmgr->GetSwapChain(0, &sc); D3DPRESENT_PARAMETERS d3dpp; sc->GetPresentParameters(&d3dpp); int ww = window_get_width(), wh = window_get_height(); d3dpp.BackBufferWidth = ww <= 0 ? 1 : ww; d3dpp.BackBufferHeight = wh <= 0 ? 1 : wh; sc->Release(); OnDeviceLost(); d3dmgr->Reset(&d3dpp); OnDeviceReset(); // clear the window color, viewport does not need set because backbuffer was just recreated enigma_user::draw_clear(enigma_user::window_get_color()); }
int screen_save(string filename) { //Assumes native integers are little endian unsigned int w=window_get_width(),h=window_get_height(),sz=w*h; string ext = enigma::image_get_format(filename); unsigned char *rgbdata = new unsigned char[sz*4]; GLint prevFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prevFbo); glPixelStorei(GL_PACK_ALIGNMENT, 1); glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); glReadPixels(0,0,w,h, GL_RGBA, GL_UNSIGNED_BYTE, rgbdata); glBindFramebuffer(GL_FRAMEBUFFER_EXT, prevFbo); int ret = image_save(filename, rgbdata, w, h, w, h, false); delete[] rgbdata; return ret; }
//NOTE: GM8.1 allowed the mouse to go outside the window, for basically all mouse functions and constants, Studio however //now wraps the mouse not allowing it to go out of bounds, so it will never report a negative mouse position for constants or functions. //On top of this, it not only appears that they have wrapped it, but it appears that they in fact stop updating the mouse altogether in Studio //because moving the mouse outside the window will sometimes freeze at a positive number, so it appears to be a bug in their window manager. //ENIGMA's behaviour is a modified version of GM8.1, it uses the current view to obtain these positions so that it will work correctly //for overlapped views while being backwards compatible. int window_views_mouse_get_x() { gs_scalar sx; sx = (window_get_width() - window_get_region_width_scaled()) / 2; int x = (window_mouse_get_x() - sx) * ((gs_scalar)window_get_region_width() / (gs_scalar)window_get_region_width_scaled()); if (view_enabled) { x = view_xview[view_current]+((x-view_xport[view_current])/(double)view_wport[view_current])*view_wview[view_current]; } return x; /* This code replicates GM8.1's broken mouse_x/y int x = window_mouse_get_x(); int y = window_mouse_get_y(); if (view_enabled) { for (int i = 0; i < 8; i++) { if (view_visible[i]) { if (x >= view_xport[i] && x < view_xport[i]+view_wport[i] && y >= view_yport[i] && y < view_yport[i]+view_hport[i]) { return view_xview[i]+((x-view_xport[i])/(double)view_wport[i])*view_wview[i]; } } } } return x; */ }
void EnableDrawing (HGLRC *hRC) { WindowResizedCallback = &WindowResized; d3dmgr = new ContextManager(); int screenWidth = window_get_width(), screenHeight = window_get_height(); screenWidth = screenWidth <= 0 ? 1 : screenWidth; screenHeight = screenHeight <= 0 ? 1 : screenHeight; bool vsync = false; HWND hwnd = enigma::hWnd; bool fullscreen = false; HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { //return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { //return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { //return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { //return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { //return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { //return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { //return false; } // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. //error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { //return false; } // Release the display mode list. delete [] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Set the feature level to DirectX 11. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { //return false; } // Get the pointer to the back buffer. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { //return false; } // Create the render target view with the back buffer pointer. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { //return false; } // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = 0; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { //return false; } // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { //return false; } // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // Initailze the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { //return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { //return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); // Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); }
int main(int argc, char** argv) { init_core(); debug_message("[hunter] initialized core"); init_graphic(); debug_message("[hunter] initialized graphics, mode W%d H%d", window_get_width(global_get(global_get_singleton(), GLOBAL_WINDOW)), window_get_height(global_get(global_get_singleton(), GLOBAL_WINDOW))); init_sound(); debug_message("[hunter] initialized sound"); init_systems(); debug_message("[hunter] initialized systems"); window* window_handle = global_get(global_get_singleton(), GLOBAL_WINDOW); input* input_handle = global_get(global_get_singleton(), GLOBAL_INPUT); syscontainer* syscontainer_handle = global_get(global_get_singleton(), GLOBAL_SYSCONTAINER); text* text_handle = global_get(global_get_singleton(), GLOBAL_TEXT); hl_render* hl_render_handle = global_get(global_get_singleton(), GLOBAL_HL_RENDER); shader* shader_texture_handle = global_get(global_get_singleton(), GLOBAL_SHADER_TEXTURE); camera* camera_handle = global_get(global_get_singleton(), GLOBAL_CAMERA); debug_draw* debug_draw_handle = global_get(global_get_singleton(), GLOBAL_DEBUG_DRAW); float delta_ref_point = time_get_elapsed(window_handle); float delta_accumulator = 0.0f; float delta_frame_time = 0.0f; float fps_accumulator = 0.0f; float fps_value = 0.0f; float fps_value_last = fps_value; unsigned int fps_counter = 0; unsigned int game_kill_flag = 0; debug_message("[hunter] posting init event to systems"); syscontainer_post_event(syscontainer_handle, EVENT_INIT); while (!game_kill_flag) { delta_frame_time = time_get_elapsed(window_handle) - delta_ref_point; delta_ref_point = time_get_elapsed(window_handle); window_update(window_handle); input_state current_input_state; input_get_input_state(input_handle, ¤t_input_state); game_kill_flag |= window_get_should_close(window_handle); game_kill_flag |= current_input_state.key_dev; window_set_clear_color(window_handle, 1.0f, 0.0f, 1.0f, 0.0f); debug_draw_clear(debug_draw_handle); window_clear(window_handle); delta_accumulator += delta_frame_time; if (delta_accumulator < 0.0f) { delta_accumulator = 0.0f; } while (delta_accumulator >= 1.0f / DELTA_REFERENCE_FPS) { syscontainer_post_event(syscontainer_handle, EVENT_PRE_LOGIC); syscontainer_post_event(syscontainer_handle, EVENT_LOGIC); syscontainer_post_event(syscontainer_handle, EVENT_POST_LOGIC); delta_accumulator -= 1.0f / DELTA_REFERENCE_FPS; } syscontainer_post_event(syscontainer_handle, EVENT_DRAW); window_set_blend_mode(window_handle, WINDOW_BLEND_ALPHA); debug_draw_render_all(debug_draw_handle); hl_render_draw(hl_render_handle, shader_texture_handle, camera_handle); hl_render_clear(hl_render_handle); fps_counter++; fps_accumulator += delta_frame_time; if (fps_accumulator >= 1.0f) { fps_value_last = fps_value; fps_value = (float) fps_counter / fps_accumulator; fps_counter = 0; fps_accumulator = 0.0f; } text_batch fps_batch = {20, 20, 0.2f, 0.8f, 1.0f, 1.0f, "", "monospace", 12}; sprintf(fps_batch.text_data, "FPS : %3.2f (%3.2f)", fps_value, fps_value - fps_value_last); text_submit_batch(text_handle, &fps_batch); text_render_all(text_handle); text_flush_batch(text_handle); window_swap_buffers(window_handle); } debug_message("[hunter] posting destroy event to systems"); syscontainer_post_event(syscontainer_handle, EVENT_DESTROY); free_systems(); free_sound(); free_graphic(); free_core(); h_free_all(); debug_message("[hunter] terminated cleanly"); return 0; }
void init_graphic(void) { global* global_handle = global_get_singleton(); config* config_handle = NULL; config_alloc(&config_handle, "config/graphics.cfg"); int resx = config_get_int_value(config_handle, "resx"); int resy = config_get_int_value(config_handle, "resy"); int samples = config_get_int_value(config_handle, "msaa"); int windowed = config_get_int_value(config_handle, "windowed"); int vsync = config_get_int_value(config_handle, "vertical_sync"); config_free(&config_handle); window* window_handle = NULL; window_alloc(&window_handle, resx, resy, samples, !windowed, vsync, 1); window_set_blend_mode(window_handle, WINDOW_BLEND_ALPHA); window_set_clear_color(window_handle, 0.0f, 0.0f, 0.0f, 0.0f); global_set(global_handle, GLOBAL_WINDOW, window_handle); hl_render* hl_render_handle = NULL; hl_render_alloc(&hl_render_handle); global_set(global_handle, GLOBAL_HL_RENDER, hl_render_handle); // effect* effect_motion_blur_handle = NULL; // effect_alloc(&effect_motion_blur_handle, effect_motion_blur_init, effect_motion_blur_render, effect_motion_blur_config, effect_motion_blur_free, window_get_width(window_handle), window_get_height(window_handle)); // hl_render_add_effect(hl_render_handle, effect_motion_blur_handle, WINDOW_BLEND_ALPHA); camera* camera_handle = NULL; camera_alloc(&camera_handle); camera_set_dimension(camera_handle, CAMERA_SIZE * (float) window_get_width(window_handle) / (float) window_get_height(window_handle), CAMERA_SIZE); camera_set_position(camera_handle, 0.0f, 0.0f); camera_update_matrices(camera_handle); global_set(global_handle, GLOBAL_CAMERA, camera_handle); shader* shader_texture_handle = NULL; shader_alloc(&shader_texture_handle, SHADER_TEXTURE_VS, SHADER_TEXTURE_PS); global_set(global_handle, GLOBAL_SHADER_TEXTURE, shader_texture_handle); text* text_handle = NULL; text_alloc(&text_handle, camera_handle, window_handle); global_set(global_handle, GLOBAL_TEXT, text_handle); input* input_handle = NULL; input_alloc(&input_handle, window_handle); global_set(global_handle, GLOBAL_INPUT, input_handle); debug_draw* debug_draw_handle = NULL; debug_draw_alloc(&debug_draw_handle, hl_render_handle); global_set(global_handle, GLOBAL_DEBUG_DRAW, debug_draw_handle); }
int window_get_region_width_scaled() { return window_get_width(); }
/* ...surround-view scene rendering */ static void sview_redraw(display_data_t *display, void *data) { app_data_t *app = data; window_data_t *window = app->window; int W = window_get_width(window); int H = window_get_height(window); GstBuffer *buffers[CAMERAS_NUMBER]; texture_data_t *texture[CAMERAS_NUMBER]; GLuint tex[CAMERAS_NUMBER]; void *planes[CAMERAS_NUMBER]; s64 ts; /* ...try to get buffers */ while(sview_pop_buffers(app, buffers, texture, tex, planes, &ts)) { float fps = window_frame_rate_update(window); cairo_t *cr; /* ...ready for rendering; clear surface content */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); /* ...specify a GL-viewport for an image */ if (0) glViewport(0, 0, W, H); /* ...draw graphics on top of the scene */ cr = window_get_cairo(window); /* ...generate a single scene; acquire engine access lock */ pthread_mutex_lock(&app->access); sview_engine_process(app->sv, tex, planes, cr, ts); pthread_mutex_unlock(&app->access); /* ...output frame-rate in the upper-left corner */ if(app->flags & APP_FLAG_DEBUG) { cairo_set_source_rgba(cr, 1, 1, 1, 0.5); cairo_move_to(cr, 40, 80); draw_string(cr, "%.1f FPS", fps); } else { TRACE(DEBUG, _b("main-window fps: %.1f"), fps); } /* ...output GUI graphics as needed */ gui_redraw(app->gui, cr); /* ...release cairo interface */ window_put_cairo(window, cr); /* ...submit window to a compositor */ window_draw(window); /* ...release buffers collected */ sview_release_buffers(app, buffers); } TRACE(DEBUG, _b("surround-view drawing complete")); }