Drawing an image or even better an opengl view in IMGUI window #497

Closed
opened 2016-01-20 21:02:50 +00:00 by nikmes · 15 comments
nikmes commented 2016-01-20 21:02:50 +00:00 (Migrated from github.com)

Hi,
I am facing the following issue. I use ImGui::Image to draw in a window a bitmap (sprite) that i can scale and rotate in my home game editor.
image
My problem is that i can not rotate the Image in the preview window or I am not sure how i can do it so the preview window reflects the actual bitmap I am modifying. The reason i need this is cause when u manipulate properties of the bitmap used for drawing the bitmap is not displayed somewhere so for the user to see in real time the changes.

Regards

Hi, I am facing the following issue. I use ImGui::Image to draw in a window a bitmap (sprite) that i can scale and rotate in my home game editor. ![image](https://cloud.githubusercontent.com/assets/2520168/12462952/bb33e1dc-bfc9-11e5-9c31-d7392327f4d8.png) My problem is that i can not rotate the Image in the preview window or I am not sure how i can do it so the preview window reflects the actual bitmap I am modifying. The reason i need this is cause when u manipulate properties of the bitmap used for drawing the bitmap is not displayed somewhere so for the user to see in real time the changes. Regards
ocornut commented 2016-01-20 21:13:15 +00:00 (Migrated from github.com)

Rotate the 4 corner points, then call draw_list->PrimQuadUV() or add the triangles/indices yourself.

Are you doing something involving Wonder Boy?

Rotate the 4 corner points, then call draw_list->PrimQuadUV() or add the triangles/indices yourself. Are you doing something involving Wonder Boy?
nikmes commented 2016-01-20 21:31:28 +00:00 (Migrated from github.com)

:) the truth is I want to make my own version of Wonder Boy. I start building simple opengl engine to handle 2D and i ended up building a 2D Game Builder tool (https://youtu.be/3aSHfHRLrpQ). Hopefully it will allow me once i finish to make my own version of Wonder Boy (fast-paced but with RPG elements like Wonder Boy in Monster Land). I am just using graphics from internet.. for the moment to test my 2D Game Builder. Amazing work you doing with ImGui by the way!

Not sure i understood how to rotate the 4 corner points.
I do something like below to display the graphics:

 void SpritePropertiesWindow::run(bool* opened)
 {
    ImVec2 uv0; 
    ImVec2 uv1;

    ImGui::Begin(this->m_name.c_str(), opened, ImVec2(0, 0), 1.0f, ImGuiWindowFlags_AlwaysAutoResize);
    {
        Sprite *currentSprite = ServiceLocator::getGridService()->getCurrentSprite();

        g2dTexture *tex = ServiceLocator::getTextureService()->GetTexture(ServiceLocator::getLevelService()->getCurrentLayer()->getSpriteBatch()->m_textureFileName);

        uv0 = ImVec2(currentSprite->cX / (float)tex->w, currentSprite->cY / (float)tex->h);
        uv1 = ImVec2((currentSprite->cX + currentSprite->cW) / (float)tex->w, (currentSprite->cY + currentSprite->cH) / (float)tex->h);

        ImGui::Image((ImTextureID*)tex->id, ImVec2(currentSprite->sW, currentSprite->sH), uv0, uv1, ImColor(255, 255, 255, 55));

    }

    ImGui::End();
}
:) the truth is I want to make my own version of Wonder Boy. I start building simple opengl engine to handle 2D and i ended up building a 2D Game Builder tool (https://youtu.be/3aSHfHRLrpQ). Hopefully it will allow me once i finish to make my own version of Wonder Boy (fast-paced but with RPG elements like Wonder Boy in Monster Land). I am just using graphics from internet.. for the moment to test my 2D Game Builder. Amazing work you doing with ImGui by the way! Not sure i understood how to rotate the 4 corner points. I do something like below to display the graphics: ``` void SpritePropertiesWindow::run(bool* opened) { ImVec2 uv0; ImVec2 uv1; ImGui::Begin(this->m_name.c_str(), opened, ImVec2(0, 0), 1.0f, ImGuiWindowFlags_AlwaysAutoResize); { Sprite *currentSprite = ServiceLocator::getGridService()->getCurrentSprite(); g2dTexture *tex = ServiceLocator::getTextureService()->GetTexture(ServiceLocator::getLevelService()->getCurrentLayer()->getSpriteBatch()->m_textureFileName); uv0 = ImVec2(currentSprite->cX / (float)tex->w, currentSprite->cY / (float)tex->h); uv1 = ImVec2((currentSprite->cX + currentSprite->cW) / (float)tex->w, (currentSprite->cY + currentSprite->cH) / (float)tex->h); ImGui::Image((ImTextureID*)tex->id, ImVec2(currentSprite->sW, currentSprite->sH), uv0, uv1, ImColor(255, 255, 255, 55)); } ImGui::End(); } ```
ocornut commented 2016-01-20 21:43:40 +00:00 (Migrated from github.com)

Instead of calling ImGui::Image() get the draw list and do something like

draw_list->PushTextureID(tex_id);
draw_list->PrimReserve(6, 4);
draw_list->PrimQuadUV(a, b, c, d, uv_a,uv_b, uv_c, uv_d, col);
draw_list->PopTextureID();

To render an arbitrary quad. Use whatever math you would use (e.g. 2x2 rotation matrix) to rotate the 4 corners a,b,c,d.

I love Monster Land, I have purchased the arcade board a while ago. I am now working on Wonder Boy related project as well :)

