我有一个名为DrawImage
的绘图函数,但它确实令人困惑,只能使用特殊forms的重塑函数,因此我有两个问题:
function如下:
void DrawImage(char filename, int xx, int yy, int ww, int hh, int angle) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, filename); glLoadIdentity(); glTranslatef(xx,yy,0.0); glRotatef(angle,0.0,0.0,1.0); glTranslatef(-xx,-yy,0.0); // Draw a textured quad glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(xx,yy); glTexCoord2f(0, 1); glVertex2f(xx,yy + hh); glTexCoord2f(1, 1); glVertex2f(xx + ww,yy + hh); glTexCoord2f(1, 0); glVertex2f(xx + ww,yy); glDisable(GL_TEXTURE_2D); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glEnd(); }
有人告诉我你不能在glBegin
和glEnd
之间调用glDisable
, glPopMatrix
或glMatrixMode
。 问题是 – 没有它,代码将无法运行。 知道如何让它没有它吗? 2.关于glutReshapeFunc,文档说它获得了一个指向具有2个args,width和height的函数的指针 – 我创建(到现在为止)一个无效的函数 – 任何想法如何编写一个获得宽度的重塑函数高度,实际上做重塑需要做的事情。
还有一个小问题:在涉及像OpenGL这样的GUI时,C ++比C更好? 正如我所看到的,只有OOP是问题而我没有遇到OOP可以解决的任何问题而且C不能(我在OpenGL中的意思)。
无需回答所有问题 – 问题1对我来说基本上是最重要的:P
那么,投影矩阵……
要在2D屏幕上以3Dforms绘制内容,您可以将3D点“投影”到平面上。 我相信你看过这样的图像:
这允许您定义任意3D坐标系。 除了在2D中绘制东西之外,它自然希望直接使用像素坐标。 毕竟这是你监控显示的内容。 因此,您希望使用一种旁路投影,它不进行任何透视缩放,并匹配比例和宽高比中的像素。
默认投影(或“查看体积”)是正交-1到一个立方体。 改变它,
glMatrixMode(GL_PROJECTION); //from now on all glOrtho, glTranslate etc affect projection glOrtho(0, widthInPixels, 0, heightInPixels, -1, 1); glMatrixMode(GL_MODELVIEW); //good to leave in edit-modelview mode
实际上在任何地方调用它,但由于唯一影响的变量是窗口宽度/高度,将它放在一些初始化代码中是正常的,或者,如果您计划调整窗口大小,则resize事件处理程序,例如:
void reshape(int x, int y) {... do stuff with x/y ...} ... glutReshapeFunc(reshape); //give glut the callback
这将使屏幕的左下角成为原点,传递给glVertex
值现在可以以像素为单位。
还有一些事情:而不是glTranslatef(-xx,-yy,0.0);
你可以在之后使用glVertex2f(0,0)
。 推/弹矩阵应始终在函数内配对,因此不希望调用者匹配它。
我将以一个完整的例子结束:
#include #include #include int main(int argc, char** argv) { //create GL context glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(800, 600); glutCreateWindow("windowname"); //create test checker image unsigned char texDat[64]; for (int i = 0; i < 64; ++i) texDat[i] = ((i + (i / 8)) % 2) * 128 + 127; //upload to GPU texture GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 8, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texDat); glBindTexture(GL_TEXTURE_2D, 0); //match projection to window resolution (could be in reshape callback) glMatrixMode(GL_PROJECTION); glOrtho(0, 800, 0, 600, -1, 1); glMatrixMode(GL_MODELVIEW); //clear and draw quad with texture (could be in display callback) glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, tex); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2i(0, 0); glVertex2i(100, 100); glTexCoord2i(0, 1); glVertex2i(100, 500); glTexCoord2i(1, 1); glVertex2i(500, 500); glTexCoord2i(1, 0); glVertex2i(500, 100); glEnd(); glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); glFlush(); //don't need this with GLUT_DOUBLE and glutSwapBuffers getchar(); //pause so you can see what just happened //System("pause"); //I think this works on windows return 0; }
如果您使用OpenGL 3.0或更高版本,绘制纹理的更简单方法是glBlitFramebuffer()
。 它不支持旋转,只是将纹理复制到帧缓冲区中的矩形,包括必要时缩放。
我没有测试过这段代码,但它看起来像这样, tex
是你的纹理id:
GLuint readFboId = 0; glGenFramebuffers(1, &readFboId); glBindFramebuffer(GL_READ_FRAMEBUFFER, readFboId); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); glBlitFramebuffer(0, 0, texWidth, texHeight, 0, 0, winWidth, winHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &readFboId);
如果要重复绘制纹理,您当然可以重复使用相同的FBO。 我只在这里创建/销毁它以使代码自包含。
以上就是c/c++开发分享在OpenGL中绘制2D纹理相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562640.html