OpenGL (ES) 图像处理C++
OpenGL (ES) Image Processing C++
我目前正在尝试使用OpenGL ES进行图像处理。我正在尝试做一些基本的图像效果,比如模糊切换色彩空间等。 我想构建最简单的程序来执行以下操作:
- 图像加载
- 图像处理(使用着色器(
- 图像保存
我已经设法构建了以下设置:
- 一个 OpenGL 上下文
- 我想在使用 DevIL 加载时执行效果的图像。 两个着色器
- (一个顶点着色器和一个片段着色器(
我现在只能使用我加载的图像将数据发送到片段着色器。我正在尝试做的是将图像作为sampler2D发送到片段着色器并对其应用处理。
我有多个问题,例如:
- 如果我想做的只是纯 2D 图像处理,我是否需要顶点着色器? 如果我这样做,应该在这个顶点
- 着色器中做什么,因为我根本没有顶点。我应该创建四边形顶点(如 (0,0( (1, 0( (0, 1( (1, 1(( ?如果是这样,为什么?
- 我是否需要使用 VBO(似乎与顶点着色器有关(、FBO 或其他类似的东西? 我
- 不能只将图像加载到纹理中并等待片段着色器在此纹理上执行我想要的所有操作吗?
- 有人可以提供一些简单的"干净"代码来帮助我理解(没有任何花哨的类使理解如此复杂(?
以下是我的片段着色器在简单颜色交换中的样子:
uniform int width;
uniform int height;
uniform sampler2D texture;
void main() {
vec2 texcoord = vec2(gl_FragCoord.x/width, gl_FragCoord.y/height);
vec4 texture_value = texture2D(texture, texcoord);
gl_FragColor = texture_value.bgra;
}
和我的主要.cpp:
int main(int argc, char** argv)
{
if (argc != 4) {
std::cerr << "Usage: " << argv[0] << " <vertex shader path> <fragment shader path> <image path>" << std::endl;
return EXIT_FAILURE;
}
// Get an EGL valid display
EGLDisplay display;
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) {
std::cerr << "Failed to get EGL Display" << std::endl
<< "Error: " << eglGetError() << std::endl;
return EXIT_FAILURE;
}
else {
std::cerr << "Successfully get EGL Display." << std::endl;
}
// Create a connection to the display
int minor, major;
if (eglInitialize(display, &minor, &major) == EGL_FALSE) {
std::cerr << "Failed to initialize EGL Display" << std::endl
<< "Error: " << eglGetError() << std::endl;
eglTerminate(display);
return EXIT_FAILURE;
}
else {
std::cerr << "Successfully intialized display (OpenGL ES version " << minor << "." << major << ")." << std::endl;
}
// OpenGL ES Config are used to specify things like multi sampling, channel size, stencil buffer usage, & more
// See the doc: https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglChooseConfig.xhtml for more informations
EGLConfig config;
EGLint num_configs;
if (!eglChooseConfig(display, configAttribs, &config, 1, &num_configs)) {
std::cerr << "Failed to choose EGL Config" << std::endl
<< "Error: " << eglGetError() << std::endl;
eglTerminate(display);
return EXIT_FAILURE;
}
else {
std::cerr << "Successfully choose OpenGL ES Config ("<< num_configs << ")." << std::endl;
}
// Creating an OpenGL Render Surface with surface attributes defined above.
EGLSurface surface = eglCreatePbufferSurface(display, config, pbufferAttribs);
if (surface == EGL_NO_SURFACE) {
std::cerr << "Failed to create EGL Surface." << std::endl
<< "Error: " << eglGetError() << std::endl;
}
else {
std::cerr << "Successfully created OpenGL ES Surface." << std::endl;
}
eglBindAPI(EGL_OPENGL_API);
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
if (context == EGL_NO_CONTEXT) {
std::cerr << "Failed to create EGL Context." << std::endl
<< "Error: " << eglGetError() << std::endl;
}
else {
std::cerr << "Successfully created OpenGL ES Context." << std::endl;
}
//Bind context to surface
eglMakeCurrent(display, surface, surface, context);
// Create viewport and check if it has been created correctly
glViewport(0, 0, WIDTH, HEIGHT);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
if (viewport[2] != WIDTH || viewport[3] != HEIGHT) {
std::cerr << "Failed to create the viewport. Size does not match (glViewport/glGetIntegerv not working)." << std::endl
<< "OpenGL ES might be faulty!" << std::endl
<< "If you are on Raspberry Pi, you should not updated EGL as it will install fake EGL." << std::endl;
eglTerminate(display);
return EXIT_FAILURE;
}
// Clear buffer and get ready to draw some things
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Create a shader program
GLuint program = load_shaders(std::string(argv[1]), std::string(argv[2]));
if (program == -1)
{
std::cerr << "Failed to create a shader program. See above for more details." << std::endl;
eglTerminate(display);
return EXIT_FAILURE;
}
/* Initialization of DevIL */
if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) {
std::cerr << "Failed to use DevIL: Wrong version." << std::endl;
return EXIT_FAILURE;
}
ilInit();
ILuint image = load_image(argv[3]);
GLuint texId;
glGenTextures(1, &texId); /* Texture name generation */
glBindTexture(GL_TEXTURE_2D, texId); /* Binding of texture name */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */
谢谢。
我是否需要顶点着色器,因为我只想做纯 2D 图像处理?
在 OpenGL ES 2 中必须使用顶点和片段着色器。
如果我这样做,应该在这个顶点着色器中做什么,因为我根本没有顶点。我应该创建四边形顶点(如 (0,0( (1, 0( (0, 1( (1, 1(( ?如果是这样,为什么?
是的。因为这就是OpenGL ES 2的工作方式。否则,您将需要使用诸如计算机着色器(在OpenGL ES 3.1+中支持(或OpenCL之类的东西。
我是否需要使用 VBO(似乎与顶点着色器有关(、FBO 或其他类似的东西?
使用 VBO/IBO 对您来说几乎没有任何区别,因为您只有 4 个顶点和 2 个基元。您可能需要渲染为纹理,具体取决于您的需要。
我不能只将图像加载到纹理中并等待片段着色器在此纹理上执行我想要的所有操作吗?
不。
相关文章:
- Qt中的RGB图像处理
- 有关图像处理应用程序的硬件和软件安全性的建议
- C++灰度图像处理
- CUDA 速度比预期慢 - 图像处理
- 如何将 MATLAB 图像处理库内置函数转换为 MATLAB 编码器代码生成不支持的 C++?
- 矢量化图像处理
- OpenGL (ES) 图像处理C++
- C++:灰度位图标题和实时绘画+opencv图像处理
- 在 Unity 中C++使用后台线程进行图像处理会导致崩溃
- 线程会影响树莓派的图像处理性能吗?
- 低性能 – 补丁匹配.GPU 上的图像处理 (CUDA)
- 如何使用OpENCV解决图像处理摄像头IO延迟
- 从单线程到多线程图像处理
- 如何使用win IoT在Raspberry Pi上的相机中显示视频流以及一些图像处理
- C 图像处理(来自单元格的裁剪图像)
- C++中的二进制图像处理
- 实时图像处理:HSV图像中的噪声(openCV)
- C 图像处理数据块进入数组 /指针
- OPENCV图像处理,向量下标超出范围
- C++图像处理 - 将图像文件读入 2D 数组