如何使用OpenGL和DevIL获取用户绘制像素

时间:2013-06-11 17:42:51

标签: opengl textures devil

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

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

2 个答案:

答案 0 :(得分:0)

首先请注意,很多代码都已弃用。但仅从代码片段中理解它更容易。我不是为你做的一切,但我希望通过提供基本的工作流程来帮助你。

要获得您想要的结果,您需要做一些事情 首先,您必须在视频内存中加载纹理。这完成了:

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);

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

答案 1 :(得分:0)

我假设你正在研究普通的2D应用程序 我们的想法是,如果性能不是您的关注,您可以考虑通过粗略地操纵像素数据并使用您选择的图形库绘制图像来完成软件中的所有操作。我推荐Simple Directmedia Layer库。它还有一个名为SDL_image的子库,可以加载各种各样的格式 像这样的方法一直有效,直到你搞乱大/多纹理。如果您需要GPU马力来实现实时帧率,那么您必须通过FrameBuffer对象进行战斗,但要注意!这基本上意味着“尽你所能 - 你可以在像素着色器内”并尽可能多地限制你可以调用glReadPixels / glTexImage2D& co。