我需要加载图像,显示图像,并让用户在图像上绘制一些笔触并获取那些绘图像素。
我知道 OpenGL 可以加载 DevIL 读取的纹理图像,并显示它。但我不确定如何使用 OpenGL 从加载的纹理中获取用户绘制像素。
首先,请注意,很多此代码已被弃用。但是仅从代码片段中更容易理解。我不会为您做所有事情,但我希望通过提供基本工作流程来帮助您入门。
您需要做一些事情来获得您正在寻找的结果。
首先,您必须将纹理加载到视频内存中。这是通过以下方式完成的:
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() 来执行此操作,如下所示:
无效 glReadPixels(0, 0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, new_image_data);
你现在有一个字节数组,上面有用户的笔画。我强烈建议您为此过程编写自己的代码,因为我使用的代码已被弃用,并且只应在针对旧平台时使用。工作流程应该保持不变。我希望这足以让你开始。祝你好运!
我假设您正在开发一个普通的 2D 应用程序。
这个想法是,如果您不关心性能,您可以考虑通过粗略地操作像素数据并使用您选择的图形库绘制图像来在软件中完成所有工作。我推荐Simple Directmedia Layer库。它还有一个名为SDL_image的子库,可以加载各种格式。
像这样的方法一直有效,直到您弄乱了大/多个纹理。如果您需要 GPU 的能力来获得实时帧速率,那么您必须通过 FrameBuffer 对象努力争取,但要小心!这基本上意味着“你可以在像素着色器内部做任何事情”,并限制尽可能多的调用,如 glReadPixels/glTexImage2D &co。