Code Monkey home page Code Monkey logo

Comments (23)

A3Wypiok avatar A3Wypiok commented on June 29, 2024 1

If you really need to use opengl 2 backend on the server side then you could try this patch.

from netimgui.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

A3Wypiok avatar A3Wypiok commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

A3Wypiok avatar A3Wypiok commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

Ok, I am able to successfully render in GL3.
image

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.

A3Wypiok avatar A3Wypiok commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

A3Wypiok avatar A3Wypiok commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

ozlb avatar ozlb commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

ozlb avatar ozlb commented on June 29, 2024

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.

image

from netimgui.

sammyfreg avatar sammyfreg commented on June 29, 2024

It looks like the font texture has not been successfully created on the server side.

from netimgui.

A3Wypiok avatar A3Wypiok commented on June 29, 2024

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.

ozlb avatar ozlb commented on June 29, 2024

The background should be dark grey not totally black. Are you using the NetImguiServer_HAL_GL3.cpp and replaced ImGui_ImplOpenGL3_* by ImGui_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.

ozlb avatar ozlb commented on June 29, 2024

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.

sammyfreg avatar sammyfreg commented on June 29, 2024

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.

ozlb avatar ozlb commented on June 29, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.