glew first init in GLX

本文详细介绍了如何使用X11和OpenGL库在Linux环境下创建窗口并进行基本的渲染操作。通过设置X11显示配置、获取帧缓冲配置、创建GL上下文,实现了窗口的创建、OpenGL初始化及事件循环,展示了基础的渲染流程。
#include <cstdlib>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>

#define GLEW_STATIC

#include <GL/glew.h>
#include <GL/glx.h>
// #include <GL/gl.h>
#include <GL/glu.h>

#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <algorithm>
#include <memory.h>
#include <iostream>

Display *display;
int defaultScreen;
GLXFBConfig *fbConfig;
XVisualInfo *visual;
Window root;
Colormap colorMap;

Window createWindow() {
	XSetWindowAttributes swa;
	swa.colormap = colorMap;
	swa.event_mask = ExposureMask | KeyPressMask;
	unsigned long valueMask = CWColormap | CWEventMask;
	auto window = XCreateWindow(display, root, 100, 100, 320, 240, 0, visual->depth, InputOutput, visual->visual,
								valueMask, &swa);
	XMapWindow(display, window);
	XStoreName(display, window, "show me");
	XFlush(display);
	// XSync(display, 0);
	return window;
}

void render() {
	glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

int main() {
	// connect to X Server
	auto displayName = getenv("DISPLAY");
	display = XOpenDisplay(displayName);
	assert(display);

	// get default screen
	defaultScreen = DefaultScreen(display);

	// get frame buffer configurations
	int att[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, True, GLX_DEPTH_SIZE, 16, None};
	int nelements;
	fbConfig = glXChooseFBConfig(display, defaultScreen, att, &nelements);
	assert(fbConfig);

	// get visual
	visual = glXGetVisualFromFBConfig(display, *fbConfig);
	assert(visual);

	// get root window
	root = RootWindow(display, defaultScreen);
	colorMap = XCreateColormap(display, root, visual->visual, AllocNone);

	// create gl context
	auto glContext = glXCreateNewContext(display, *fbConfig, GLX_RGBA_TYPE, 0, GL_TRUE);

	// =================================================================
	// create window

	auto window1 = createWindow();
	glXMakeCurrent(display, window1, glContext);
	GLenum err = glewInit();
	assert(GLEW_OK == err);
	glXMakeCurrent(display, None, 0);
	XDestroyWindow(display, window1);


	auto window = createWindow();

	// init opengl status, or create resources

	// message loop
	for (;;) {


		XEvent event;
		// XNextEvent(app.display, &event);
		if (XCheckMaskEvent(display, ExposureMask | KeyPressMask, &event)) {
			switch (event.type) {
				case Expose:
					break;
				case KeyPress:
					auto keySys = XkbKeycodeToKeysym(display, event.xkey.keycode, 0,
													 event.xkey.state & ShiftMask ? 1 : 0);
					if (keySys == XK_Escape) { goto L_EXIT; }

					// Root::GetInstance()->SetInvalidate();

					break;
			}
		} else {

			if (event.xexpose.window == window) {

				glXMakeCurrent(display, event.xexpose.window, glContext);

				// render
				render();

				// swap buffer
				glXSwapBuffers(display, event.xexpose.window);

			}
			pthread_yield();

		}


	}

	L_EXIT:

	// clear
	XFreeColormap(display, colorMap);
	if (glXGetCurrentDrawable() == window) {
		glXMakeCurrent(display, None, 0);
	}
	XDestroyWindow(display, window);
	XFree(visual);
	XFree(fbConfig);

	if (glXGetCurrentContext() == glContext) {
		glXMakeCurrent(display, None, 0);
	}
	glXDestroyContext(display, glContext);

	// disconnect to X Server
	XCloseDisplay(display);

	return 0;
}
<think> 我们正在处理两个独立的错误:`IndexError: list index out of range` 和 `Passthrough is not supported, GL is disabled, ANGLE is`。下面分别解释并提供解决方案。 ### 1. `IndexError: list index out of range` 这个错误通常发生在尝试访问列表中不存在的索引时。例如,如果列表长度为3,而你试图访问索引3(Python索引从0开始,所以有效索引为0、1、2),就会引发此错误。 **常见原因:** - 列表为空,但尝试访问某个索引。 - 循环或索引计算错误,导致索引超出范围。 - 从外部源(如文件、网络)获取数据,但数据量少于预期。 **解决方案:** #### 步骤1:检查列表长度 在访问列表元素之前,确保索引在有效范围内: ```python my_list = [1, 2, 3] index = 3 if index < len(my_list): value = my_list[index] else: print(f"Index {index} is out of range for list of length {len(my_list)}") ``` #### 步骤2:使用`try-except`块捕获异常 如果无法避免潜在的错误,可以使用异常处理: ```python try: value = my_list[index] except IndexError: print("Index out of range") ``` #### 步骤3:检查循环条件 在循环中,确保索引不会超过列表长度: ```python for i in range(len(my_list)): print(my_list[i]) # 或者更安全的做法是直接遍历元素: for item in my_list: print(item) ``` #### 步骤4:检查数据来源 如果列表来自外部数据,确保数据完整性和预期长度。 **示例:** 假设有以下代码引发错误: ```python def get_element(data, index): return data[index] # 调用时传入超出范围的索引 result = get_element([1, 2], 2) # 索引2不存在,因为列表只有两个元素(索引0和1) ``` 修改为: ```python def get_element(data, index): if index < len(data): return data[index] else: return None # 或者抛出其他自定义异常 ``` ### 2. `Passthrough is not supported, GL is disabled, ANGLE is` 这个错误与图形渲染相关,通常在使用OpenGL的应用程序中出现(如Kivy、Pygame等)。错误表明系统不支持直通(Passthrough)渲染,并且OpenGL被禁用,而ANGLE(一种将OpenGL调用转换为DirectX的兼容层)被启用。这通常发生在Windows系统上,因为某些图形驱动程序或系统配置问题。 **可能原因:** - 系统没有安装合适的显卡驱动。 - 应用程序尝试使用不支持的OpenGL版本。 - 系统环境变量(如`ANGLE`)被设置导致冲突。 **解决方案:** #### 步骤1:更新显卡驱动 访问显卡制造商(如NVIDIA、AMD、Intel)官网下载并安装最新驱动。 #### 步骤2:检查OpenGL支持 使用工具(如GPU Caps Viewer)检查系统支持的OpenGL版本。确保应用程序要求的OpenGL版本在支持范围内。 #### 步骤3:设置环境变量 尝试禁用ANGLE,强制使用原生OpenGL: - 在代码中设置环境变量(在导入任何图形库之前): ```python import os os.environ["KIVY_GL_BACKEND"] = "angle_sdl2" # 或者尝试其他后端,如"sdl2", "glew" ``` 或者,在运行程序前设置环境变量(在命令行中): ```bash set KIVY_GL_BACKEND=angle_sdl2 # Windows export KIVY_GL_BACKEND=angle_sdl2 # Linux/Mac ``` #### 步骤4:降低OpenGL版本要求 如果应用程序要求较高的OpenGL版本,尝试降低版本要求(如从OpenGL 3.0降到2.0)。 #### 步骤5:使用兼容模式 在Windows上,尝试以兼容模式运行程序(右键点击程序,选择“属性”>“兼容性”>选择兼容模式)。 #### 步骤6:检查应用程序日志 查看完整错误日志,确定错误发生的具体位置。有时,错误信息会提供更多线索。 ### 注意事项 - 对于`IndexError`,重点在于代码逻辑的检查和修正。 - 对于OpenGL错误,可能需要系统级调整。 如果上述步骤无法解决OpenGL错误,可能需要考虑更换图形后端或使用软件渲染(如设置`KIVY_GRAPHICS=gl`为`legacy`或`angle_sdl2`等)。 ### 相关问题 1. 如何避免Python中的索引错误? 2. 如何更新显卡驱动以支持OpenGL? 3. 在Kivy中如何切换图形后端? 4. 如何处理Python中的异常? 5. 如何检查系统支持的OpenGL版本? </think> ### 解决 `IndexError: list index out of range` 错误 这个错误表示你尝试访问列表中不存在的索引位置。以下是逐步解决方案: #### 1. **检查列表长度和索引值** ```python my_list = [1, 2, 3] # 错误写法:print(my_list[3]) # 索引范围是0-2 # 正确写法: if len(my_list) > 3: print(my_list[3]) else: print(f"列表长度不足,最大索引是{len(my_list)-1}") ``` #### 2. **循环遍历时的安全写法** ```python # 危险写法(可能越界) for i in range(10): print(my_list[i]) # 安全写法 for i in range(min(10, len(my_list))): print(my_list[i]) ``` #### 3. **使用 try-except 捕获异常** ```python try: value = my_list[index] except IndexError: print(f"错误:索引{index}超出列表范围(0-{len(my_list)-1})") value = None # 设置默认值 ``` #### 4. **常见场景修复** - **文件读取时**:先检查行是否为空 ```python with open("data.txt") as f: lines = f.readlines() if lines: # 确保文件非空 first_line = lines[0] ``` - **数据分割时**:验证分割结果长度 ```python parts = input_str.split(":") if len(parts) > 1: value = parts[1] ``` #### 5. **调试建议** ```python print(f"列表长度: {len(my_list)},尝试访问的索引: {index}") # 添加调试信息 ``` --- ### 解决 `Passthrough is not supported, GL is disabled, ANGLE is` 错误 此错误与图形渲染(OpenGL)相关,常见于Kivy/PyGame等框架。解决方案: #### 1. **强制使用软件渲染** 在代码开头添加环境变量设置: ```python import os os.environ["KIVY_GL_BACKEND"] = "angle_sdl2" # 对于Kivy os.environ["SDL_VIDEODRIVER"] = "dummy" # 对于PyGame ``` #### 2. **禁用GPU加速** ```python # Kivy专用配置 from kivy.config import Config Config.set('graphics', 'multisamples', '0') Config.set('graphics', 'width', '800') Config.set('graphics', 'height', '600') ``` #### 3. **更新图形驱动** 1. 更新显卡驱动程序(NVIDIA/AMD/Intel官网下载) 2. 安装OpenGL兼容库: ```bash # Ubuntu示例 sudo apt install mesa-utils libgl1-mesa-glx ``` #### 4. **虚拟环境特殊处理** - 在Docker中运行时添加`--gpu`参数 - 虚拟机中启用3D加速(VirtualBox/VMWare设置) #### 5. **降级OpenGL版本** 在代码中强制使用旧版OpenGL: ```python # Kivy示例 from kivy.core.window import Window Window.allow_screensaver = True ``` --- ### 错误原因对比表 | 错误类型 | 触发场景 | 核心原因 | |---------|---------|---------| | `IndexError` | 列表/数组操作 | 索引值 ≥ 列表长度 | | `GL/ANGLE错误` | 图形应用启动 | 显卡驱动/OpenGL兼容性问题 | > 提示:两个错误通常需要同时处理,因为3D应用常涉及顶点数据数组操作,可能同时触发两种错误[^1][^3]。 ### 相关问题 1. 如何预防Python中的常见索引错误? 2. 在无GPU的服务器上如何运行OpenGL应用? 3. Kivy图形界面开发的最佳实践有哪些? 4. Python异常处理中`try-except`和`if`校验哪种更好? 5. 如何检测系统支持的OpenGL版本?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值