关于在学习 opengl 时遇到的 bug:在 glBegin 和 glEnd 中间使用 glLineWidth 的问题

碎碎念

在帮小田 @西瓜啵啵奶昔 改程序的时候遇到的 bug,虽然知道怎么修复,但在网上查不到产生此 bug 的原因,所以记一下,给大家避个雷。感谢好兄弟又帮我长见识(bushi

如果有小伙伴知道为什么会产生这种 bug,请教教我!


bug 复现

一些基础性的代码就不多展示,先放一些用到的函数,比如渲染文字:

void drawString(const char* str) {
	static int isFirstCall = 1;
	static GLuint lists;
	if (isFirstCall) {
		isFirstCall = 0;
		lists = glGenLists(128);
		wglUseFontBitmaps(wglGetCurrentDC(), 0, 128, lists);
	}
	for (; *str != '\0'; ++str) {
		glCallList(lists + *str);
	}
}
void selectFont(int size, int charset, const char* face) {
	HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0, charset, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);
	HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont);
	DeleteObject(hOldFont);
}

还有用于渲染的 display 函数,其中的 display1display2 是两个样例,后文会提及:

void display() {
	glLoadIdentity();
	gluOrtho2D(0, 500, 0, 500);
	glClearColor(1, 1, 1, 1);
	glClear(GL_COLOR_BUFFER_BIT);
	display1();
	//display2();
	glutSwapBuffers();
}

现在开始复现这个 bug,先来看一个正常情况下的代码:

void display1() {
	glColor3f(0, 1, 0);
	glLineWidth(5);
	glBegin(GL_LINES);
		glVertex2f(150, 50);
		glVertex2f(450, 350);
	glEnd();

	glPushMatrix();
		glRasterPos2f(100, 300);
		selectFont(48, DEFAULT_CHARSET, "");
		drawString("Hello World");
	glPopMatrix();
}

在这里插入图片描述

然后是出现 bug 的代码:

void display2() {
	glColor3f(1, 0, 0);
	glLineWidth(50);
	glBegin(GL_LINES);
		glLineWidth(20);
		glVertex2f(100, 50);
		glVertex2f(450, 400);
	glEnd();

	glPushMatrix();
		glRasterPos2f(100, 400);
		selectFont(20, DEFAULT_CHARSET, "");
		drawString("Hello World");
	glPopMatrix();
}

在这里插入图片描述
可以发现,当我在 glBegin()glEnd() 中间设置 glLineWidth() 的时候,这个宽度并不会被应用。这还是可以理解的,但是更奇怪的是,我们的 drawString() 函数也没有生效,如果说状态机模型可以解释第一个问题的话,第二个问题我一直不知道该如何解释,网上也没有相关回答。

当然,这个 bug 还不只如此,如果我们先执行 display2 再执行 display1,那么显而易见,这个 bug 会照常存在,两个 display 函数里的文本都无法显示,线条宽度也没有改变:
在这里插入图片描述
但是神奇的是,如果我们先执行 display1 再执行 display2,那么会是如下状况:
在这里插入图片描述
它被正确执行了!但是这正是它危险,且容易被忽略的地方,因为它只是表面上是正确的,但这个 bug 本质上还是存在的,这可能会引起一些意想不到的问题,而且难以排查。

所以大家一定要避免在 glBegin()glEnd() 中间使用 glLineWidth()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SP FA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值