Instead of calling ImGui::Image() get the draw list and do something like ``` draw_list->PushTextureID(tex_id); draw_list->PrimReserve(6, 4); draw_list->PrimQuadUV(a, b, c, d, uv_a,uv_b, uv_c, uv_d, col); draw_list->PopTextureID(); ``` To render an arbitrary quad. Use whatever math you would use (e.g. 2x2 rotation matrix) to rotate the 4 corners a,b,c,d. I love Monster Land, I have purchased the arcade board a while ago. I am now working on Wonder Boy related project as well :)
nikmes commented 2016-01-20 21:50:30 +00:00 (Migrated from github.com)

:) Just checked your project on https://forums.tigsource.com/index.php?topic=50899
Very interesting :) :) :) I also completed home project Arcade Machine (with real Arcade Monitor) so i can play Wonder Boy games (and much more) the way i used to play them when i was little on CRT monitor with perfect frame rate and super smooth scrolling. Thanks for the help.

:) Just checked your project on https://forums.tigsource.com/index.php?topic=50899 Very interesting :) :) :) I also completed home project Arcade Machine (with real Arcade Monitor) so i can play Wonder Boy games (and much more) the way i used to play them when i was little on CRT monitor with perfect frame rate and super smooth scrolling. Thanks for the help.
ocornut commented 2016-01-21 10:02:01 +00:00 (Migrated from github.com)

Closing this for now.
Hope to be announcing our game more formally soon :)

Closing this for now. Hope to be announcing our game more formally soon :)
nikmes commented 2016-01-21 10:39:20 +00:00 (Migrated from github.com)

Good Luck! :) i will have an eye for it :) I am very big fun of old arcade remakes

Good Luck! :) i will have an eye for it :) I am very big fun of old arcade remakes
MrSapps commented 2016-01-21 18:46:40 +00:00 (Migrated from github.com)

@ocornut will your project be hosted here on github?

@ocornut will your project be hosted here on github?
ocornut commented 2016-01-21 18:53:07 +00:00 (Migrated from github.com)

It is already but it is a commercial endeavour and won't be open-sourced or at least not right away. I hope to release some tools screenshot or code pertinent to ImGui.

It is already but it is a commercial endeavour and won't be open-sourced or at least not right away. I hope to release some tools screenshot or code pertinent to ImGui.
Jaydee2190 commented 2016-01-26 16:07:30 +00:00 (Migrated from github.com)

Hi, just discovered the library and am loving it. I ran into the same issue as nikmes, and ended up writing my own little helper, but it'd be great if there was an Image function that allowed all four uv co-ordinates. (And then used PrimQuadUV)
Cheers!

