【问题标题】:How to use OpenGL and DevIL get user drawing pixels如何使用OpenGL和DevIL获取用户绘制像素
【发布时间】:2013-06-12 06:48:25
【问题描述】:

我需要加载图像,显示图像,并让用户在图像上绘制一些笔触并获取那些绘图像素。

我知道 OpenGL 可以加载 DevIL 读取的纹理图像,并显示它。但我不确定如何使用 OpenGL 从加载的纹理中获取用户绘制像素。

【问题讨论】:

  • 或任何其他比 DevIL 和 OpenGL 更好的库来服务于这个目的?
  • glReadPixels() 不起作用吗?
  • 我知道 glReadPixels 可以读取帧缓冲区并保存。它还可以读取用户绘制笔划时选择的像素,并在原始图像上实时显示红色笔划吗?你有这样的功能的代码sn-p吗?

标签: opengl textures devil


【解决方案1】:

首先,请注意,此代码中有很多已被弃用。但仅从代码 sn-ps 就更容易理解。我不会为您做所有事情,但我希望通过提供基本工作流程来帮助您入门。

您需要做一些事情才能获得所需的结果。
首先,您必须将纹理加载到视频内存中。这是通过以下方式完成的:

glGenTextures(1, texture_id); //generate a texture object
glBindTexture(GL_TEXTURE_2D, texture_id); //bind the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //set filters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //set filters
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, original_image_data); //create the actual texture in video ram

成功后,您可以使用以下方法绘制纹理:

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

//set to ortographic projection
glOrtho(0.0, window_width, 0.0, window_height, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

glLoadIdentity();
glBindTexture(GL_TEXTURE_2D,texture_id);

glBegin(GL_QUADS);
  glTexCoord2f(0, 1); glVertex2f(-1.0f,  1.0f);
  glTexCoord2f(1, 1); glVertex2f( 1.0f,  1.0f);
  glTexCoord2f(1, 0); glVertex2f( 1.0f, -1.0f);
  glTexCoord2f(0, 0); glVertex2f(-1.0f, -1.0f);
glEnd();

glPopMatrix();

glMatrixMode(GL_PROJECTION);
glPopMatrix();

glMatrixMode(GL_MODELVIEW);

接下来您需要做的是捕获用户的鼠标输入。如果您在 Windows 上,您可以使用 windowprocedure 回调并查找 WM_MOUSE 事件。如果您使用库进行窗口管理,那么该库可能会提供键盘和鼠标输入功能。

现在你有了鼠标输入,你应该在每次用户按住按钮移动鼠标时在屏幕上画一条线:

glLineWidth(2.5); 
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
  glVertex2f(mouse_x_start, mouse_y_start);
  glVertex2f(mouse_x_end, mouse_y_end);
glEnd();
glColor3f(1.0, 1.0, 1.0);

当上述所有操作顺利时,您应该会在屏幕上看到您的纹理,如果您按住鼠标按钮并移动鼠标,您应该会看到一条红线。你快到了。最后需要做的是读取像素。你可以像这样使用 glReadPixels() 来做到这一点:

void glReadPixels(0, 0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, new_image_data);

你现在有一个字节数组,上面有用户的笔画。我强烈建议您为此过程编写自己的代码,因为我使用的代码已被弃用,并且只应在针对旧平台时使用。工作流程应该保持不变。我希望这足以让你开始。祝你好运!

【讨论】:

  • 如果我在 Linux 上,什么库提供键盘和鼠标输入功能?像 windowprocedure 回调?
  • 我从未在 Linux 上工作过,所以对此我无话可说。尝试谷歌搜索 linux 消息循环,看看它是否能让你更进一步。
【解决方案2】:

我假设您正在开发一个简单的 2D 应用程序。
这个想法是,如果您不关心性能,您可以考虑在软件中通过粗略地操作像素数据并使用您选择的图形库绘制图像来完成所有操作。我推荐Simple Directmedia Layer 库。它还有一个名为 SDL_image 的子库,可以加载各种格式。
像这样的方法一直有效,直到您弄乱了大/多个纹理。如果您需要 GPU 的能力来获得实时帧速率,那么您必须通过 FrameBuffer 对象努力争取,但要小心!这基本上意味着“你可以在像素着色器内部做所有事情”,并限制尽可能多的调用,例如 glReadPixels/glTexImage2D &co。

【讨论】:

    猜你喜欢
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多