Notes for OpenGL - 3

本文介绍如何使用OpenGL绘制一个简单的四面体,并探讨了视距与对象大小的关系。此外,还详细解释了纹理映射的过程,包括生成、绑定纹理及设置纹理参数等关键步骤。

1. 今天做了一个四面体,并没有处理过锯齿,只是简单的创建了四个三角形(Triangle),这并不难操作,利用以前的框架,再添加上以下代码就可以了~

    注意,之前提过的,如果你的屏幕距离四面体过近的话会导致部分会被屏幕裁剪

(If you were to move it only 6 units into the screen, the cube would appear much larger than the pyramid, and parts of it might get cut off by the sides of the screen. You can play around with this setting, and see how moving the triangles further into the screen makes it appear smaller, and moving it closer makes it appear larger. The reason this happens is perspective. Objects in the distance should appear smaller :) )

   // this is my first tetrahedron

    glLoadIdentity();

glTranslatef( 0.0f, 0.0f, -8.0f );

glRotatef( angle = angle >= 360 ? 2 : angle + 2, 1.0f, 1.0f, 0.0f ); glBegin(GL_TRIANGLES);

{

  glColor3f( 1.0f, 0.0f, 0.0f );

  glVertex3f( 0.0f, 1.0f, 0.0f );

  glVertex3f( 0.0f, -1.0f, 1.0f );

  glVertex3f( 1.0f, 0.0f, 0.0f );

  glColor3f( 0.0f, 1.0f, 0.0f );

  glVertex3f( 0.0f, 1.0f, 0.0f );

  glVertex3f( 0.0f, -1.0f, 1.0f );

  glVertex3f( -1.0f, 0.0f, 0.0f );

  glColor3f( 0.0f, 0.0f, 1.0f );

  glVertex3f( 0.0f, 1.0f, 0.0f );

  glVertex3f( -1.0f, 0.0f, 0.0f );

  glVertex3f( 1.0f, 0.0f, 0.0f );

  glColor3f( 1.0f, 1.0f, 1.0f );

  glVertex3f( 0.0f, -1.0f, 1.0f );

  glVertex3f( -1.0f, 0.0f, 0.0f );

  glVertex3f( 1.0f, 0.0f, 0.0f );

 }

glEnd();

关于立方体的话于此是同理的,我们可以画上六个四边形,就可以了:)

 

2. glGenTextures(GLsizei, GLuint *) : glGenTextures tells OpenGL we want to generate one texture name (increase the number if you load more than one texture).

3. glBindTexture(GLenum, GLuint) : glBindTexture tells OpenGL to bind the named texture to a texture target. 2D textures have both height (on the Y axes) and width (on the X axes). The main function of glBindTexture is to assign a texture name to texture data.

4. glTexImage2D(GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)

target
Specifies the target texture. Must be GL_TEXTURE_2D.

 

level
Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.

 

components
Specifies the number of color components in the texture. Must be 1, 2, 3, or 4.

 

width
Specifies the width of the texture image. Must be 2^n + 2 * (border) for some integer n.

 

height
Specifies the height of the texture image. Must be 2^m + 2 * (border) for some integer m.

 

border
Specifies the width of the border. Must be either 0 or 1.

 

format
Specifies the format of the pixel data. The following symbolic values are accepted: GL_COLOR_INDEXGL_RED,GL_GREENGL_BLUEGL_ALPHAGL_RGBGL_RGBAGL_LUMINANCE, and GL_LUMINANCE_ALPHA.

 

type
Specifies the data type of the pixel data. The following symbolic values are accepted: GL_UNSIGNED_BYTE,GL_BYTEGL_BITMAPGL_UNSIGNED_SHORTGL_SHORTGL_UNSIGNED_INTGL_INT, andGL_FLOAT.

 

pixels
Specifies a pointer to the image data in memory.

5. glTexParameteri(GLenum target, GLenum pname, GLfloat param) :

target
Specifies the target texture, which must be either GL_TEXTURE_1D, or GL_TEXTURE_2D.

 

pname
Specifies the symbolic name of a single-valued texture parameter. pname can be one of the following:GL_TEXTURE_MIN_FILTERGL_TEXTURE_MAG_FILTERGL_TEXTURE_WRAP_S, orGL_TEXTURE_WRAP_T.

 