Hi, just discovered the library and am loving it. I ran into the same issue as nikmes, and ended up writing my own little helper, but it'd be great if there was an Image function that allowed all four uv co-ordinates. (And then used PrimQuadUV) Cheers!
ocornut commented 2016-01-26 16:55:45 +00:00 (Migrated from github.com)

Hello and welcome!
Out of curiosity, did you get stuck figuring out what approach to use? Using ImDrawList is pretty common if you start doing visual stuff.

Using 4 uv coordinates is fairly rare (rarer than needing 4 positions instead of 2). We could in theory add a helper variant of ImGui::Image() that took an angle and scale, maybe a rotation center.
However I imagine it would be rather awkward in term of layout (in term of using the axis-aligned bounding box from the rotated image as the aabb used for layout), you'd practically want to set the cursor position before and maybe after calling ImGui::Image().

I would suggest instead:

  • Adding an helper in ImDrawList that can handle rotation for you, positions explicitely passed, no aabb or layout involved.
  • Add comment around the Image() function to suggest the user to look at lower-level ImDrawList equivalent.

Do you think it would improve the situation?

Sent from my fax machine

Hi, just discovered the library and am loving it. I ran into the same issue as nikmes, and ended up writing my own little helper, but it'd be great if there was an Image function that allowed all four uv co-ordinates. (And then used PrimQuadUV)
Cheers!

―
Reply to this email directly or view it on GitHub.

Hello and welcome! Out of curiosity, did you get stuck figuring out what approach to use? Using ImDrawList is pretty common if you start doing visual stuff. Using 4 uv coordinates is fairly rare (rarer than needing 4 positions instead of 2). We could in theory add a helper variant of ImGui::Image() that took an angle and scale, maybe a rotation center. However I imagine it would be rather awkward in term of layout (in term of using the axis-aligned bounding box from the rotated image as the aabb used for layout), you'd practically want to set the cursor position before and maybe after calling ImGui::Image(). I would suggest instead: - Adding an helper in ImDrawList that can handle rotation for you, positions explicitely passed, no aabb or layout involved. - Add comment around the Image() function to suggest the user to look at lower-level ImDrawList equivalent. Do you think it would improve the situation? Sent from my fax machine > Hi, just discovered the library and am loving it. I ran into the same issue as nikmes, and ended up writing my own little helper, but it'd be great if there was an Image function that allowed all four uv co-ordinates. (And then used PrimQuadUV) > Cheers! > > ― > Reply to this email directly or view it on GitHub.
Jaydee2190 commented 2016-01-26 18:32:45 +00:00 (Migrated from github.com)

I love the first suggestion! I'm going to dive into the drawlists now. I don't know why I needed all four, graphics isn't really my forte(audio is...), I just found it easy for me to say here are the four points in clockwise order! Tnx again for a great library. EDIT - Just remembered, I did end up using a drawlist..(which I lifted for the most part from the default Image) Here is my hacky approach.

const ImVec2 p = ImGui::GetCursorScreenPos();
ImGui::Dummy(size); // create space for it
ImVec2 a(p.x,p.y); // topLeft
ImVec2 c(p.x+size.x,p.y+size.y); // bottom right
ImVec2 b(c.x, a.y); // topRight
ImVec2 d(a.x, c.y); // bottomLeft // CW order
ImVec2 uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y);

ImDrawList * drawList=ImGui::GetWindowDrawList();
const bool push_texture_id = drawList->_TextureIdStack.empty() || user_texture_id != drawList->_TextureIdStack.back();
if (push_texture_id)
    drawList->PushTextureID(user_texture_id);
drawList->PrimReserve(6,4);

//  ImGui::GetColorU32(tint_col)
drawList->PrimQuadUV(a,b,c,d,uv_b,uv_c,uv_d,uv_a, 0xFFFFFFFF);

if (push_texture_id)
    drawList->PopTextureID();
