gfx_read_image_data()
This commit is contained in:
parent
9de955c84e
commit
1b200bd162
6 changed files with 149 additions and 9 deletions
2
build.c
2
build.c
|
@ -44,5 +44,7 @@ typedef struct Context_Extra {
|
|||
// #include "oogabooga/examples/growing_array_example.c"
|
||||
// #include "oogabooga/examples/input_example.c"
|
||||
|
||||
// #include "oogabooga/examples/sanity_tests.c"
|
||||
|
||||
// This is where you swap in your own project!
|
||||
// #include "entry_yourepicgamename.c"
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
- Reworked window initialization
|
||||
Window now starts of invisible and is made visible on first os_update().
|
||||
This also gets rid of the weird window resize and reposition at startup.
|
||||
- Renderer
|
||||
- Added gfx_read_image_data() to read pixels from a Gfx_Image*
|
||||
|
||||
|
||||
## v0.01.004 - Gamepad input, text wrapping, bug fixes
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
|
||||
int entry(int argc, char **argv) {
|
||||
|
||||
// This is how we (optionally) configure the window.
|
||||
// You can set this at any point in the runtime and it will
|
||||
// be applied in os_update().
|
||||
// If you don't care, you can ignore all of this as it all
|
||||
// has reasonable default values.
|
||||
window.title = STR("Minimal Game Example");
|
||||
window.scaled_width = 1280; // We need to set the scaled size if we want to handle system scaling (DPI)
|
||||
window.scaled_height = 720;
|
||||
|
@ -8,6 +13,7 @@ int entry(int argc, char **argv) {
|
|||
window.y = 90;
|
||||
window.clear_color = hex_to_rgba(0x6495EDff);
|
||||
window.allow_resize = true;
|
||||
window.fullscreen = false;
|
||||
|
||||
float64 last_time = os_get_elapsed_seconds();
|
||||
while (!window.should_close) {
|
||||
|
|
69
oogabooga/examples/sanity_tests.c
Normal file
69
oogabooga/examples/sanity_tests.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
|
||||
int entry(int argc, char **argv) {
|
||||
|
||||
|
||||
u32 w = 128;
|
||||
u32 h = 128;
|
||||
u32 tile_w = w/4;
|
||||
u32 tile_h = w/4;
|
||||
|
||||
u8 *pixels = (u8*)alloc(get_heap_allocator(), w * h * 4);
|
||||
|
||||
for (u32 y = 0; y < h; y += 1) {
|
||||
for (u32 x = 0; x < w; x += 1) {
|
||||
u32 tile_x = x / tile_w;
|
||||
u32 tile_y = y / tile_h;
|
||||
|
||||
bool is_black_tile = (tile_x % 2 == tile_y % 2);
|
||||
|
||||
for (u32 c = 0; c < 4; c += 1) {
|
||||
if (is_black_tile) {
|
||||
pixels[(y * w + x) * 4 + c] = 127;
|
||||
} else {
|
||||
pixels[(y * w + x) * 4 + c] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gfx_Image *img = make_image(w, h, 4, pixels, get_heap_allocator());
|
||||
|
||||
u8 *read_pixels = (u8*)alloc(get_heap_allocator(), w*h*4);
|
||||
|
||||
gfx_read_image_data(img, 0, 0, w, h, read_pixels);
|
||||
|
||||
gfx_set_image_data(img, 0, 0, w, h, read_pixels);
|
||||
|
||||
assert(memcmp(read_pixels, pixels, w*h*4) == 0);
|
||||
|
||||
float64 last_time = os_get_elapsed_seconds();
|
||||
while (!window.should_close) {
|
||||
reset_temporary_storage();
|
||||
|
||||
float64 now = os_get_elapsed_seconds();
|
||||
if ((int)now != (int)last_time) log("%.2f FPS\n%.2fms", 1.0/(now-last_time), (now-last_time)*1000);
|
||||
last_time = now;
|
||||
|
||||
Matrix4 rect_xform = m4_scalar(1.0);
|
||||
rect_xform = m4_rotate_z(rect_xform, (f32)now);
|
||||
rect_xform = m4_translate(rect_xform, v3(-.25f, -.25f, 0));
|
||||
draw_image_xform(img, rect_xform, v2(.5f, .5f), COLOR_GREEN);
|
||||
|
||||
draw_rect(v2(sin(now), -.8), v2(.5, .25), COLOR_RED);
|
||||
|
||||
float aspect = (f32)window.width/(f32)window.height;
|
||||
float mx = (input_frame.mouse_x/(f32)window.width * 2.0 - 1.0)*aspect;
|
||||
float my = input_frame.mouse_y/(f32)window.height * 2.0 - 1.0;
|
||||
|
||||
draw_line(v2(-.75, -.75), v2(mx, my), 0.005, COLOR_WHITE);
|
||||
|
||||
if (is_key_just_pressed('F')) {
|
||||
window.fullscreen = !window.fullscreen;
|
||||
}
|
||||
|
||||
os_update();
|
||||
gfx_update();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -882,6 +882,7 @@ void gfx_init_image(Gfx_Image *image, void *initial_data) {
|
|||
desc.Height = image->height;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
// #Hdr
|
||||
switch (image->channels) {
|
||||
case 1: desc.Format = DXGI_FORMAT_R8_UNORM; break;
|
||||
case 2: desc.Format = DXGI_FORMAT_R8G8_UNORM; break;
|
||||
|
@ -897,7 +898,7 @@ void gfx_init_image(Gfx_Image *image, void *initial_data) {
|
|||
|
||||
D3D11_SUBRESOURCE_DATA data_desc = ZERO(D3D11_SUBRESOURCE_DATA);
|
||||
data_desc.pSysMem = data;
|
||||
data_desc.SysMemPitch = image->width * image->channels;
|
||||
data_desc.SysMemPitch = image->width * image->channels; // #Hdr
|
||||
|
||||
ID3D11Texture2D* texture = 0;
|
||||
HRESULT hr = ID3D11Device_CreateTexture2D(d3d11_device, &desc, &data_desc, &texture);
|
||||
|
@ -927,16 +928,72 @@ void gfx_set_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *data
|
|||
HRESULT hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void**)&texture);
|
||||
assert(SUCCEEDED(hr), "Expected gfx resource to be a texture but it wasn't");
|
||||
|
||||
D3D11_BOX destBox;
|
||||
destBox.left = x;
|
||||
destBox.right = x + w;
|
||||
destBox.top = y;
|
||||
destBox.bottom = y + h;
|
||||
destBox.front = 0;
|
||||
destBox.back = 1;
|
||||
D3D11_BOX region;
|
||||
region.left = x;
|
||||
region.right = x + w;
|
||||
region.top = y;
|
||||
region.bottom = y + h;
|
||||
region.front = 0;
|
||||
region.back = 1;
|
||||
|
||||
// #Hdr
|
||||
// #Incomplete bit-width 8 assumed
|
||||
ID3D11DeviceContext_UpdateSubresource(d3d11_context, (ID3D11Resource*)texture, 0, &destBox, data, w * image->channels, 0);
|
||||
ID3D11DeviceContext_UpdateSubresource(d3d11_context, (ID3D11Resource*)texture, 0, ®ion, data, w * image->channels, 0);
|
||||
|
||||
ID3D11Resource_Release(resource);
|
||||
}
|
||||
void gfx_read_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *output) {
|
||||
|
||||
D3D11_BOX region;
|
||||
region.left = x;
|
||||
region.right = x + w;
|
||||
region.top = y;
|
||||
region.bottom = y + h;
|
||||
region.front = 0;
|
||||
region.back = 1;
|
||||
|
||||
ID3D11Resource *resource = 0;
|
||||
ID3D11View_GetResource(image->gfx_handle, &resource);
|
||||
|
||||
ID3D11Texture2D *texture = 0;
|
||||
HRESULT hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void**)&texture);
|
||||
d3d11_check_hr(hr);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
texture->lpVtbl->GetDesc(texture, &desc);
|
||||
|
||||
D3D11_TEXTURE2D_DESC staging_desc = desc;
|
||||
staging_desc.Usage = D3D11_USAGE_STAGING;
|
||||
staging_desc.BindFlags = 0;
|
||||
staging_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
staging_desc.MiscFlags = 0;
|
||||
|
||||
ID3D11Texture2D *staging_texture = 0;
|
||||
hr = ID3D11Device_CreateTexture2D(d3d11_device, &staging_desc, 0, &staging_texture);
|
||||
d3d11_check_hr(hr);
|
||||
|
||||
ID3D11DeviceContext_CopySubresourceRegion(
|
||||
d3d11_context,
|
||||
(ID3D11Resource *)staging_texture,
|
||||
0, 0, 0, 0,
|
||||
(ID3D11Resource *)texture, 0,
|
||||
®ion
|
||||
);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_texture;
|
||||
hr = ID3D11DeviceContext_Map(d3d11_context, (ID3D11Resource *)staging_texture, 0, D3D11_MAP_READ, 0, &mapped_texture);
|
||||
d3d11_check_hr(hr);
|
||||
|
||||
// #Hdr
|
||||
assert(mapped_texture.RowPitch == image->width * image->channels, "Unexpected row pitch in d3d11 texture");
|
||||
|
||||
// #Hdr
|
||||
memcpy(output, mapped_texture.pData, image->width*image->height*image->channels);
|
||||
|
||||
ID3D11DeviceContext_Unmap(d3d11_context, (ID3D11Resource *)staging_texture, 0);
|
||||
|
||||
ID3D11Resource_Release(resource);
|
||||
ID3D11Texture2D_Release(staging_texture);
|
||||
}
|
||||
void gfx_deinit_image(Gfx_Image *image) {
|
||||
ID3D11ShaderResourceView *view = image->gfx_handle;
|
||||
|
@ -952,6 +1009,8 @@ void gfx_deinit_image(Gfx_Image *image) {
|
|||
} else {
|
||||
panic("Unhandled D3D11 resource deletion");
|
||||
}
|
||||
|
||||
ID3D11Resource_Release(resource);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -49,6 +49,8 @@ ogb_instance void
|
|||
gfx_init_image(Gfx_Image *image, void *data);
|
||||
ogb_instance void
|
||||
gfx_set_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *data);
|
||||
ogb_instance void
|
||||
gfx_read_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *output);
|
||||
ogb_instance void
|
||||
gfx_deinit_image(Gfx_Image *image);
|
||||
|
||||
|
|
Reference in a new issue