/* ================ Draw_ConsoleBackground -- johnfitz -- rewritten ================ */ void Draw_ConsoleBackground (void) { qpic_t *pic; float alpha; pic = Draw_CachePic ("gfx/conback.lmp"); pic->width = vid.conwidth; pic->height = vid.conheight; alpha = (con_forcedup) ? 1.0 : scr_conalpha.value; GL_SetCanvas (CANVAS_CONSOLE); //in case this is called from weird places if (alpha > 0.0) { if (alpha < 1.0) { glEnable (GL_BLEND); glColor4f (1,1,1,alpha); glDisable (GL_ALPHA_TEST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } Draw_Pic (0, 0, pic); if (alpha < 1.0) { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable (GL_ALPHA_TEST); glDisable (GL_BLEND); glColor4f (1,1,1,1); } } }
void SCR_DrawNotifyString (void) { const char *start; int l; int j; int x, y; GL_SetCanvas (CANVAS_MENU); //johnfitz start = scr_notifystring; y = 200 * 0.35; //johnfitz -- stretched overlays do { // scan the width of the line for (l=0 ; l<40 ; l++) if (start[l] == '\n' || !start[l]) break; x = (320 - l*8)/2; //johnfitz -- stretched overlays for (j=0 ; j<l ; j++, x+=8) Draw_Character (x, y, start[j]); y += 8; while (*start && *start != '\n') start++; if (!*start) break; start++; // skip the \n } while (1); }
/* ============== SCR_DrawCrosshair -- johnfitz ============== */ void SCR_DrawCrosshair (void) { if (!crosshair.value) return; GL_SetCanvas (CANVAS_CROSSHAIR); Draw_Character (-4, -4, '+'); //0,0 is center of viewport }
void SCR_DrawClock (void) { char str[9]; if (scr_clock.value == 1) { int minutes, seconds; minutes = cl.time / 60; seconds = ((int)cl.time)%60; sprintf (str,"%i:%i%i", minutes, seconds/10, seconds%10); } #ifdef _WIN32 else if (scr_clock.value == 2) { int hours, minutes, seconds; SYSTEMTIME systime; char m[3] = "AM"; GetLocalTime(&systime); hours = systime.wHour; minutes = systime.wMinute; seconds = systime.wSecond; if (hours > 12) strcpy(m, "PM"); hours = hours%12; if (hours == 0) hours = 12; sprintf (str,"%i:%i%i:%i%i %s", hours, minutes/10, minutes%10, seconds/10, seconds%10, m); } else if (scr_clock.value == 3) { int hours, minutes, seconds; SYSTEMTIME systime; GetLocalTime(&systime); hours = systime.wHour; minutes = systime.wMinute; seconds = systime.wSecond; sprintf (str,"%i:%i%i:%i%i", hours%12, minutes/10, minutes%10, seconds/10, seconds%10); } #endif else return; //draw it GL_SetCanvas (CANVAS_BOTTOMRIGHT); Draw_String(320 - (strlen(str) << 3), 200 - 8, str); scr_tileclear_updates = 0; }
void Screen_DrawFPS(void) { static double oldtime = 0,fps = 0; static int oldframecount = 0; double time; char str[128]; int x,y,frames; time = realtime-oldtime; frames = Video.iFrameCount - oldframecount; if(time < 0 || frames < 0) { oldtime = realtime; oldframecount = Video.iFrameCount; return; } // Allow us to set our own update rate. if(time > scr_fps_rate.value) { fps = frames / time; oldtime = realtime; oldframecount = Video.iFrameCount; } if(scr_showfps.value) //draw it { // Set the highest and lowest counts we get. if(fps > dHighestFPS) dHighestFPS = fps; if((fps < dLowestFPS) && fps >= 1) dLowestFPS = fps; sprintf(str,"%4.0f FPS (%1.0f/%1.0f)", fps,dHighestFPS,dLowestFPS); x = 320-(strlen(str)<<3); if (scr_con_current && (cls.state != ca_connected)) y = 200 - 16; else y = 200 - 8; if (scr_clock.value) y -= 8; //make room for clock GL_SetCanvas(CANVAS_BOTTOMRIGHT); Draw_String(x, y, str); scr_tileclear_updates = 0; } }
void SCR_DrawNet(void) { // [24/7/2012] Don't display when we're not even connected ~hogsy if( cl.maxclients <= 1 || cls.demoplayback || realtime-cl.last_received_message < 0.3f) return; GL_SetCanvas(CANVAS_DEFAULT); //johnfitz Draw_ExternPic("textures/interface/net",1.0f,scr_vrect.x+64,scr_vrect.y,64,64); }
/* ============== SCR_DrawNet ============== */ void SCR_DrawNet (void) { if (realtime - cl.last_received_message < 0.3) return; if (cls.demoplayback) return; GL_SetCanvas (CANVAS_DEFAULT); //johnfitz Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); }
/* ================ GL_Set2D -- johnfitz -- rewritten ================ */ void GL_Set2D (void) { currentcanvas = CANVAS_INVALID; GL_SetCanvas (CANVAS_DEFAULT); glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_BLEND); glEnable (GL_ALPHA_TEST); glColor4f (1,1,1,1); }
/* ============== SCR_DrawRam ============== */ void SCR_DrawRam (void) { if (!scr_showram.value) return; if (!r_cache_thrash) return; GL_SetCanvas (CANVAS_DEFAULT); //johnfitz Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); }
void Screen_DrawFPS(void) { static double oldtime = 0,fps = 0; static int oldframecount = 0; double time; char str[128]; int x,y,frames; time = realtime-oldtime; frames = r_framecount-oldframecount; if(time < 0 || frames < 0) { oldtime = realtime; oldframecount = r_framecount; return; } // [14/6/2012] Allow us to set our own update rate ~hogsy if(time > scr_fps_rate.value) { fps = frames/time; oldtime = realtime; oldframecount = r_framecount; } if(scr_showfps.value) //draw it { // [9/10/2012] Set the highest and lowest counts we get ~hogsy if(fps > dHighestFPS) dHighestFPS = fps; if((fps < dLowestFPS) && fps >= 1) dLowestFPS = fps; sprintf(str,"%4.0f FPS (%1.0f/%1.0f)", fps,dHighestFPS,dLowestFPS); x = 320-(strlen(str)<<3); y = 200-8; if (scr_clock.value) y -= 8; //make room for clock GL_SetCanvas(CANVAS_BOTTOMRIGHT); R_DrawString(x,y,str); scr_tileclear_updates = 0; } }
/* ============== SCR_DrawLoading ============== */ void SCR_DrawLoading (void) { qpic_t *pic; if (!scr_drawloading) return; GL_SetCanvas (CANVAS_MENU); //johnfitz pic = Draw_CachePic ("gfx/loading.lmp"); Draw_Pic ( (320 - pic->width)/2, (240 - 48 - pic->height)/2, pic); //johnfitz -- stretched menus scr_tileclear_updates = 0; //johnfitz }
void SCR_DrawCenterString (void) //actually do the drawing { char *start; int l; int j; int x, y; int remaining; GL_SetCanvas (CANVAS_MENU); //johnfitz // the finale prints the characters one at a time if (cl.intermission) remaining = scr_printspeed.value * (cl.time - scr_centertime_start); else remaining = 9999; scr_erase_center = 0; start = scr_centerstring; if (scr_center_lines <= 4) y = 200*0.35; //johnfitz -- 320x200 coordinate system else y = 48; if (crosshair.value) y -= 8; do { // scan the width of the line for (l=0 ; l<40 ; l++) if (start[l] == '\n' || !start[l]) break; x = (320 - l*8)/2; //johnfitz -- 320x200 coordinate system for (j=0 ; j<l ; j++, x+=8) { Draw_Character (x, y, start[j]); //johnfitz -- stretch overlays if (!remaining--) return; } y += 8; while (*start && *start != '\n') start++; if (!*start) break; start++; // skip the \n } while (1); }
/* Each frame, update warping textures */ void R_UpdateWarpTextures (void) { texture_t *tx; int i; float x, y, x2, warptess; if (r_oldwater.value || cl.bIsPaused || r_drawflat_cheatsafe || r_lightmap_cheatsafe) return; warptess = 128.0f / Math_Clamp(3.0f, floor(r_waterquality.value), 64.0f); for (i=0; i<cl.worldmodel->numtextures; i++) { tx = cl.worldmodel->textures[i]; if(!tx) continue; if(!tx->update_warp) continue; //render warp GL_SetCanvas (CANVAS_WARPIMAGE); Video_SetTexture(tx->gltexture); for (x=0.0; x<128.0; x=x2) { x2 = x + warptess; glBegin (GL_TRIANGLE_STRIP); for (y=0.0; y<128.01; y+=warptess) // .01 for rounding errors { glTexCoord2f (WARPCALC(x,y), WARPCALC(y,x)); glVertex2f (x,y); glTexCoord2f (WARPCALC(x2,y), WARPCALC(y,x2)); glVertex2f (x2,y); } glEnd(); } //copy to texture Video_SetTexture(tx->warpimage); glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly+glheight-gl_warpimagesize, gl_warpimagesize, gl_warpimagesize); tx->update_warp = FALSE; } //if viewsize is less than 100, we need to redraw the frame around the viewport scr_tileclear_updates = 0; }
/* ============== DrawPause ============== */ void SCR_DrawPause (void) { qpic_t *pic; if (!cl.paused) return; if (!scr_showpause.value) // turn off for screenshots return; GL_SetCanvas (CANVAS_MENU); //johnfitz pic = Draw_CachePic ("gfx/pause.lmp"); Draw_Pic ( (320 - pic->width)/2, (240 - 48 - pic->height)/2, pic); //johnfitz -- stretched menus scr_tileclear_updates = 0; //johnfitz }
void SCR_DrawDevStats (void) { Colour_t colour_dark = { 0, 0, 0, 0.5f }; char str[40]; int y = 25-9; //9=number of lines to print int x = 0; //margin if (!devstats.value) return; GL_SetCanvas (CANVAS_BOTTOMLEFT); Draw_Rectangle(x,y*8,152,72, colour_dark); //dark rectangle sprintf (str, "devstats |Curr Peak"); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "---------+---------"); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Edicts |%4i %4i", dev_stats.edicts, dev_peakstats.edicts); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Packet |%4i %4i", dev_stats.packetsize, dev_peakstats.packetsize); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Visedicts|%4i %4i", dev_stats.visedicts, dev_peakstats.visedicts); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Efrags |%4i %4i", dev_stats.efrags, dev_peakstats.efrags); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Dlights |%4i %4i", dev_stats.dlights, dev_peakstats.dlights); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Beams |%4i %4i", dev_stats.beams, dev_peakstats.beams); Draw_String(x, (y++) * 8 - x, str); sprintf (str, "Tempents |%4i %4i", dev_stats.tempents, dev_peakstats.tempents); Draw_String(x, (y++) * 8 - x, str); }
/* ============== SCR_DrawTurtle ============== */ void SCR_DrawTurtle (void) { static int count; if (!scr_showturtle.value) return; if (host_frametime < 0.1) { count = 0; return; } count++; if (count < 3) return; GL_SetCanvas (CANVAS_DEFAULT); //johnfitz Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); }
/* ============== SCR_DrawFPS -- johnfitz ============== */ void SCR_DrawFPS (void) { static double oldtime = 0; static double lastfps = 0; static int oldframecount = 0; double elapsed_time; int frames; elapsed_time = realtime - oldtime; frames = r_framecount - oldframecount; if (elapsed_time < 0 || frames < 0) { oldtime = realtime; oldframecount = r_framecount; return; } // update value every 3/4 second if (elapsed_time > 0.75) { lastfps = frames / elapsed_time; oldtime = realtime; oldframecount = r_framecount; } if (scr_showfps.value) { char st[16]; int x, y; sprintf (st, "%4.0f fps", lastfps); x = 320 - (strlen(st)<<3); y = 200 - 8; if (scr_clock.value) y -= 8; //make room for clock GL_SetCanvas (CANVAS_BOTTOMRIGHT); Draw_String (x, y, st); scr_tileclear_updates = 0; } }
/* ============== SCR_DrawClock -- johnfitz ============== */ void SCR_DrawClock (void) { char str[12]; if (scr_clock.value == 1) { int minutes, seconds; minutes = cl.time / 60; seconds = ((int)cl.time)%60; sprintf (str,"%i:%i%i", minutes, seconds/10, seconds%10); } else return; //draw it GL_SetCanvas (CANVAS_BOTTOMRIGHT); Draw_String (320 - (strlen(str)<<3), 200 - 8, str); scr_tileclear_updates = 0; }
/* ================ Draw_FadeScreen -- johnfitz -- revised ================ */ void Draw_FadeScreen (void) { GL_SetCanvas (CANVAS_DEFAULT); glEnable (GL_BLEND); glDisable (GL_ALPHA_TEST); glDisable (GL_TEXTURE_2D); glColor4f (0, 0, 0, 0.5); glBegin (GL_QUADS); glVertex2f (0,0); glVertex2f (glwidth, 0); glVertex2f (glwidth, glheight); glVertex2f (0, glheight); glEnd (); glColor4f (1,1,1,1); glEnable (GL_TEXTURE_2D); glEnable (GL_ALPHA_TEST); glDisable (GL_BLEND); Sbar_Changed(); }
void R_UpdateWarpTextures (void) { texture_t *tx; int i; float x, y, x2, warptess; if (cl.paused || r_drawflat_cheatsafe || r_lightmap_cheatsafe) return; warptess = 128.0/CLAMP (3.0, floor(r_waterquality.value), 64.0); int num_textures = cl.worldmodel->numtextures; int num_warp_textures = 0; // Render warp to top mips for (i = 0; i < num_textures; ++i) { if (!(tx = cl.worldmodel->textures[i])) continue; if (!tx->update_warp) continue; VkRect2D render_area; render_area.offset.x = 0; render_area.offset.y = 0; render_area.extent.width = WARPIMAGESIZE; render_area.extent.height = WARPIMAGESIZE; VkRenderPassBeginInfo render_pass_begin_info; memset(&render_pass_begin_info, 0, sizeof(render_pass_begin_info)); render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin_info.renderArea = render_area; render_pass_begin_info.renderPass = vulkan_globals.warp_render_pass; render_pass_begin_info.framebuffer = tx->warpimage->frame_buffer; vkCmdBeginRenderPass(vulkan_globals.command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); //render warp GL_SetCanvas (CANVAS_WARPIMAGE); vkCmdBindPipeline(vulkan_globals.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan_globals.warp_pipeline); vkCmdBindDescriptorSets(vulkan_globals.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan_globals.basic_pipeline_layout, 0, 1, &tx->gltexture->descriptor_set, 0, NULL); int num_verts = 0; for (y=0.0; y<128.01; y+=warptess) // .01 for rounding errors num_verts += 2; for (x=0.0; x<128.0; x=x2) { VkBuffer buffer; VkDeviceSize buffer_offset; basicvertex_t * vertices = (basicvertex_t*)R_VertexAllocate(num_verts * sizeof(basicvertex_t), &buffer, &buffer_offset); int i = 0; x2 = x + warptess; for (y=0.0; y<128.01; y+=warptess) // .01 for rounding errors { vertices[i].position[0] = x; vertices[i].position[1] = y; vertices[i].position[2] = 0.0f; vertices[i].texcoord[0] = WARPCALC(x,y); vertices[i].texcoord[1] = WARPCALC(y,x); vertices[i].color[0] = 255; vertices[i].color[1] = 255; vertices[i].color[2] = 255; vertices[i].color[3] = 255; i += 1; vertices[i].position[0] = x2; vertices[i].position[1] = y; vertices[i].position[2] = 0.0f; vertices[i].texcoord[0] = WARPCALC(x2,y); vertices[i].texcoord[1] = WARPCALC(y,x2); vertices[i].color[0] = 255; vertices[i].color[1] = 255; vertices[i].color[2] = 255; vertices[i].color[3] = 255; i += 1; } vkCmdBindVertexBuffers(vulkan_globals.command_buffer, 0, 1, &buffer, &buffer_offset); vkCmdDraw(vulkan_globals.command_buffer, num_verts, 1, 0, 0); } vkCmdEndRenderPass(vulkan_globals.command_buffer); VkImageMemoryBarrier * image_barrier = &warp_image_barriers[num_warp_textures]; image_barrier->sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_barrier->pNext = NULL; image_barrier->srcAccessMask = VK_ACCESS_SHADER_READ_BIT; image_barrier->dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; image_barrier->oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_barrier->newLayout = VK_IMAGE_LAYOUT_GENERAL; image_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_barrier->image = tx->warpimage->image; image_barrier->subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; image_barrier->subresourceRange.baseMipLevel = 1; image_barrier->subresourceRange.levelCount = WARPIMAGEMIPS - 1; image_barrier->subresourceRange.baseArrayLayer = 0; image_barrier->subresourceRange.layerCount = 1; warp_textures[num_warp_textures] = tx; num_warp_textures += 1; } // Make sure that writes are done for top mips we just rendered to VkMemoryBarrier memory_barrier; memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; memory_barrier.pNext = NULL; memory_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Transfer all other mips from UNDEFINED to GENERAL layout vkCmdPipelineBarrier(vulkan_globals.command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &memory_barrier, 0, NULL, num_warp_textures, warp_image_barriers); // Generate mip chains for (int mip = 1; mip < WARPIMAGEMIPS; ++mip) { int srcSize = WARPIMAGESIZE >> (mip - 1); int dstSize = WARPIMAGESIZE >> mip; for (i = 0; i < num_warp_textures; ++i) { tx = warp_textures[i]; VkImageBlit region; memset(®ion, 0, sizeof(region)); region.srcOffsets[1].x = srcSize; region.srcOffsets[1].y = srcSize; region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.srcSubresource.layerCount = 1; region.srcSubresource.mipLevel = (mip - 1); region.dstOffsets[1].x = dstSize; region.dstOffsets[1].y = dstSize; region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.dstSubresource.layerCount = 1; region.dstSubresource.mipLevel = mip; vkCmdBlitImage(vulkan_globals.command_buffer, tx->warpimage->image, VK_IMAGE_LAYOUT_GENERAL, tx->warpimage->image, VK_IMAGE_LAYOUT_GENERAL, 1, ®ion, VK_FILTER_LINEAR); } if (mip < (WARPIMAGEMIPS - 1)) { memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; vkCmdPipelineBarrier(vulkan_globals.command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &memory_barrier, 0, NULL, 0, NULL); } } // Transfer all warp texture mips from GENERAL to SHADER_READ_ONLY_OPTIMAL for (i = 0; i < num_warp_textures; ++i) { tx = warp_textures[i]; VkImageMemoryBarrier * image_barrier = &warp_image_barriers[i]; image_barrier->sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_barrier->pNext = NULL; image_barrier->srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; image_barrier->dstAccessMask = VK_ACCESS_SHADER_READ_BIT; image_barrier->oldLayout = VK_IMAGE_LAYOUT_GENERAL; image_barrier->newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; image_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_barrier->image = tx->warpimage->image; image_barrier->subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; image_barrier->subresourceRange.baseMipLevel = 0; image_barrier->subresourceRange.levelCount = WARPIMAGEMIPS; image_barrier->subresourceRange.baseArrayLayer = 0; image_barrier->subresourceRange.layerCount = 1; tx->update_warp = false; } vkCmdPipelineBarrier(vulkan_globals.command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, num_warp_textures, warp_image_barriers); //if warp render went down into sbar territory, we need to be sure to refresh it next frame if (WARPIMAGESIZE + sb_lines > glheight) Sbar_Changed (); //if viewsize is less than 100, we need to redraw the frame around the viewport scr_tileclear_updates = 0; }