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/growing_array_example.c"
|
||||||
// #include "oogabooga/examples/input_example.c"
|
// #include "oogabooga/examples/input_example.c"
|
||||||
|
|
||||||
|
// #include "oogabooga/examples/sanity_tests.c"
|
||||||
|
|
||||||
// This is where you swap in your own project!
|
// This is where you swap in your own project!
|
||||||
// #include "entry_yourepicgamename.c"
|
// #include "entry_yourepicgamename.c"
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
- Reworked window initialization
|
- Reworked window initialization
|
||||||
Window now starts of invisible and is made visible on first os_update().
|
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.
|
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
|
## v0.01.004 - Gamepad input, text wrapping, bug fixes
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
|
||||||
int entry(int argc, char **argv) {
|
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.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_width = 1280; // We need to set the scaled size if we want to handle system scaling (DPI)
|
||||||
window.scaled_height = 720;
|
window.scaled_height = 720;
|
||||||
|
@ -8,6 +13,7 @@ int entry(int argc, char **argv) {
|
||||||
window.y = 90;
|
window.y = 90;
|
||||||
window.clear_color = hex_to_rgba(0x6495EDff);
|
window.clear_color = hex_to_rgba(0x6495EDff);
|
||||||
window.allow_resize = true;
|
window.allow_resize = true;
|
||||||
|
window.fullscreen = false;
|
||||||
|
|
||||||
float64 last_time = os_get_elapsed_seconds();
|
float64 last_time = os_get_elapsed_seconds();
|
||||||
while (!window.should_close) {
|
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.Height = image->height;
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
|
// #Hdr
|
||||||
switch (image->channels) {
|
switch (image->channels) {
|
||||||
case 1: desc.Format = DXGI_FORMAT_R8_UNORM; break;
|
case 1: desc.Format = DXGI_FORMAT_R8_UNORM; break;
|
||||||
case 2: desc.Format = DXGI_FORMAT_R8G8_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);
|
D3D11_SUBRESOURCE_DATA data_desc = ZERO(D3D11_SUBRESOURCE_DATA);
|
||||||
data_desc.pSysMem = data;
|
data_desc.pSysMem = data;
|
||||||
data_desc.SysMemPitch = image->width * image->channels;
|
data_desc.SysMemPitch = image->width * image->channels; // #Hdr
|
||||||
|
|
||||||
ID3D11Texture2D* texture = 0;
|
ID3D11Texture2D* texture = 0;
|
||||||
HRESULT hr = ID3D11Device_CreateTexture2D(d3d11_device, &desc, &data_desc, &texture);
|
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);
|
HRESULT hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void**)&texture);
|
||||||
assert(SUCCEEDED(hr), "Expected gfx resource to be a texture but it wasn't");
|
assert(SUCCEEDED(hr), "Expected gfx resource to be a texture but it wasn't");
|
||||||
|
|
||||||
D3D11_BOX destBox;
|
D3D11_BOX region;
|
||||||
destBox.left = x;
|
region.left = x;
|
||||||
destBox.right = x + w;
|
region.right = x + w;
|
||||||
destBox.top = y;
|
region.top = y;
|
||||||
destBox.bottom = y + h;
|
region.bottom = y + h;
|
||||||
destBox.front = 0;
|
region.front = 0;
|
||||||
destBox.back = 1;
|
region.back = 1;
|
||||||
|
|
||||||
|
// #Hdr
|
||||||
// #Incomplete bit-width 8 assumed
|
// #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) {
|
void gfx_deinit_image(Gfx_Image *image) {
|
||||||
ID3D11ShaderResourceView *view = image->gfx_handle;
|
ID3D11ShaderResourceView *view = image->gfx_handle;
|
||||||
|
@ -952,6 +1009,8 @@ void gfx_deinit_image(Gfx_Image *image) {
|
||||||
} else {
|
} else {
|
||||||
panic("Unhandled D3D11 resource deletion");
|
panic("Unhandled D3D11 resource deletion");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ID3D11Resource_Release(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -50,6 +50,8 @@ gfx_init_image(Gfx_Image *image, void *data);
|
||||||
ogb_instance void
|
ogb_instance void
|
||||||
gfx_set_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *data);
|
gfx_set_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *data);
|
||||||
ogb_instance void
|
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);
|
gfx_deinit_image(Gfx_Image *image);
|
||||||
|
|
||||||
ogb_instance void
|
ogb_instance void
|
||||||
|
|
Reference in a new issue