void screen_init() { enigma::gui_width = window_get_region_width_scaled(); enigma::gui_height = window_get_region_height_scaled(); d3dmgr->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3dmgr->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); if (!view_enabled) { d3dmgr->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); screen_set_viewport(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled()); d3d_set_projection_ortho(0, 0, room_width, room_height, 0); } else { for (view_current = 0; view_current < 7; view_current++) { if (view_visible[(int)view_current]) { int vc = (int)view_current; screen_set_viewport(view_xport[vc], view_yport[vc], (window_get_region_width_scaled() - view_xport[vc]), (window_get_region_height_scaled() - view_yport[vc])); d3d_set_projection_ortho(view_xview[vc], view_wview[vc] + view_xview[vc], view_yview[vc], view_hview[vc] + view_yview[vc], view_angle[vc]); break; } } } d3dmgr->SetRenderState(D3DRS_LIGHTING, FALSE); d3dmgr->SetRenderState(D3DRS_ZENABLE, TRUE); d3dmgr->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); d3dmgr->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x00000001); d3dmgr->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); d3dmgr->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); d3dmgr->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); d3dmgr->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); draw_set_color(c_white); }
void display_reset(int samples, bool vsync) { int interval = vsync ? 1 : 0; if (enigma::is_ext_swapcontrol_supported()) { wglSwapIntervalEXT(interval); } GLint fbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo); GLuint ColorBufferID, DepthBufferID; // Cleanup the multi-sampler fbo if turning off multi-sampling if (samples == 0) { if (enigma::msaa_fbo != 0) { glDeleteFramebuffers(1, &enigma::msaa_fbo); enigma::msaa_fbo = 0; } return; } //TODO: Change the code below to fix this to size properly to views // If we don't already have a multi-sample fbo then create one if (enigma::msaa_fbo == 0) { glGenFramebuffers(1, &enigma::msaa_fbo); } glBindFramebuffer(GL_FRAMEBUFFER, enigma::msaa_fbo); // Now make a multi-sample color buffer glGenRenderbuffers(1, &ColorBufferID); glBindRenderbuffer(GL_RENDERBUFFER, ColorBufferID); glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGBA8, window_get_region_width_scaled(), window_get_region_height_scaled()); // We also need a depth buffer glGenRenderbuffersEXT(1, &DepthBufferID); glBindRenderbufferEXT(GL_RENDERBUFFER, DepthBufferID); glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, window_get_region_width_scaled(), window_get_region_height_scaled()); // Attach the render buffers to the multi-sampler fbo glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ColorBufferID); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBufferID); }
void screen_init() { enigma::gui_width = window_get_region_width_scaled(); enigma::gui_height = window_get_region_height_scaled(); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (!view_enabled) { glClearColor(0,0,0,0); screen_set_viewport(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled()); d3d_set_projection_ortho(0, 0, room_width, room_height, 0); } else { for (view_current = 0; view_current < 7; view_current++) { if (view_visible[(int)view_current]) { int vc = (int)view_current; glClearColor(0,0,0,0); screen_set_viewport(view_xport[vc], view_yport[vc], view_wport[vc], view_hport[vc]); d3d_set_projection_ortho(view_xview[vc], view_yview[vc], view_wview[vc], view_hview[vc], 0); break; } } } glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glAlphaFunc(GL_ALWAYS,0); texture_reset(); draw_set_color(c_white); }
//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 screen_redraw() { //d3dmgr->EndShapesBatching(); //If called inside bound surface we need to finish drawing d3dmgr->BeginScene(); // Clean up any textures that ENIGMA may still think are binded but actually are not d3d_set_zwriteenable(true); if (!view_enabled) { screen_set_viewport(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled()); clear_view(0, 0, room_width, room_height, 0, background_showcolor); draw_back(); draw_insts(); draw_tiles(); } else { //TODO: Possibly implement view option from Stupido to control which view clears the background // Only clear the background on the first visible view by checking if it hasn't been cleared yet bool draw_backs = true; bool background_allviews = true; // FIXME: Create a setting for this. for (view_current = 0; view_current < 8; view_current++) { int vc = (int)view_current; if (!view_visible[vc]) continue; int vob = (int)view_object[vc]; if (vob != -1) follow_object(vob, vc); screen_set_viewport(view_xport[vc], view_yport[vc], view_wport[vc], view_hport[vc]); clear_view(view_xview[vc], view_yview[vc], view_wview[vc], view_hview[vc], view_angle[vc], background_showcolor && draw_backs); if (draw_backs) draw_back(); draw_insts(); if (draw_tiles()) break; draw_backs = background_allviews; } view_current = 0; } // Now process the sub event of draw called draw gui // It is for drawing GUI elements without view scaling and transformation if (enigma::gui_used) { screen_set_viewport(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled()); d3d_set_projection_ortho(0, 0, enigma::gui_width, enigma::gui_height, 0); // Clear the depth buffer if hidden surface removal is on at the beginning of the draw step. if (enigma::d3dMode) d3dmgr->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); draw_gui(); } d3dmgr->EndScene(); ///TODO: screen_refresh() shouldn't be in screen_redraw(). They are separate functions for a reason. screen_refresh(); }
void screen_init() { enigma::gui_width = window_get_region_width_scaled(); enigma::gui_height = window_get_region_height_scaled(); if (!view_enabled) { //glMatrixMode(GL_PROJECTION); //gluPerspective(0, 1, 0, 1); //glMatrixMode(GL_MODELVIEW); d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); D3DVIEWPORT9 pViewport = { 0, 0, (DWORD)window_get_region_width_scaled(), (DWORD)window_get_region_height_scaled(), 0, 1.0f }; d3ddev->SetViewport(&pViewport); D3DXMATRIX matTrans, matScale; // Calculate a translation matrix D3DXMatrixTranslation(&matTrans, -0.5, -room_height - 0.5, 0); D3DXMatrixScaling(&matScale, 1, -1, 1); // Calculate our world matrix by multiplying the above (in the correct order) D3DXMATRIX matWorld = matTrans * matScale; // Set the matrix to be applied to anything we render from now on d3ddev->SetTransform( D3DTS_VIEW, &matWorld); D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixOrthoOffCenterLH(&matProjection, 0, (FLOAT)room_width, 0, (FLOAT)room_height, 0.0f, // the near view-plane 1.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection transform d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->SetRenderState(D3DRS_ZENABLE, FALSE); d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //glEnable(GL_BLEND); //glEnable(GL_TEXTURE_2D); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); //glAlphaFunc(GL_ALWAYS,0); //glColor4f(0,0,0,1); } else { for (view_current = 0; view_current < 7; view_current++) { if (view_visible[(int)view_current]) { int vc = (int)view_current; //gluPerspective(0, 1, 0, 1); D3DVIEWPORT9 pViewport = { (DWORD)view_xport[vc], (DWORD)view_yport[vc], (DWORD)(window_get_region_width_scaled() - view_xport[vc]), (DWORD)(window_get_region_height_scaled() - view_yport[vc]), 0, 1.0f }; d3ddev->SetViewport(&pViewport); D3DXMATRIX matTrans, matScale; // Calculate a translation matrix D3DXMatrixTranslation(&matTrans, -view_xview[vc] - 0.5, -view_yview[vc] - room_height - 0.5, 0); D3DXMatrixScaling(&matScale, 1, -1, 1); // Calculate our world matrix by multiplying the above (in the correct order) D3DXMATRIX matWorld = matTrans * matScale; // Set the matrix to be applied to anything we render from now on d3ddev->SetTransform( D3DTS_VIEW, &matWorld); D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixOrthoOffCenterLH(&matProjection, 0, (FLOAT)view_wview[vc], 0, (FLOAT)view_hview[vc], 0.0f, // the near view-plane 1.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection transform d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->SetRenderState(D3DRS_ZENABLE, FALSE); d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //glEnable(GL_BLEND); //glEnable(GL_TEXTURE_2D); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); //glAlphaFunc(GL_ALWAYS,0); //glColor4f(0,0,0,1); break; } } } }
void screen_redraw() { // Should implement extended lost device checking //if (d3ddev == NULL ) return; // Clean up any textures that ENIGMA may still think are binded but actually are not texture_reset(); d3ddev->BeginScene(); // begins the 3D scene dsprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DO_NOT_ADDREF_TEXTURE); if (!view_enabled) { D3DVIEWPORT9 pViewport = { 0, 0, (DWORD)window_get_region_width_scaled(), (DWORD)window_get_region_height_scaled(), 0, 1.0f }; d3ddev->SetViewport(&pViewport); D3DXMATRIX matTrans, matScale; // Calculate a translation matrix D3DXMatrixTranslation(&matTrans, -0.5, -room_height - 0.5, 0); D3DXMatrixScaling(&matScale, 1, -1, 1); // Calculate our world matrix by multiplying the above (in the correct order) D3DXMATRIX matWorld = matTrans * matScale; // Set the matrix to be applied to anything we render from now on d3ddev->SetTransform( D3DTS_VIEW, &matWorld); D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixOrthoOffCenterLH(&matProjection, 0, (FLOAT)room_width, 0, (FLOAT)room_height, 0.0f, // the near view-plane 1.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection transform if (background_showcolor) { int clearcolor = ((int)background_color) & 0x00FFFFFF; // clear the window to the background color d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(__GETR(clearcolor), __GETG(clearcolor), __GETB(clearcolor)), 1.0f, 0); // clear the depth buffer } // Clear the depth buffer if 3d mode is on at the beginning of the draw step. if (enigma::d3dMode) d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); draw_back(); // Apply and clear stored depth changes. for (map<int,pair<double,double> >::iterator it = id_to_currentnextdepth.begin(); it != id_to_currentnextdepth.end(); it++) { enigma::object_graphics* inst_depth = (enigma::object_graphics*)enigma::fetch_instance_by_id((*it).first); if (inst_depth != NULL) { drawing_depths[(*it).second.first].draw_events->unlink(inst_depth->depth.myiter); inst_iter* mynewiter = drawing_depths[(*it).second.second].draw_events->add_inst(inst_depth->depth.myiter->inst); if (instance_event_iterator == inst_depth->depth.myiter) { instance_event_iterator = inst_depth->depth.myiter->prev; } inst_depth->depth.myiter = mynewiter; } } id_to_currentnextdepth.clear(); if (enigma::particles_impl != NULL) { const double high = numeric_limits<double>::max(); const double low = drawing_depths.rbegin() != drawing_depths.rend() ? drawing_depths.rbegin()->first : -numeric_limits<double>::max(); (enigma::particles_impl->draw_particlesystems)(high, low); } bool stop_loop = false; for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++) { if (dit->second.tiles.size()) //glCallList(drawing_depths[dit->second.tiles[0].depth].tilelist); texture_reset(); enigma::inst_iter* push_it = enigma::instance_event_iterator; //loop instances for (enigma::instance_event_iterator = dit->second.draw_events->next; enigma::instance_event_iterator != NULL; enigma::instance_event_iterator = enigma::instance_event_iterator->next) { enigma::instance_event_iterator->inst->myevent_draw(); if (enigma::room_switching_id != -1) { stop_loop = true; break; } } enigma::instance_event_iterator = push_it; if (stop_loop) break; //particles if (enigma::particles_impl != NULL) { const double high = dit->first; dit++; const double low = dit != drawing_depths.rend() ? dit->first : -numeric_limits<double>::max(); dit--; (enigma::particles_impl->draw_particlesystems)(high, low); } } //return; } else { bool stop_loop = false; for (view_current = 0; view_current < 7; view_current++) { if (view_visible[(int)view_current]) { int vc = (int)view_current; int vob = (int)view_object[vc]; if (vob != -1) { object_basic *instanceexists = fetch_instance_by_int(vob); if (instanceexists) { object_planar* vobr = (object_planar*)instanceexists; double vobx = vobr->x, voby = vobr->y; //int bbl=*vobr.x+*vobr.bbox_left,bbr=*vobr.x+*vobr.bbox_right,bbt=*vobr.y+*vobr.bbox_top,bbb=*vobr.y+*vobr.bbox_bottom; //if (bbl<view_xview[vc]+view_hbor[vc]) view_xview[vc]=bbl-view_hbor[vc]; double vbc_h, vbc_v; (view_hborder[vc] > view_wview[vc]/2) ? vbc_h = view_wview[vc]/2 : vbc_h = view_hborder[vc]; (view_vborder[vc] > view_hview[vc]/2) ? vbc_v = view_hview[vc]/2 : vbc_v = view_vborder[vc]; if (view_hspeed[vc] == -1) { if (vobx < view_xview[vc] + vbc_h) view_xview[vc] = vobx - vbc_h; else if (vobx > view_xview[vc] + view_wview[vc] - vbc_h) view_xview[vc] = vobx + vbc_h - view_wview[vc]; } else { if (vobx < view_xview[vc] + vbc_h) { view_xview[vc] -= view_hspeed[vc]; if (view_xview[vc] < vobx - vbc_h) view_xview[vc] = vobx - vbc_h; } else if (vobx > view_xview[vc] + view_wview[vc] - vbc_h) { view_xview[vc] += view_hspeed[vc]; if (view_xview[vc] > vobx + vbc_h - view_wview[vc]) view_xview[vc] = vobx + vbc_h - view_wview[vc]; } } if (view_vspeed[vc] == -1) { if (voby < view_yview[vc] + vbc_v) view_yview[vc] = voby - vbc_v; else if (voby > view_yview[vc] + view_hview[vc] - vbc_v) view_yview[vc] = voby + vbc_v - view_hview[vc]; } else { if (voby < view_yview[vc] + vbc_v) { view_yview[vc] -= view_vspeed[vc]; if (view_yview[vc] < voby - vbc_v) view_yview[vc] = voby - vbc_v; } if (voby > view_yview[vc] + view_hview[vc] - vbc_v) { view_yview[vc] += view_vspeed[vc]; if (view_yview[vc] > voby + vbc_v - view_hview[vc]) view_yview[vc] = voby + vbc_v - view_hview[vc]; } } if (view_xview[vc] < 0) view_xview[vc] = 0; else if (view_xview[vc] > room_width - view_wview[vc]) view_xview[vc] = room_width - view_wview[vc]; if (view_yview[vc] < 0) view_yview[vc] = 0; else if (view_yview[vc] > room_height - view_hview[vc]) view_yview[vc] = room_height - view_hview[vc]; } } D3DVIEWPORT9 pViewport = { (DWORD)view_xport[vc], (DWORD)view_yport[vc], (DWORD)(window_get_region_width_scaled() - view_xport[vc]), (DWORD)(window_get_region_height_scaled() - view_yport[vc]), 0, 1.0f }; d3ddev->SetViewport(&pViewport); D3DXMATRIX matTrans, matScale; // Calculate a translation matrix D3DXMatrixTranslation(&matTrans, -view_xview[vc] - 0.5, -view_yview[vc] - room_height - 0.5, 0); D3DXMatrixScaling(&matScale, 1, -1, 1); // Calculate our world matrix by multiplying the above (in the correct order) D3DXMATRIX matWorld = matTrans * matScale; // Set the matrix to be applied to anything we render from now on d3ddev->SetTransform( D3DTS_VIEW, &matWorld); D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixOrthoOffCenterLH(&matProjection, 0, (FLOAT)view_wview[vc], 0, (FLOAT)view_hview[vc], 0.0f, // the near view-plane 1.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection transform if (background_showcolor && view_current == 0) { int clearcolor = ((int)background_color) & 0x00FFFFFF; // clear the window to the background color d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(__GETR(clearcolor), __GETG(clearcolor), __GETB(clearcolor)), 1.0f, 0); } // Clear the depth buffer if 3d mode is on at the beginning of the draw step. if (enigma::d3dMode) d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); if (view_current == 0) { draw_back(); } // Apply and clear stored depth changes. for (map<int,pair<double,double> >::iterator it = id_to_currentnextdepth.begin(); it != id_to_currentnextdepth.end(); it++) { enigma::object_graphics* inst_depth = (enigma::object_graphics*)enigma::fetch_instance_by_id((*it).first); if (inst_depth != NULL) { drawing_depths[(*it).second.first].draw_events->unlink(inst_depth->depth.myiter); inst_iter* mynewiter = drawing_depths[(*it).second.second].draw_events->add_inst(inst_depth->depth.myiter->inst); if (instance_event_iterator == inst_depth->depth.myiter) { instance_event_iterator = inst_depth->depth.myiter->prev; } inst_depth->depth.myiter = mynewiter; } } id_to_currentnextdepth.clear(); if (enigma::particles_impl != NULL) { const double high = numeric_limits<double>::max(); const double low = drawing_depths.rbegin() != drawing_depths.rend() ? drawing_depths.rbegin()->first : -numeric_limits<double>::max(); (enigma::particles_impl->draw_particlesystems)(high, low); } for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++) { if (dit->second.tiles.size()) //glCallList(drawing_depths[dit->second.tiles[0].depth].tilelist); texture_reset(); enigma::inst_iter* push_it = enigma::instance_event_iterator; //loop instances for (enigma::instance_event_iterator = dit->second.draw_events->next; enigma::instance_event_iterator != NULL; enigma::instance_event_iterator = enigma::instance_event_iterator->next) { enigma::instance_event_iterator->inst->myevent_draw(); if (enigma::room_switching_id != -1) { stop_loop = true; break; } } enigma::instance_event_iterator = push_it; if (stop_loop) break; //particles if (enigma::particles_impl != NULL) { const double high = dit->first; dit++; const double low = dit != drawing_depths.rend() ? dit->first : -numeric_limits<double>::max(); dit--; (enigma::particles_impl->draw_particlesystems)(high, low); } } if (stop_loop) break; } } view_current = 0; } int culling = d3d_get_culling(); d3d_set_culling(rs_none); // Now process the sub event of draw called draw gui // It is for drawing GUI elements without view scaling and transformation if (enigma::gui_used) { // Now process the sub event of draw called draw gui // It is for drawing GUI elements without view scaling and transformation D3DVIEWPORT9 pViewport = { 0, 0, window_get_region_width_scaled(), window_get_region_height_scaled(), 0, 1.0f }; d3ddev->SetViewport(&pViewport); D3DXMATRIX matTrans, matScale; // Calculate a translation matrix D3DXMatrixTranslation(&matTrans, -0.5, -room_height - 0.5, 0); D3DXMatrixScaling(&matScale, 1, -1, 1); // Calculate our world matrix by multiplying the above (in the correct order) D3DXMATRIX matWorld = matTrans * matScale; // Set the matrix to be applied to anything we render from now on d3ddev->SetTransform( D3DTS_VIEW, &matWorld); D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixOrthoOffCenterLH(&matProjection, 0, (FLOAT)enigma::gui_width, 0, (FLOAT)enigma::gui_height, 0.0f, // the near view-plane 1.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection transform //dsprite->SetWorldViewRH(NULL, &matWorld); // Clear the depth buffer if hidden surface removal is on at the beginning of the draw step. if (enigma::d3dMode) d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); bool stop_loop = false; for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++) { enigma::inst_iter* push_it = enigma::instance_event_iterator; //loop instances for (enigma::instance_event_iterator = dit->second.draw_events->next; enigma::instance_event_iterator != NULL; enigma::instance_event_iterator = enigma::instance_event_iterator->next) { enigma::instance_event_iterator->inst->myevent_drawgui(); if (enigma::room_switching_id != -1) { stop_loop = true; break; } } enigma::instance_event_iterator = push_it; if (stop_loop) break; } } // Textures should be clamped when rendering 2D sprites and stuff, so memorize it. DWORD wrapu, wrapv, wrapw; d3ddev->GetSamplerState( 0, D3DSAMP_ADDRESSU, &wrapu ); d3ddev->GetSamplerState( 0, D3DSAMP_ADDRESSV, &wrapv ); d3ddev->GetSamplerState( 0, D3DSAMP_ADDRESSW, &wrapw ); d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP ); // The D3D sprite batcher uses clockwise face culling which is default but can't tell if // this here should memorize it and force it to CW all the time and then reset what the user had // or not. //d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); dsprite->End(); // And now reset the texture repetition. d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSU, wrapu ); d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSV, wrapv ); d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSW, wrapw ); // reset the culling d3d_set_culling(culling); d3ddev->EndScene(); // ends the 3D scene screen_refresh(); }
void screen_redraw() { // Clean up any textures that ENIGMA may still think are binded but actually are not d3d_set_zwriteenable(true); if (!view_enabled) { if (bound_framebuffer != 0) //This fixes off-by-one error when rendering on surfaces. This should be checked to see if other GPU's have the same effect screen_set_viewport(1, 1, window_get_region_width_scaled(), window_get_region_height_scaled()); else screen_set_viewport(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled()); clear_view(0, 0, room_width, room_height, background_showcolor); draw_back(); draw_insts(); draw_tiles(); } else { //TODO: Possibly implement view option from Stupido to control which view clears the background // Only clear the background on the first visible view by checking if it hasn't been cleared yet bool draw_backs = true; bool background_allviews = true; // FIXME: Create a setting for this. for (view_current = 0; view_current < 8; view_current++) { int vc = (int)view_current; if (!view_visible[vc]) continue; int vob = (int)view_object[vc]; if (vob != -1) follow_object(vob, vc); if (bound_framebuffer != 0) //This fixes off-by-one error when rendering on surfaces. This should be checked to see if other GPU's have the same effect screen_set_viewport(view_xport[vc]+1, view_yport[vc]+1, view_wport[vc], view_hport[vc]); else printf("%d %d %d %d\n", (int)view_xport[vc], (int)view_yport[vc], (int)view_wport[vc], (int)view_hport[vc]), screen_set_viewport(view_xport[vc], view_yport[vc], view_wport[vc], view_hport[vc]); clear_view(view_xview[vc], view_yview[vc], view_wview[vc], view_hview[vc], background_showcolor && draw_backs); if (draw_backs) draw_back(); draw_insts(); if (draw_tiles()) break; draw_backs = background_allviews; } view_current = 0; } // Now process the sub event of draw called draw gui // It is for drawing GUI elements without view scaling and transformation if (enigma::gui_used) { screen_set_viewport(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled()); d3d_set_projection_ortho(0, 0, enigma::gui_width, enigma::gui_height, 0); // Clear the depth buffer if hidden surface removal is on at the beginning of the draw step. if (enigma::d3dMode) glClear(GL_DEPTH_BUFFER_BIT); draw_gui(); } if (enigma::msaa_fbo != 0) { GLint fbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, enigma::msaa_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //TODO: Change the code below to fix this to size properly to views glBlitFramebuffer(0, 0, window_get_region_width_scaled(), window_get_region_height_scaled(), 0, 0, window_get_region_width_scaled(), window_get_region_height_scaled(), GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); // glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels); } ///TODO: screen_refresh() shouldn't be in screen_redraw(). They are separate functions for a reason. if (bound_framebuffer==0 || enigma::msaa_fbo != 0) { screen_refresh(); } }