You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python OpenGL代码时,集成显卡与1050Ti渲染点数组结果不同的原因?

OpenGL渲染点数组在GTX1050Ti与集成显卡表现不一致问题

本人使用华硕TUF FX505G笔记本(搭载集成显卡与GTX1050Ti),用Python 3.10.8编写OpenGL代码渲染点数组时,发现不同显卡渲染结果有差异:GTX1050Ti下渲染不符合预期,集成显卡表现正常。

插电时1050Ti的错误表现
断电时主板显卡的正确表现

以下是相关代码:

Main.py

import glfw
import Shader
from OpenGL.GL import *
from Math_3d import Vector3f


class Window:
    def __init__(self, width: int, height: int, title: str):
        # Exit keyboard flag
        self.exitNow = False

        # Vertex Buffer Object
        # Create point vertex data
        self.v3f = Vector3f.data

        if not glfw.init():
            raise Exception("glfw can not be initialized")

        # OpenGL 4.0 version for shader subroutines and Dynamically uniform expression support
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

        self._win = glfw.create_window(width, height, title, None, None)

        if not self._win:
            glfw.terminate()
            raise Exception("glfw window can not be created")

        glfw.set_window_pos(self._win, 400, 200)
        glfw.make_context_current(self._win)
        # Enable key events
        # glfw.set_input_mode(self._win, glfw.STICKY_KEYS, GL_TRUE)
        # Enable key event callback from keyboard
        # glfw.set_key_callback(self._win, self.onKeyboard)
        self.program = glCreateProgram()
        self.buffer = glGenBuffers(1)

    def initialize(self):
        # Request program and shader slots from the GPU

        vertex = glCreateShader(GL_VERTEX_SHADER)
        fragment = glCreateShader(GL_FRAGMENT_SHADER)

        # Set shader sources
        glShaderSource(vertex, Shader.vertex_code)
        glShaderSource(fragment, Shader.fragment_code)
        # Compile shaders and check that they have compiled
        glCompileShader(vertex)
        glCompileShader(fragment)
        if not glGetShaderiv(vertex, GL_COMPILE_STATUS):
            report_shader = glGetShaderInfoLog(vertex)
            print(report_shader)
            raise RuntimeError("Vertex shader compilation error")

        if not glGetShaderiv(fragment, GL_COMPILE_STATUS):
            report_frag = glGetShaderInfoLog(fragment)
            print(report_frag)
            raise RuntimeError("Fragment shader compilation error")

        # Link shaders to program
        glAttachShader(self.program, vertex)
        glAttachShader(self.program, fragment)
        glLinkProgram(self.program)

        if not glGetProgramiv(self.program, GL_LINK_STATUS):
            print(glGetProgramInfoLog(self.program))
            raise RuntimeError('Linking error')
        # Get rid of shaders
        glDetachShader(self.program, vertex)
        glDetachShader(self.program, fragment)
        # Make default program to run
        glUseProgram(self.program)

        # Request a buffer slot from GPU
        # buffer = glGenBuffers(1)
        # Make this buffer the default one
        glBindBuffer(GL_ARRAY_BUFFER, self.buffer)
        # Vertex Array Buffer
        vao = glGenVertexArrays(1)
        glBindVertexArray(vao)

        loc = glGetAttribLocation(self.program, 'position')
        glEnableVertexAttribArray(loc)
        glVertexAttribPointer(loc, self.v3f.itemsize, GL_FLOAT, False, self.v3f.data.strides[0], None)
        glBufferData(GL_ARRAY_BUFFER, self.v3f.data.nbytes, self.v3f.data, GL_DYNAMIC_DRAW)

    def renderscene(self):
        while not glfw.window_should_close(self._win) and not self.exitNow:
            glClear(GL_COLOR_BUFFER_BIT)
            glPointSize(30)
            glDrawArrays(GL_POINTS, 0, self.v3f.itemsize)

            glfw.swap_buffers(self._win)
            # Do not refresh screen before receiving event
            glfw.wait_events()
        glDisableVertexAttribArray(0)
        glUseProgram(0)
        glfw.terminate()


if __name__ == '__main__':
    win = Window(1024, 768, "GLFW Window - Rotate glPoints")
    win.initialize()  # Create and initialize shaders and initialize Vertex Buffer Object
    win.renderscene()  # Swap buffer and render scene

Shader.py

vertex_code = """
    attribute vec3 position;
    void main()
    {
        gl_Position = vec4(position, 1.0);
    }   
    """

fragment_code = """
    void main() 
    { 
        gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0); 
    }
    """

Math_3d.py

from OpenGL.GL import *
import numpy as np
np.set_printoptions(precision=3, suppress=True)


class Vector3f:
    data = np.array([[0.5, 0.5, 0],
                    [-0.5, 0.5, 0],
                    [-0.5, -0.5, 0],
                    [0.5, -0.5, 0]], dtype=np.float32)

    def Rotate(self):
        pass

if __name__ == '__main__':
    vec3 = Vector3f
    print(vec3.data)
    print("Item size: ", vec3.data.itemsize)
    print("Strides: ", vec3.data.strides[0])
    print("Bytes:", vec3.data.nbytes)

本人在两种显卡环境下都运行了代码,认为不存在明显的缓冲区溢出问题。


问题原因与修复方案

代码存在两个关键错误,这是导致显卡表现差异的核心原因:

  1. glVertexAttribPointer参数错误
    该函数第二个参数是顶点属性的分量数,你传入的self.v3f.itemsize是单个float32元素的字节数(4),但你的顶点是vec3类型,正确值应为3。

  2. glDrawArrays顶点数量参数错误
    该函数第三个参数是要渲染的顶点总数,你用了self.v3f.itemsize(数值碰巧为4),但逻辑上应该用数组的行数self.v3f.shape[0]来表示顶点数量,避免后续数组修改时出现错误。

修正后的关键代码片段:

在initialize方法中:

# 修正顶点属性分量数为3,对应vec3类型
glVertexAttribPointer(loc, 3, GL_FLOAT, False, self.v3f.data.strides[0], None)

在renderscene方法中:

# 用数组行数作为顶点数量,逻辑更准确
glDrawArrays(GL_POINTS, 0, self.v3f.shape[0])

不同显卡对错误参数的容错性不同:集成显卡可能自动兼容了错误参数,而GTX1050Ti严格按照参数解析数据,导致顶点数据读取异常,最终渲染出错误结果。


内容的提问来源于stack exchange,提问作者Treslav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:15:34