bool JRenderServer::UnlockVB( int vbID ) { if (vbID < 0 || vbID >= m_VBuffers.size()) return false; IDirect3DVertexBuffer8* pBuffer = m_VBuffers[vbID].m_pBuffer; if (!pBuffer) return NULL; HRESULT hRes = pBuffer->Unlock(); return (hRes == S_OK); } // JRenderServer::UnlockVB
int JRenderServer::ClearVB( int vbID ) { if (vbID < 0 || vbID >= m_VBuffers.size()) return false; IDirect3DVertexBuffer8* pBuffer = m_VBuffers[vbID].m_pBuffer; if (!pBuffer) return false; BYTE* pData = NULL; HRESULT hRes = pBuffer->Lock( 0, m_VBuffers[vbID].m_Size, &pData, D3DLOCK_DISCARD ); if (hRes != S_OK) return -1; pBuffer->Unlock(); m_VBuffers[vbID].m_CurIteration++; return m_VBuffers[vbID].m_CurIteration; return -1; } // JRenderServer::ClearVB
void d3d_batch_string(int sx, int sy, char *s, int bw, int bh, float u_scale, float v_scale, uint color) { int spacing = 0; int width; int x = sx; int y = sy; // centered x =(sx==0x8000) ? get_centered_x(s) : sx; do { HRESULT hr; int magic_num, magic_num2; int len = strlen_magic(s, magic_num, magic_num2); int new_id = -1; if(len == 0) return; // Set to 0 to turn off batching to gfx card memory #if 1 // Check the string is of a valid size if(len > MIN_STRING_LEN && len < MAX_LG_STR_LEN) { bool long_str = (len >= MAX_SM_STR_LEN); int index = find_string(len, magic_num, magic_num2, sx, sy, color, long_str); // We have found the string, render and mark as rendered if(index != -1) { StringBatch *array = (long_str) ? long_str_array : small_str_array; extern VertexTypeInfo vertex_types[D3DVT_MAX]; d3d_SetVertexShader(FONT_VTYPE); hr = GlobalD3DVars::lpD3DDevice->SetStreamSource( 0, array[index].vbuffer, vertex_types[FONT_VTYPE].size); Assert(SUCCEEDED(hr)); hr = GlobalD3DVars::lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, array[index].char_count * 2); // Assert(SUCCEEDED(hr)); array[index].used_this_frame = true; return; // Prepare to enter the string } else { new_id = find_free_slot(long_str); } } #endif IDirect3DVertexBuffer8 *vbuffer = NULL; FONT_VERTEX *locked_buffer = NULL; StringBatch *array = NULL; if(new_id != -1) { array = (len > MAX_SM_STR_LEN) ? long_str_array : small_str_array; vbuffer = array[new_id].vbuffer; hr = vbuffer->Lock(0, len * 6 * vertex_types[FONT_VTYPE].size, (BYTE **) &locked_buffer, 0); array[new_id].used_this_frame = true; // We can always bail out at this point if(FAILED(hr)) { Assert(0); new_id = -1; } } int char_count = 0; while (*s) { x += spacing; while (*s== '\n' ) { s++; y += Current_font->h; // centered x =(sx==0x8000) ? get_centered_x(s) : sx; } if (*s == 0 ) break; int letter = get_char_width(s[0],s[1],&width,&spacing); s++; //not in font, draw as space if (letter<0) { continue; } int xd, yd, xc, yc; int wc, hc; // Check if this character is totally clipped if ( x + width < gr_screen.clip_left ) continue; if ( y + Current_font->h < gr_screen.clip_top ) continue; if ( x > gr_screen.clip_right ) continue; if ( y > gr_screen.clip_bottom ) continue; xd = yd = 0; if ( x < gr_screen.clip_left ) xd = gr_screen.clip_left - x; if ( y < gr_screen.clip_top ) yd = gr_screen.clip_top - y; xc = x+xd; yc = y+yd; wc = width - xd; hc = Current_font->h - yd; if ( xc + wc > gr_screen.clip_right ) wc = gr_screen.clip_right - xc; if ( yc + hc > gr_screen.clip_bottom ) hc = gr_screen.clip_bottom - yc; if ( wc < 1 ) continue; if ( hc < 1 ) continue; font_char *ch; ch = &Current_font->char_data[letter]; int u = Current_font->bm_u[letter]; int v = Current_font->bm_v[letter]; if ( wc < 1 ) continue; if ( hc < 1 ) continue; FONT_VERTEX *src_v = NULL; if(new_id != -1) { src_v = &locked_buffer[char_count * 6]; } else { src_v = &d3d_verts[char_count * 6]; } #if 0 // Change the color this way to see which strings are being cached uint color2 = (new_id == -1) ? color : 0xff00ff00; // Marks the end of a batch blue if(char_count > (MAX_STRING_LEN - 10)) color2 = 0xff0000ff; #endif d3d_stuff_char(src_v, xc, yc, wc, hc, u+xd, v+yd, bw, bh, u_scale, v_scale, color); char_count++; if(char_count >= MAX_STRING_LEN) { // We've run out of space, we are going to have to go round again break; } } if(new_id != -1) { vbuffer->Unlock(); if(char_count == 0) { array[new_id].free_slot = true; array[new_id].used_this_frame = false; continue; } hr = d3d_SetVertexShader(FONT_VTYPE); Assert(SUCCEEDED(hr)); hr = GlobalD3DVars::lpD3DDevice->SetStreamSource(0, vbuffer, vertex_types[FONT_VTYPE].size); Assert(SUCCEEDED(hr)); hr = GlobalD3DVars::lpD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, char_count * 2); // Assert(SUCCEEDED(hr)); // Fill in details array[new_id].char_count = char_count; array[new_id].color = color; array[new_id].free_slot = false; array[new_id].len = len; array[new_id].magic_number = magic_num; array[new_id].magic_number2 = magic_num2; array[new_id].x = sx; array[new_id].y = sy; array[new_id].offsetx = gr_screen.offset_x; array[new_id].offsety = gr_screen.offset_y; array[new_id].used_this_frame = true; } else if(char_count > 0) { d3d_DrawPrimitive(FONT_VTYPE, D3DPT_TRIANGLELIST,(LPVOID)d3d_verts, char_count * 6); } } while (*s); }