Comments (23)
If you really need to use opengl 2 backend on the server side then you could try this patch.
from netimgui.
I'm glad to see that adding an API abstraction layer to allow the server to run on other OS, was of interest to someone.
Haven't touched OpenGL in a while, but I can try to take your code and compile with OpenGl on Windows, and see what's happening. I'm mostly relying on the Dear ImGui rendering backend to display content. This will be in the coming weeks.
If you could send me a RenderDoc capture, I could also have a quick look and have a better idea of what's going on.
from netimgui.
I started working with opengl only a few months ago so i didn't know about RenderDoc.
It seams that RenderDoc support opengl from 3.2 up to 4.6 and i need to use opengl 2 😢 .
But i changed my client app and netimgui server to use opengl 3. Client works but the server crashed. It crashed in function HAL_RenderDrawData
on this lines :
{
NetImgui::Internal::ScopedImguiContext scopedCtx(client.mpBGContext);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
The function ImGui_ImplOpenGL3_RenderDrawData
calls ImGui_ImplOpenGL3_GetBackendData
that returns null pointer (because ImGui::GetIO().BackendRendererUserData
is null).
Here is the content of client.mpBGContext
and you can see that all Backend* members are null :
If i comment this two lines the server doesn't crash and the client texture displayed on netimgui server is good. No texture problems like with opengl 2. But as i commented this two lines i don't have the background texture.
I tried to comment this two lines with opengl 2 but nothing changed, the displayed texture is still bad.
from netimgui.
This suggest that some of the Initialization wasn't completely done on your Dear Imgui Context (missing backend configuration). As mentioned, the OS/Graphics support mostly comes directly from the Dear ImGui samples provided, with some tweak (that are annotated).
As a quick tip for your current problem, create your NetImguiServer_App_glfwOpenGl.cpp
from (DearImGuiFolder)\examples\example_glfw_opengl3\main.cpp
, then compare my NetImguiServer_App_win32dx11.cpp
to the original (DearImGuiFolder)\examples\example_win32_directx11\main.cpp
(or just look for the @SAMPLE_EDIT tags in my version of the source file) and apply the changes back to your NetImguiServer_App_glfwOpenGl.cpp
.
from netimgui.
I'm already using the example files from imgui and just added the lines with @SAMPLE_EDIT tag.
I see that in NetImguiServer_App.cpp
the function CreateDrawData
set flags :
pCmdList->Flags = ImDrawListFlags_AllowVtxOffset |
ImDrawListFlags_AntiAliasedLines |
ImDrawListFlags_AntiAliasedFill |
ImDrawListFlags_AntiAliasedLinesUseTex;
The flag ImDrawListFlags_AllowVtxOffset
is only supported with OpenGL 3.2+ as i found in the imgui ImGui_ImplOpenGL3_Init
:
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
if (bd->GlVersion >= 320)
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
#endif
Also i find a note in NetImgui_CmdPackets_DrawFrame.h
about ImguiVert Note: Keep these 4 constants in sync with 'ImguiVS.hlsl'
but i don't have this file. I don't know what it is for and is it important ?
I'm not using shaders but imgui opengl3 banckend initialize one in function ImGui_ImplOpenGL3_CreateDeviceObjects
where ImGui_ImplOpenGL2_CreateDeviceObjects
not.
Does one of these differences could explain why there is problem with opengl2 and none with opengl3 ?
from netimgui.
The flag ImDrawListFlags_AllowVtxOffset is only supported with OpenGL 3.2+ as i found in the imgui
This might be a problem for API that do not support it, I'll look into it and see if it can be gotten around, I do rely on offsets in my rendering... Thanks for finding out about it.
Also i find a note in NetImgui_CmdPackets_DrawFrame.h about ImguiVert Note: Keep these 4 constants in sync with 'ImguiVS.hlsl' but i don't have this file. I don't know what it is for and is it important ?
This was from older NetImguiServer code, when I was using my own vertex shader. I now convert back the vertices back to 'normal' values and use the stock Dear Imgui sample shaders, so this is not a problem.
I'm not using shaders but imgui opengl3 banckend initialize one in function ImGui_ImplOpenGL3_CreateDeviceObjects where ImGui_ImplOpenGL2_CreateDeviceObjects not.
If you are using the Dear Imgui samples code straight, with the few adjustments I tagged in my code, it should work as is. Obviously it is not, so over the coming weeks, when I have some free time, I'll try to also compile the NetImguiServer using the OpenGL2/3 code and see what are the problems for myself (under Windows).
from netimgui.
I managed to compiled with GL3 and run in Windows, but still have to fix some texture issues. I used most of the GL you already made for the HAL interface.
I had a question regarding the GL2 support. Do you really need to have the NetImguiServer run with GL2? Just to be sure, the server doesn't need to be running the same renderer backend than the client code, and I find it surprising that GL3 wouldn't be supported under a regular linux PC distro.
from netimgui.
Ok, I am able to successfully render in GL3.
There's still some things I want to improve before I submit the code, but here's the GL HAL code so far. Let me know if it helps you. It's not very different from the code you wrote, with the addition of deferred texture creation/destruction. Maybe the issues is more tied to the OS, or the version of OpenGL?
//=================================================================================================
// Source file handling renderer specific commands needed by NetImgui server.
// It complement the rendering backend with a few more functionalities.
//=================================================================================================
#include "NetImguiServer_App.h"
#if HAL_API_PLATFORM_GLFW_GL3
#include <array>
#include "NetImguiServer_RemoteClient.h"
#include <imgui_impl_opengl3.h>
#include <GL/glcorearb.h>
#include <GL/gl3w.h>
namespace NetImguiServer { namespace App
{
//=================================================================================================
// 2 Ring buffer to defer texture creation/destruction so that it
// is done on the main thread
//=================================================================================================
struct PendingTextureCreate
{
uint16_t mWidth;
uint16_t mHeight;
NetImgui::eTexFormat mFormat;
uint32_t* mpPixelData;
ServerTexture* mpOutTexture;
};
constexpr uint64_t kPendingCount = 128;
static std::array<PendingTextureCreate,kPendingCount> sPendingCreateTextures;
static std::atomic_uint64_t sPendingCreateReadIndex = 0;
static std::atomic_uint64_t sPendingCreateWriteIndex = 0;
static std::array<ServerTexture*,kPendingCount> sPendingDestroyTextures;
static std::atomic_uint64_t sPendingDestroyReadIndex = 0;
static std::atomic_uint64_t sPendingDestroyWriteIndex = 0;
//=================================================================================================
// HAL RENDER DRAW DATA
// The drawing of remote clients is handled normally by the standard rendering backend,
// but output is redirected to an allocated client texture instead default swapchain
//=================================================================================================
void HAL_RenderDrawData(RemoteClient::Client& client, ImDrawData* pDrawData)
{
if( client.mpHAL_AreaRT )
{
//-----------------------------------------------------------------------------------------
// Destroy all pending textures
//-----------------------------------------------------------------------------------------
while (sPendingDestroyReadIndex < sPendingDestroyWriteIndex) {
ServerTexture* pServerTexture = sPendingDestroyTextures[(sPendingDestroyReadIndex++) % kPendingCount];
GLuint pTexture = static_cast<GLuint>(reinterpret_cast<uint64_t>(pServerTexture));
glDeleteTextures(1, &pTexture);
memset(pServerTexture, 0, sizeof(ServerTexture));
}
//-----------------------------------------------------------------------------------------
// Create all pending textures
//-----------------------------------------------------------------------------------------
GLint last_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); // Save state
while (sPendingCreateReadIndex < sPendingCreateWriteIndex) {
PendingTextureCreate& textureInfo = sPendingCreateTextures[sPendingCreateReadIndex%kPendingCount];
// Release previous texture
if( textureInfo.mpOutTexture->mpHAL_Texture )
{
GLuint pTexture = static_cast<GLuint>(reinterpret_cast<uint64_t>(textureInfo.mpOutTexture->mpHAL_Texture));
glDeleteTextures(1, &pTexture);
memset(textureInfo.mpOutTexture, 0, sizeof(ServerTexture));
}
// Create new texture
GLuint texture = 0u;
glGenTextures(1, &texture);
GLenum error = glGetError();
(void)error;
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureInfo.mWidth, textureInfo.mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureInfo.mpPixelData);
textureInfo.mpOutTexture->mSize[0] = textureInfo.mWidth;
textureInfo.mpOutTexture->mSize[1] = textureInfo.mHeight;
textureInfo.mpOutTexture->mpHAL_Texture = reinterpret_cast<void*>(static_cast<uint64_t>(texture));
NetImgui::Internal::netImguiDeleteSafe(textureInfo.mpPixelData);
++sPendingCreateReadIndex;
}
glBindTexture(GL_TEXTURE_2D, last_texture); // Restore state
//-----------------------------------------------------------------------------------------
// Render the Client and Server content
//-----------------------------------------------------------------------------------------
glBindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(reinterpret_cast<uint64_t>(client.mpHAL_AreaRT)));
glClearColor(client.mBGSettings.mClearColor[0], client.mBGSettings.mClearColor[1], client.mBGSettings.mClearColor[2], client.mBGSettings.mClearColor[3]);
glClear(GL_COLOR_BUFFER_BIT);
{
NetImgui::Internal::ScopedImguiContext scopedCtx(client.mpBGContext);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
if (pDrawData)
{
ImGui_ImplOpenGL3_RenderDrawData(pDrawData);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
//=================================================================================================
// HAL CREATE RENDER TARGET
// Allocate RenderTargetView / TextureView for each connected remote client.
// The drawing of their menu content will be outputed in it, then displayed normally
// inside our own 'NetImGui application' Imgui drawing
//=================================================================================================
bool HAL_CreateRenderTarget(uint16_t Width, uint16_t Height, void*& pOutRT, void*& pOutTexture)
{
HAL_DestroyRenderTarget(pOutRT, pOutTexture);
GLuint pTextureView = 0u;
glGenTextures(1, &pTextureView);
glBindTexture(GL_TEXTURE_2D, pTextureView);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
GLuint pRenderTargetView = 0u;
glGenFramebuffers(1, &pRenderTargetView);
glBindFramebuffer(GL_FRAMEBUFFER, pRenderTargetView);
//Attach 2D texture to this FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pTextureView, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
bool bSuccess = status == GL_FRAMEBUFFER_COMPLETE;
// Unbind resources
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if( bSuccess ){
pOutRT = reinterpret_cast<void*>(static_cast<uint64_t>(pRenderTargetView));
pOutTexture = reinterpret_cast<void*>(static_cast<uint64_t>(pTextureView));
return true;
}
return false;
}
//=================================================================================================
// HAL DESTROY RENDER TARGET
// Free up allocated resources tried to a RenderTarget
//=================================================================================================
void HAL_DestroyRenderTarget(void*& pOutRT, void*& pOutTexture)
{
if(pOutRT)
{
GLuint pRT = static_cast<GLuint>(reinterpret_cast<uint64_t>(pOutRT));
pOutRT = nullptr;
glDeleteFramebuffers(1, &pRT);
}
if(pOutTexture)
{
GLuint pTexture = static_cast<GLuint>(reinterpret_cast<uint64_t>(pOutTexture));
pOutTexture = nullptr;
glDeleteTextures(1, &pTexture);
}
}
//=================================================================================================
// HAL CREATE TEXTURE
// Receive info on a Texture to allocate. At the moment, 'Dear ImGui' default rendering backend
// only support RGBA8 format, so first convert any input format to a RGBA8 that we can use
//=================================================================================================
bool HAL_CreateTexture(uint16_t Width, uint16_t Height, NetImgui::eTexFormat Format, const uint8_t* pPixelData, ServerTexture& OutTexture)
{
HAL_DestroyTexture(OutTexture);
// Convert all incoming textures data to RGBA8
uint32_t* pPixelDataAlloc = NetImgui::Internal::netImguiSizedNew<uint32_t>(Width*Height*4);
if(Format == NetImgui::eTexFormat::kTexFmtA8)
{
for (int i = 0; i < Width * Height; ++i){
pPixelDataAlloc[i] = 0x00FFFFFF | (static_cast<uint32_t>(pPixelData[i])<<24);
}
pPixelData = reinterpret_cast<const uint8_t*>(pPixelDataAlloc);
}
else if (Format == NetImgui::eTexFormat::kTexFmtRGBA8)
{
memcpy(pPixelDataAlloc, pPixelData, Width*Height*4);
}
else
{
// Unsupported format
return false;
}
PendingTextureCreate& textureInfo = sPendingCreateTextures[sPendingCreateWriteIndex%kPendingCount];
textureInfo.mWidth = Width;
textureInfo.mHeight = Height;
textureInfo.mFormat = Format;
textureInfo.mpPixelData = pPixelDataAlloc;
textureInfo.mpOutTexture = &OutTexture;
++sPendingCreateWriteIndex;
return true;
}
//=================================================================================================
// HAL DESTROY TEXTURE
// Free up allocated resources tried to a Texture
//=================================================================================================
void HAL_DestroyTexture(ServerTexture& OutTexture)
{
if( (OutTexture.mpHAL_Texture) &&
(sPendingDestroyWriteIndex - sPendingDestroyReadIndex >= kPendingCount) )
{
sPendingDestroyTextures[(sPendingDestroyWriteIndex++) % kPendingCount] = &OutTexture;
}
}
}} //namespace NetImguiServer { namespace App
#endif // HAL_API_PLATFORM_GLFW_GL3
from netimgui.
When creating my window i request an opengl 2 window to glfw but an opengl 3.1 window is created (i used glGetString(GL_VERSION)
to see the opengl version). That could explain the texture problem (missing backend configuration as you said) but it's strange that the client is correctly rendered using imgui opengl2 backend with opengl 3.1 context.
I have tested your code with opengl 3 and texture is good but i still have a crash when rendering the background, i have to comment this two lines :
{
NetImgui::Internal::ScopedImguiContext scopedCtx(client.mpBGContext);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
client.mpBGContext->IO.BackendRendererUserData
is a null pointer but it is used by the imgui opengl3 backend.
As you suggested, i will use opengl 3 for the server.
from netimgui.
Ah, this might explains it.
Even if you initialize the OpenGL to 3, the Dear ImGui sample code wouldn't know that, and still configure the context backend to 2, creating the incompatibility (in ImGui_ImplGlfw_Init()
and ImGui_ImplOpenGLXX_Init()
coming from imgui_impl_opengl2.cpp
instead of imgui_impl_opengl3.cpp
).
It would make things simpler to use OpenGL3 with vertex support on the Server, I rely on vertex offset being functional, and if they are not, some change to my server code and the Dear ImGui backend shader code would need to be done for things to work properly. (I only create 1 big vertex/index buffer for the entire frame data to render, using offset into it, by each drawcall).
from netimgui.
I have updated the dev branch with OpenGL3 support (under Windows).
You can take a look and use that. The NetImguiServer_HAL_Glfw.cpp
source is missing the Linux implementation, if you're interested in creating a pull request with your Linux changes in it, I'd be happy to take it.
from netimgui.
Thank you!
I have only implemented HAL_GetSocketInfo
and i don't really know how to implement others (especially HAL_ConvertKeyDown
).
GetCommandLineA
is a windows function and i don't know how to correctly replace it. As i don't use NetImguiServer::App::Startup
i simply replaced with an empty string.
Additionnaly some functions (strcpy_s
, sprintf_s
and strncpy_s
) must be replaced or something is missing to compile correctly on linux. I was too lazy to investagate this so i just added macro to call the non "_s" version.
from netimgui.
The GetCommandLineA
is not too important, and I will probably remove it. It's only there for the 'About window', to open the web link to this github webpage.
The NetImguiServer::App::Startup
allows passing the commandline parameters to the initialize the server. It is use to support connecting to a specific client. If you don't need this, can be an empty string.
HAL_ConvertKeyDown
has to convert the Linux keycodes, to Windows keycodes. It is to handle Dear ImGui response to particular special keys, but maybe I should change it to be configured on the HAL OS file instead. For now, should not be too complicated to convert, once you have the Linux Keycodes.
And finally, yeah, I should remove the _s version of string manipulation. I'll try to do that and avoid the warning Windows generates when doing that.
from netimgui.
Hi, I would like to implement server app in linux with glfw + OpenGL 2. If i understood well, at the end you give up and use GL3?
from netimgui.
Yes. At the moment the NetImguiServer application needs support for 'vertex offset' in drawcalls. It would be possible to modify the codebase to support drawing without offset support, but I don't believe it is worth the effort, given how old this APi is. The server application should be running on a modern PC and doesn't care if the client is using an old rendering API (the client actually doesn't even need any rendering backend at all when using NetImgui)
from netimgui.
Rendering on the NetImgui Server without 'Vertex Offset' OR 'Index Offset' requires a few changes in Client::ConvertToImguiDrawData
.
-Always use 32bits indices (instead of 16bits) for the IndexBuffer
-Output 1 IndexBuffer for each drawing command that use a different starting IndexOffset
-Make sure the Indices written to the IndexBuffer take into account the VertexOffset
from netimgui.
If you really need to use opengl 2 backend on the server side then you could try this patch.
Thanks!!! I can compile and run but when i connect a client i see all black...
I apply the patch and obviously include also NetImguiServer_HAL_GL2.cpp as per #20 (comment) and obviously NetImguiServer_App_GlfwGL2.cpp
This is the server app connected to client; server app forward commands to client application because i can blindly interact with it. NetImguiServer build on windows works properly with same client application.
from netimgui.
It looks like the font texture has not been successfully created on the server side.
from netimgui.
The background should be dark grey not totally black. Are you using the NetImguiServer_HAL_GL3.cpp
and replaced ImGui_ImplOpenGL3_*
by ImGui_ImplOpenGL2_*
?
from netimgui.
The background should be dark grey not totally black. Are you using the
NetImguiServer_HAL_GL3.cpp
and replacedImGui_ImplOpenGL3_*
byImGui_ImplOpenGL2_*
?
No, i'm using your NetImguiServer_HAL_opengl2.cpp
as per #20 (comment)
I can't use NetImguiServer_HAL_GL3.cpp
and replace GL3 with GL2, i could not compile the project.
from netimgui.
It looks like the font texture has not been successfully created on the server side.
If you mean Roboto_Medium
font and image background, I removed, but i exclude it's the issue since with GL3 is working properly.
I need GL2 due to the fact that "kiosk stand" systems does not support GL3.
from netimgui.
No, I meant that Dear ImGui creates a texture with all selected font (even if only the default font is used when not adding any) and then we need to create a texture. This is handled in HAL_CreateTexture
. It could be that even the RenderTarget hasn't been created properly by HAL_CreateRenderTarget
(you can test that by trying to clear the RenderTarget another color. But really, a render capture would be needed to debug it further (with renderdoc).
from netimgui.
I'm not so confident, but I will try..
For info both functions are as per #20 (comment) NetImguiServer_HAL_opengl2.cpp
from netimgui.
Related Issues (20)
- Texture callback
- Including assets and multiple dear imgui copies in repository HOT 4
- It crashes due to the balance between thread release and Shutdown() HOT 7
- Server draw lost message when "Use 32-bit vertex indices" HOT 1
- Linux server application HOT 2
- Supporting multiple imgui contexts in the same app HOT 3
- ServerApp 100% crashes when connecting to client on Android HOT 11
- Server app crashes when more than 64 textures are synchonized by network HOT 6
- Server render delegates HOT 3
- Cmake build system HOT 6
- Can netimgui support X86? HOT 8
- Multiple calls of ConnectFromApp results in multiple contextHooks being added HOT 3
- Auto saving .ini settings of imgui HOT 2
- client and server on Linux HOT 6
- Server segfault after client leaves (opengl3) HOT 5
- Usage of SO_REUSEPORT HOT 4
- GLFW texture corruption HOT 7
- Missing texture replace HOT 18
- Supporting websocket HOT 13
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from netimgui.