It looks like I can't use glew
library under Windows with wxWidgets 3.2.2.1.
Here is the sample code:
#include <GL/glew.h> // include GLEW header file
#include <GL/gl.h> // OpenGL header file
#include <wx/wx.h>
#include <wx/glcanvas.h>
class MyGLCanvas : public wxGLCanvas
{
public:
MyGLCanvas(wxWindow* parent, wxSize size) :
wxGLCanvas(parent, wxID_ANY, NULL, wxDefaultPosition, size,
wxFULL_REPAINT_ON_RESIZE)
{
m_context = new wxGLContext(this);
SetCurrent(*m_context);
glEnable(GL_DEPTH_TEST);
}
virtual ~MyGLCanvas()
{
delete m_context;
}
private:
void Render()
{
SetCurrent(*m_context);
glViewport(0, 0, GetSize().x, GetSize().y);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Define the vertex positions and colors.
float vertices[] = {
// Front face
-0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
// Back face
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
};
unsigned int indices[] = {
0, 1, 2, // Front
2, 3, 0,
1, 5, 6, // Right
6, 2, 1,
7, 6, 5, // Back
5, 4, 7,
4, 0, 3, // Left
3, 7, 4,
4, 5, 1, // Bottom
1, 0, 4,
3, 2, 6, // Top
6, 7, 3,
};
// Create the vertex buffer.
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create the index buffer.
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Create the vertex array object.
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// Load and compile the shaders.
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\n"
"out vec3 fColor;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" fColor = aColor;\n"
"}\n";
const char* fragmentShaderSource = "#version 330 core\n"
"in vec3 fColor;\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(fColor, 1.0);\n"
"}\n";
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glUseProgram(shaderProgram);
// Render the cube.
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
SwapBuffers();
}
wxGLContext* m_context;
// Event handlers.
void OnPaint(wxPaintEvent& event)
{
Render();
}
void OnSize(wxSizeEvent& event)
{
Refresh();
}
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(MyGLCanvas, wxGLCanvas)
EVT_PAINT(MyGLCanvas::OnPaint)
EVT_SIZE(MyGLCanvas::OnSize)
wxEND_EVENT_TABLE()
class MyFrame : public wxFrame
{
public:
MyFrame()
{
GLenum err = glewInit();
if (GLEW_OK != err) {
//wxLogError("Error: %s\n", glewGetErrorString(err));
printf("Error: %s\n", glewGetErrorString(err));
exit(1);
}
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
MyGLCanvas* canvas = new MyGLCanvas(this, wxSize(512, 512));
sizer->Add(canvas, 1, wxEXPAND);
SetSizer(sizer);
SetMinSize(wxSize(512, 512));
}
};
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
when I run the program, I got the error in the console:
Error: Missing GL version
Anyone knows how to solve this issue? glewInit
can't get initialized correctly.
It looks like the code snippet:
GLenum err = glewInit();
if (GLEW_OK != err) {
//wxLogError("Error: %s\n", glewGetErrorString(err));
printf("Error: %s\n", glewGetErrorString(err));
exit(1);
}
My environment is:
msys2's G++, the wx library and glew
library are both from msys2 prebuild libs(installed by pacman command)
Another issue is that I have to put the header files:
#include <GL/glew.h> // include GLEW header file
#include <GL/gl.h> // OpenGL header file
Before the wx include header files, if I put glew's header file after wx's header file, I will got compiler errors.
Originally posted by @asmwarrior in #22710 (comment)
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
@asmwarrior I don't know why does this error happen, but maybe there is some (other) incompatibility between OpenGL used by wx and by glew? What errors are you getting if you include glew headers after wx?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
GLEW works with the wxGLCanvas fine, since we use it heavily in KiCad on MSW, macOS and GTK.
The first thing that stands out to me is that we have an include of
#ifdef _WIN32
#include <GL/wglew.h>
#endif // _WIN32
in addition to the standard glew.h
include. So maybe that is what is causing the issue.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
Please, to use glew first of all read its docs: https://glew.sourceforge.net/basic.html
There you can find:
++ That you need to include GL/glew.h
before GL/gl.h
(both #define same common things)
++ That you must create and set as current a gl-context before calling glewInit()
++ That you should use glewExperimental
before glewInit()
++ The usage of GLEW_STATIC
or GLEW_BUILD
depending on you add glew.c to your project or buid glew as a dll.
Looking into your code I see:
++ That you create a default wxGLContext at wxGLCanvas ctor. This will give you OGL version <=2.1, but your OGL code (shaders, etc) requires OGL 3.3. Read wx docs for wxGLContext.
++ That you call glewInit()
at frame ctor, before the gl-context is created.
Other comments:
++ Calling SetCurrent()
from wxGLCanvas ctor has no problem in MSW, but it randomly fail in Linux. I prefer to wait until the window has a real size.
++ Most of your Render() code may be called just once, not for every Refresh()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
@asmwarrior I don't know why does this error happen, but maybe there is some (other) incompatibility between OpenGL used by wx and by glew? What errors are you getting if you include glew headers after wx?
If I wrote such include headers:
#include <wx/wx.h>
#include <wx/glcanvas.h>
#include <GL/glew.h>
#include <GL/gl.h>
I will got such errors:
-------------- Build: win_gcc in opengl_cube (compiler: GNU GCC Compiler)---------------
[ 50.0%] g++.exe -Wall -g -IF:/msys2/mingw64/lib/wx/include/msw-unicode-3.2 -IF:/msys2/mingw64/include/wx-3.2 -mthreads -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXMSW__ -DHAVE_W32API_H -D_UNICODE -fmessage-length=0 -pipe -c F:\code\cb_projects_for_wxWidgets\samples\opengl\cube\cube.cpp -o .objs\win_gcc\cube\cube.o
In file included from F:\code\cb_projects_for_wxWidgets\samples\opengl\cube\cube.cpp:5:
F:/msys2/mingw64/include/GL/glew.h:85:2: error: #error gl.h included before glew.h
85 | #error gl.h included before glew.h
| ^~~~~
F:/msys2/mingw64/include/GL/glew.h:1831:94: error: 'GLchar' does not name a type; did you mean 'u_char'?
1831 | typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:1842:148: error: 'GLchar' has not been declared
1842 | typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
| ^~~~~~
F:/msys2/mingw64/include/GL/glew.h:1843:149: error: 'GLchar' has not been declared
1843 | typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
| ^~~~~~
F:/msys2/mingw64/include/GL/glew.h:1845:80: error: 'GLchar' does not name a type; did you mean 'u_char'?
1845 | typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:1846:107: error: 'GLchar' has not been declared
1846 | typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
| ^~~~~~
F:/msys2/mingw64/include/GL/glew.h:1848:105: error: 'GLchar' has not been declared
1848 | typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
| ^~~~~~
F:/msys2/mingw64/include/GL/glew.h:1849:103: error: 'GLchar' has not been declared
1849 | typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
| ^~~~~~
F:/msys2/mingw64/include/GL/glew.h:1851:81: error: 'GLchar' does not name a type; did you mean 'u_char'?
1851 | typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:1861:88: error: 'GLchar' does not name a type; did you mean 'u_char'?
1861 | typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:2182:102: error: 'GLchar' does not name a type; did you mean 'u_char'?
2182 | typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint colorNumber, const GLchar* name);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:2194:82: error: 'GLchar' does not name a type; did you mean 'u_char'?
2194 | typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:2198:163: error: 'GLchar' has not been declared
2198 | typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name);
| ^~~~~~
F:/msys2/mingw64/include/GL/glew.h:2205:102: error: 'GLchar' does not name a type; did you mean 'u_char'?
2205 | typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode);
| ^~~~~~
| u_char
F:/msys2/mingw64/include/GL/glew.h:2379:91: error: 'GLint64' has not been declared
I think the important message here is:
F:/msys2/mingw64/include/GL/glew.h:85:2: error: #error gl.h included before glew.h
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
Please, to use glew first of all read its docs: https://glew.sourceforge.net/basic.html There you can find: ++ That you need to include
GL/glew.h
beforeGL/gl.h
(both #define same common things) ++ That you must create and set as current a gl-context before callingglewInit()
++ That you should useglewExperimental
beforeglewInit()
++ The usage ofGLEW_STATIC
orGLEW_BUILD
depending on you add glew.c to your project or buid glew as a dll.
Hi, thanks for the help. I haven't read that document before.
Looking into your code I see: ++ That you create a default wxGLContext at wxGLCanvas ctor. This will give you OGL version <=2.1, but your OGL code (shaders, etc) requires OGL 3.3. Read wx docs for wxGLContext. ++ That you call
glewInit()
at frame ctor, before the gl-context is created.
Now, I have changed my code to follow your advice, such as this:
class MyGLCanvas : public wxGLCanvas
{
public:
MyGLCanvas(wxWindow* parent, wxSize size) :
wxGLCanvas(parent, wxID_ANY, NULL, wxDefaultPosition, size,
wxFULL_REPAINT_ON_RESIZE)
{
wxGLContextAttrs ctxAttrs;
ctxAttrs.PlatformDefaults().CoreProfile().OGLVersion(3, 2).EndList();
m_context = new wxGLContext(this, NULL, &ctxAttrs);
SetCurrent(*m_context);
glewExperimental=TRUE;
GLenum err = glewInit();
if (GLEW_OK != err) {
//wxLogError("Error: %s\n", glewGetErrorString(err));
printf("Error: %s\n", glewGetErrorString(err));
exit(1);
}
glEnable(GL_DEPTH_TEST);
}
virtual ~MyGLCanvas()
{
delete m_context;
}
Now, I got failed to create a wxGLContext, the error wxWidgets Debug Alert messagebox shows something like below in screen shot:
I don't know why, any ideas?
Other comments: ++ Calling
SetCurrent()
from wxGLCanvas ctor has no problem in MSW, but it randomly fail in Linux. I prefer to wait until the window has a real size. ++ Most of your Render() code may be called just once, not for every Refresh()
OK, thanks for the comments, in-fact, I don't see much resources on the web to tell us how to use wxWidgets and OpenGL, In-fact, my sample code was created and modified from chatGPT. I think people need some basic tutorial and sample code to handle such things.
I see your tutorial here: FAQ: wxWidgets and OpenGL - wxWidgets Discussion Forum, that is a simple tutorial, and I think the wxWidgets community still need some more detailed tutorials about how to use OpenGL(especially the core profile mode).
That's why I got replied to this wx-user mail-list: OpenGL, wxGLCanvas.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
I think the important message here is:
F:/msys2/mingw64/include/GL/glew.h:85:2: error: #error gl.h included before glew.h
Yes, indeed, thanks, this explains this part. So glew.h
has to be included before wx/glcanvas.h
.
As for the failure to create OpenGL, I'm really not sure: wglCreateContext()
is not supposed to fail, and it doesn't even use any attributes, so it can't be due to them. It looks like the creation of wxGLCanvas
itself might have failed, i.e. the window is invalid?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
I think the important message here is:
F:/msys2/mingw64/include/GL/glew.h:85:2: error: #error gl.h included before glew.h
Yes, indeed, thanks, this explains this part. So
glew.h
has to be included beforewx/glcanvas.h
.As for the failure to create OpenGL, I'm really not sure:
wglCreateContext()
is not supposed to fail, and it doesn't even use any attributes, so it can't be due to them. It looks like the creation ofwxGLCanvas
itself might have failed, i.e. the window is invalid?
Hi, vadz, you are my heros. Yes, the window is invalid. In-fact, chatGPT has created a buggy code for constructing the wxFrame, and I just fix the bug, and it's working now, here is the working code and screen shot of the result program:
#include <GL/glew.h>
#include <GL/gl.h>
#include <wx/wx.h>
#include <wx/glcanvas.h>
class MyGLCanvas : public wxGLCanvas
{
public:
MyGLCanvas(wxWindow* parent, wxSize size) :
wxGLCanvas(parent, wxID_ANY, NULL, wxDefaultPosition, size,
wxFULL_REPAINT_ON_RESIZE)
{
wxGLContextAttrs ctxAttrs;
ctxAttrs.PlatformDefaults().CoreProfile().OGLVersion(3, 2).EndList();
m_context = new wxGLContext(this, NULL, &ctxAttrs);
SetCurrent(*m_context);
glewExperimental=TRUE;
GLenum err = glewInit();
if (GLEW_OK != err) {
//wxLogError("Error: %s\n", glewGetErrorString(err));
printf("Error: %s\n", glewGetErrorString(err));
exit(1);
}
glEnable(GL_DEPTH_TEST);
}
virtual ~MyGLCanvas()
{
delete m_context;
}
private:
void Render()
{
SetCurrent(*m_context);
glViewport(0, 0, GetSize().x, GetSize().y);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Define the vertex positions and colors.
float vertices[] = {
// Front face
-0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
// Back face
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
};
unsigned int indices[] = {
0, 1, 2, // Front
2, 3, 0,
1, 5, 6, // Right
6, 2, 1,
7, 6, 5, // Back
5, 4, 7,
4, 0, 3, // Left
3, 7, 4,
4, 5, 1, // Bottom
1, 0, 4,
3, 2, 6, // Top
6, 7, 3,
};
// Create the vertex buffer.
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create the index buffer.
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Create the vertex array object.
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// Load and compile the shaders.
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\n"
"out vec3 fColor;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" fColor = aColor;\n"
"}\n";
const char* fragmentShaderSource = "#version 330 core\n"
"in vec3 fColor;\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(fColor, 1.0);\n"
"}\n";
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glUseProgram(shaderProgram);
// Render the cube.
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
SwapBuffers();
}
wxGLContext* m_context;
// Event handlers.
void OnPaint(wxPaintEvent& event)
{
Render();
}
void OnSize(wxSizeEvent& event)
{
Refresh();
}
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(MyGLCanvas, wxGLCanvas)
EVT_PAINT(MyGLCanvas::OnPaint)
EVT_SIZE(MyGLCanvas::OnSize)
wxEND_EVENT_TABLE()
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style = wxDEFAULT_FRAME_STYLE)
:wxFrame(NULL, wxID_ANY, title, pos, size, style)
{
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
MyGLCanvas* canvas = new MyGLCanvas(this, wxSize(512, 512));
sizer->Add(canvas, 1, wxEXPAND);
SetSizer(sizer);
SetMinSize(wxSize(512, 512));
}
};
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame(_("OpenGL Sample by glew"),
wxDefaultPosition, wxDefaultSize);
frame->Show();
return true;
}
};
Here is the screen shot of the application:
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
I believe this can be closed then, right?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
Closed #23480 as completed.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
Yes, this issue can be closed. I learn a lot from all your comments, thanks!
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.