param
Specifies the value of pname.   GL_LINEAR ,GL_NEAREST : 
Using GL_LINEAR requires alot of work from the processor/video card, so if your system is slow, you might want to use GL_NEAREST. A texture that's filtered with GL_NEAREST will appear blocky when it's stretched. You can also try a combination of both. Make it filter things up close, but not things in the distance.
标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法和创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性和应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法和系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论和技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征和理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型和非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案和实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试和性能评估。4.1测试环境与方法介绍测试环境配置和采用的测试方法。4.2功能测试结果展示各功能模块的测试结果和问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果和技术创新。5.2未来展望指出系统局限性并提出后续优化方向。
import camelot import pdfplumber import json import os import traceback import ctypes import sys import platform import logging # 配置日志记录 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # 解决libGL缺失问题的前置检查 def check_lib_dependencies(): """检查并尝试解决libGL依赖问题""" try: # 尝试加载GL库 ctypes.CDLL("libGL.so.1") logger.info("libGL.so.1 已找到") except OSError as e: # 提供解决方案 if platform.system() == "Linux": error_msg = f"警告: 缺少libGL.so.1库,PDF处理需要此库: {str(e)}" solution = "解决方案: sudo apt-get update && sudo apt-get install libgl1-mesa-glx" logger.error(error_msg) logger.error(solution) # 抛出明确的错误信息 raise RuntimeError(f"{error_msg}\n{solution}") else: logger.warning(f"非Linux系统依赖问题: {str(e)}") raise # 运行依赖检查(确保在导入图形库前执行) try: check_lib_dependencies() except Exception as e: logger.critical(f"关键依赖检查失败: {str(e)}") def handler(event, context=None): """ 插件入口函数,处理所有请求逻辑 event: 包含输入参数的字典 context: 运行时上下文(可选,默认值为None) """ try: # 验证必要参数 required_params = [&#39;file_url_id&#39;, &#39;task_type&#39;, &#39;question&#39;] for param in required_params: if param not in event: error_msg = f"缺少必要参数: {param}" logger.error(error_msg) return { "status": "error", "error": error_msg } # 解析参数 file_url_id = event[&#39;file_url_id&#39;] task_type = event[&#39;task_type&#39;] question = event[&#39;question&#39;] pages = event.get(&#39;pages&#39;, []) language = event.get(&#39;language&#39;, &#39;zh-CN&#39;) # 检查文件是否存在 if not os.path.exists(file_url_id): error_msg = f"文件不存在: {file_url_id}" logger.error(error_msg) return { "status": "error", "error": error_msg } # 根据任务类型执行对应操作 try: logger.info(f"开始处理任务: {task_type} 文件: {file_url_id}") if task_type == &#39;parse_overview&#39;: result = parse_overview(file_url_id) elif task_type == &#39;parse_text&#39;: result = parse_text(file_url_id, pages) elif task_type == &#39;parse_tables&#39;: result = parse_tables(file_url_id, pages) elif task_type == &#39;summarize_drawing&#39;: result = summarize_drawing(file_url_id, language) elif task_type == &#39;extract_rebar&#39;: result = extract_rebar(file_url_id) elif task_type == &#39;extract_components&#39;: result = extract_components(file_url_id, event.get(&#39;target_types&#39;, [])) else: error_msg = f"不支持的任务类型: {task_type}" logger.error(error_msg) return { "status": "error", "error": error_msg } except RuntimeError as e: # 专门处理依赖错误 logger.error(f"运行时依赖错误: {str(e)}") return { "status": "error", "error": str(e), "solution": "请安装libgl1-mesa-glx: sudo apt-get update && sudo apt-get install libgl1-mesa-glx" } except Exception as e: logger.error(f"处理任务时出错: {str(e)}", exc_info=True) # 处理系统依赖错误 if "libGL.so.1" in str(e) or "libGL" in str(e) or "GL" in str(e): return { "status": "error", "error": "系统缺少必要的图形处理库", "solution": "请安装libgl1-mesa-glx: sudo apt-get update && sudo apt-get install libgl1-mesa-glx" } else: raise # 构造成功响应 logger.info(f"任务 {task_type} 处理成功") return { "status": "success", "result": result, "qa_answer": generate_answer(question, result) } except Exception as e: # 捕获并返回错误信息,包含详细堆栈跟踪以便调试 logger.critical(f"处理请求时发生未捕获异常: {str(e)}", exc_info=True) return { "status": "error", "error": str(e), "traceback": traceback.format_exc() } # 辅助函数:生成问题答案 def generate_answer(question, result): return f"针对问题「{question}」的处理结果:{str(result)[:200]}..." # 解析概览信息 def parse_overview(file_url_id): try: logger.info(f"解析文件概览: {file_url_id}") # 设置环境变量以避免GUI依赖 os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1" os.environ["CV_IO_ENABLE_OPENEXR"] = "1" with pdfplumber.open(file_url_id) as pdf: pages_count = len(pdf.pages) first_page = pdf.pages[0] if pages_count > 0 else None # 提取第一页文本内容 first_page_text = "" if first_page: try: first_page_text = first_page.extract_text() or "" except Exception as e: logger.warning(f"提取第一页文本失败: {str(e)}") first_page_text = "" return { "document_id": file_url_id, "pages": pages_count, "page_sizes": [{ "width": first_page.width if first_page else 0, "height": first_page.height if first_page else 0, "unit": "pt" }] if first_page else [], "has_text": bool(first_page_text), "has_tables": False, # 简化处理,实际应检测 "has_vectors": False, # 简化处理,实际应检测 "probable_types": ["结构平面图", "建筑详图"] } except Exception as e: logger.error(f"解析概览失败: {str(e)}", exc_info=True) raise Exception(f"解析概览失败: {str(e)}") # 解析文本 def parse_text(file_url_id, pages): try: logger.info(f"解析文本内容: {file_url_id}, 页数: {pages}") text_blocks = [] # 设置环境变量以避免GUI依赖 os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1" os.environ["CV_IO_ENABLE_OPENEXR"] = "1" with pdfplumber.open(file_url_id) as pdf: # 确定要处理的页面 process_pages = pages if pages else range(len(pdf.pages)) for page_num in process_pages: if 0 <= page_num < len(pdf.pages): page = pdf.pages[page_num] try: text = page.extract_text() or "" except Exception as e: logger.warning(f"提取第 {page_num+1} 页文本失败: {str(e)}") text = "" if text: text_blocks.append({ "page": page_num + 1, # 页码从1开始 "bbox": [0, 0, page.width, page.height], "text": text, "font": "unknown", "size": 12 }) return { "document_id": file_url_id, "items": text_blocks } except Exception as e: logger.error(f"解析文本失败: {str(e)}", exc_info=True) raise Exception(f"解析文本失败: {str(e)}") # 解析表格 def parse_tables(file_url_id, pages): try: logger.info(f"解析表格: {file_url_id}, 页数: {pages}") # 设置环境变量以避免GUI依赖 os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1" os.environ["CV_IO_ENABLE_OPENEXR"] = "1" # 转换为camelot需要的页码格式 pages_str = &#39;,&#39;.join(map(str, [p+1 for p in pages])) if pages else &#39;all&#39; # 尝试使用不同的解析方式 try: logger.info("尝试使用lattice模式解析表格") tables = camelot.read_pdf( file_url_id, pages=pages_str, flavor=&#39;lattice&#39; ) except Exception as e: logger.warning(f"lattice模式失败,尝试stream模式: {str(e)}") try: tables = camelot.read_pdf( file_url_id, pages=pages_str, flavor=&#39;stream&#39; ) except Exception as inner_e: logger.error(f"两种表格解析模式均失败: {str(inner_e)}") raise result_tables = [] for table in tables: cells = [] for i, row in enumerate(table.df.values): for j, cell_text in enumerate(row): cells.append({ "row": i, "col": j, "text": cell_text, "bbox": table._bbox }) result_tables.append({ "page": table.page, "title": f"Table on page {table.page}", "cells": cells }) return { "document_id": file_url_id, "items": result_tables } except Exception as e: logger.error(f"解析表格失败: {str(e)}", exc_info=True) # 处理特定的表格解析错误 if "Ghostscript is not installed" in str(e): error_msg = "未安装Ghostscript,请执行: sudo apt-get install ghostscript" logger.error(error_msg) raise Exception(error_msg) raise Exception(f"解析表格失败: {str(e)}") # 图纸摘要生成(简化版) def summarize_drawing(file_url_id, language): logger.info(f"生成图纸摘要: {file_url_id}, 语言: {language}") overview = parse_overview(file_url_id) return { "document_id": file_url_id, "text_summary": f"该图纸包含{overview[&#39;pages&#39;]}页,可能是{overview[&#39;probable_types&#39;][0]}", "structured": { "drawing_type": overview[&#39;probable_types&#39;][0], "levels": ["一层", "二层"], "grids": ["1-6", "A-D"], "notes": ["混凝土强度等级为C30"] } } # 钢筋信息提取(简化版) def extract_rebar(file_url_id): logger.info(f"提取钢筋信息: {file_url_id}") # 设置环境变量以避免GUI依赖 os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1" os.environ["CV_IO_ENABLE_OPENEXR"] = "1" return { "document_id": file_url_id, "summary": { "total_weight_kg": 1250.5, "total_count": 25 }, "items": [ { "mark": "GJ1", "grade": "HRB400", "diameter": "Φ20", "spacing": "200mm", "length": 6500, "quantity": 10 } ] } # 构件提取(简化版) def extract_components(file_url_id, target_types): logger.info(f"提取构件: {file_url_id}, 目标类型: {target_types}") # 设置环境变量以避免GUI依赖 os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1" os.environ["CV_IO_ENABLE_OPENEXR"] = "1" return { "document_id": file_url_id, "items": [ { "id": "B1", "type": "beam", "grid": "2-3/B-C", "elevation": "+5.400", "size": { "width": 300, "height": 500 }, "rebar_spec": "上部 2Φ20@200, 下部 2Φ18@200" } ] } 将 代码修改,使用pymupsd依赖包,不使用openGL,将修改完的完整代码发给我
08-30
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值