I love the first suggestion! I'm going to dive into the drawlists now. I don't know why I needed all four, graphics isn't really my forte(audio is...), I just found it easy for me to say here are the four points in clockwise order! Tnx again for a great library. EDIT - Just remembered, I did end up using a drawlist..(which I lifted for the most part from the default Image) Here is my hacky approach. ``` const ImVec2 p = ImGui::GetCursorScreenPos(); ImGui::Dummy(size); // create space for it ImVec2 a(p.x,p.y); // topLeft ImVec2 c(p.x+size.x,p.y+size.y); // bottom right ImVec2 b(c.x, a.y); // topRight ImVec2 d(a.x, c.y); // bottomLeft // CW order ImVec2 uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y); ImDrawList * drawList=ImGui::GetWindowDrawList(); const bool push_texture_id = drawList->_TextureIdStack.empty() || user_texture_id != drawList->_TextureIdStack.back(); if (push_texture_id) drawList->PushTextureID(user_texture_id); drawList->PrimReserve(6,4); // ImGui::GetColorU32(tint_col) drawList->PrimQuadUV(a,b,c,d,uv_b,uv_c,uv_d,uv_a, 0xFFFFFFFF); if (push_texture_id) drawList->PopTextureID(); ```
nikmes commented 2016-01-27 10:04:36 +00:00 (Migrated from github.com)

Jaydee2190: The above performs rotation of the image? Is just drawing the image without rotation correct? To be honest i didn't manage yet to draw using drawList and rotate the image.

Jaydee2190: The above performs rotation of the image? Is just drawing the image without rotation correct? To be honest i didn't manage yet to draw using drawList and rotate the image.
nikmes commented 2016-01-27 10:06:01 +00:00 (Migrated from github.com)

ocornut: I like the idea of helper. Just we pass rotation (angles or degrees) and the scale factor and then image is just drawn in window scaled and rotated :)

ocornut: I like the idea of helper. Just we pass rotation (angles or degrees) and the scale factor and then image is just drawn in window scaled and rotated :)
Jaydee2190 commented 2016-01-28 14:40:54 +00:00 (Migrated from github.com)

Hi nikmes, yes it maps rotated(just does the texture mapping). So you pass in your u,v co-ordiantes
0,1(uv_b) 1,1(uv_c)
0,0(uv_a) 1,0(uv_d)

And it'll draw thew starting with b(so if you use a texturepacker like me that rotates 90 degree's CW, this rotates it back)

I have had luck(different problem) with adding a UserCallback before adding the image and in that apply a matrix, then after the image reseting the matrix(another userCallback with a flag in UseCallbackData as to whether to set or reset). Probably better ways of doing it, but that worked for me!

Hi nikmes, yes it maps rotated(just does the texture mapping). So you pass in your u,v co-ordiantes 0,1(uv_b) 1,1(uv_c) 0,0(uv_a) 1,0(uv_d) And it'll draw thew starting with b(so if you use a texturepacker like me that rotates 90 degree's CW, this rotates it back) I have had luck(different problem) with adding a UserCallback before adding the image and in that apply a matrix, then after the image reseting the matrix(another userCallback with a flag in UseCallbackData as to whether to set or reset). Probably better ways of doing it, but that worked for me!
ocornut commented 2016-01-28 14:44:44 +00:00 (Migrated from github.com)

Note that when you start using callbacks and you are breaking the draw-call merging mechanism of ImGui. Each callback will lead to creating a new draw call.

nikmes, I'll post some helper code later, really you only have to apply a 2d rotation matrix to each of the four points.

    x' = x \cos \theta - y \sin \theta\,,
    y' = x \sin \theta + y \cos \theta\,. 

If this is confusing ignore the UV coordinates and draw lines between those 4 points for testing (and remember you can add imgui widget to easily test your code in an interactive manner)

Note that when you start using callbacks and you are breaking the draw-call merging mechanism of ImGui. Each callback will lead to creating a new draw call. nikmes, I'll post some helper code later, really you only have to apply a 2d rotation matrix to each of the four points. ``` x' = x \cos \theta - y \sin \theta\,, y' = x \sin \theta + y \cos \theta\,. ``` If this is confusing ignore the UV coordinates and draw lines between those 4 points for testing (and remember you can add imgui widget to easily test your code in an interactive manner)
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ocornut/imgui#497
No description provided.