0

我正在使用这个color_cube_actor.py文件,并且能够在使用我的HTC Vive时运行hello_qt_controllers.py示例,我确实看到了彩色立方体,并且我能够使用 roomscale 四处走动,所以一切都很好。

在此处输入图像描述

我想开始学习如何从 Python 实时更改缓冲区数据。

首先,我删除了 GLSL 程序的许多不必要的部分,并对其进行了修改,以将不露面的顶点渲染为 10 像素的白点。

在此处输入图像描述

尝试从 Python 循环中输入一个值以更改顶点点大小我正在尝试这个示例drawWithoutVBOs(),并根据样式修改了我的项目。

使用一个简单的静态不变变量 ( layout(location = 8) uniform float Size = 10;),我的程序可以工作并生成上面的图像。

但是,如果我使用“可变”变量 ( layout(location = 8) in float Size;),那么 Python 将完全崩溃而不会出现错误。

项目的源代码

#!/bin/env python

# file color_cube_actor.py

from textwrap import dedent
import numpy as np
from OpenGL.arrays import vbo
from OpenGL.GL import *  # @UnusedWildImport # this comment squelches an IDE warning
from OpenGL.GL.shaders import compileShader, compileProgram
from pyqtgraph.opengl.shaders import getShaderProgram


class ColorCubeActor(object):
    """
    Draws a cube

       2________ 3
       /|      /|
     6/_|____7/ |
      | |_____|_|
      | /0    | /1
      |/______|/
      4       5
    """

    def __init__(self):
        self.shader = 0

    def init_gl(self):
        vertex_shader = compileShader(dedent(
            """
            #version 450 core

            layout(location = 0) uniform mat4 Projection = mat4(1);
            layout(location = 4) uniform mat4 ModelView = mat4(1);
            //layout(location = 8) in float Size; //This causes Python to crash!
            layout(location = 8) uniform float Size = 10;

            vec3 UNIT_CUBE[8] = vec3[8](
              vec3(-1.0, -0.0, -1.0), // 0: lower left rear
              vec3(+1.0, -0.0, -1.0), // 1: lower right rear
              vec3(-1.0, +2.0, -1.0), // 2: upper left rear
              vec3(+1.0, +2.0, -1.0), // 3: upper right rear
              vec3(-1.0, -0.0, +1.0), // 4: lower left front
              vec3(+1.0, -0.0, +1.0), // 5: lower right front
              vec3(-1.0, +2.0, +1.0), // 6: upper left front
              vec3(+1.0, +2.0, +1.0)  // 7: upper right front
            );

            out vec3 _color;

            void main() {
              _color = vec3(1.0, 1.0, 1.0);
              gl_Position = Projection * ModelView * vec4(UNIT_CUBE[gl_VertexID] * 0.3, 1.0);

              gl_PointSize = Size;
            }
            """),
            GL_VERTEX_SHADER)

        fragment_shader = compileShader(dedent(
            """
            #version 450 core

            in vec3 _color;
            out vec4 FragColor;

            void main() {
              FragColor = vec4(_color, 1.0);
            }
            """),
            GL_FRAGMENT_SHADER)

        self.shader = compileProgram(vertex_shader, fragment_shader)

        self.vao = glGenVertexArrays(1)
        glBindVertexArray(self.vao)
        self.vbo = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)

        glBindAttribLocation(self.shader, 8, "Size")
        glLinkProgram(self.shader)

        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
        glEnable(GL_DEPTH_TEST)

    def setPointSize(self):
        size = [10.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0]
        glEnableVertexAttribArray(8)
        glVertexAttribPointer(8, 1, GL_FLOAT, GL_FALSE, 0, size)

    def display_gl(self, modelview, projection):
        glUseProgram(self.shader)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glBindVertexArray(self.vao)
        glClear(GL_COLOR_BUFFER_BIT) #| GL_DEPTH_BUFFER_BIT)

        glUniformMatrix4fv(0, 1, False, projection)
        glUniformMatrix4fv(4, 1, False, modelview)

        self.setPointSize()
        glDrawArrays(GL_POINTS, 0, 8 )

        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glBindVertexArray(0)

    def dispose_gl(self):
        glDeleteProgram(self.shader)
        self.shader = 0
        glDeleteVertexArrays(1, (self.vao,))
        self.vao = 0

我不确定我是否遗漏了什么,或者我的项目是否可能使用 QT 后端而不是 PyGame,那么我的环境和其他导致问题的示例之间存在细微差别?

我希望这里有人可以帮助我弄清楚为什么向 gl_PointSize 提供值会导致 Python 崩溃。我对使用 PyOpenVR 库时可以实时修改缓冲区数据(位置、点大小等)的方法也很感兴趣?

谢谢你的帮助!


[更新]

这是我通过从GLSL 教程 – 属性变量中复制而修改的最新项目。现在这只会在 pyGame 和 pySide QT 中产生一个空白屏幕。

#!/bin/env python

# file color_cube_actor.py

import time
from textwrap import dedent
import numpy as np

from OpenGL.GL import *  # @UnusedWildImport # this comment squelches an IDE warning
from OpenGL.GL.shaders import compileShader, compileProgram

import pygame
from pygame.locals import *

class ColorCubeActor(object):

    array_size = 100

    def __init__(self):
        self.program = 0
        self.scale = 0

        self.indices = np.ascontiguousarray( np.arange(self.array_size), dtype=np.int)
        self.colors = np.ascontiguousarray( np.tile(np.array([0.0,1.0,0.0]), (self.array_size,1)), dtype=np.float) #a bunch of green vertices
        self.sizes = np.ascontiguousarray( np.ones(self.array_size)*10, dtype=np.float)

    def init_gl(self):
        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size

        vertex_shader = compileShader(dedent("""
            #version 450 core

            layout(location = 0) uniform mat4 Projection = mat4(1);
            layout(location = 4) uniform mat4 ModelView = mat4(1);

            in vec3 ptPosition;
            in float ptSize;
            in vec3 ptColor;

            out vec3 _color;

            void main()
            {
                _color = ptColor; //vec3(0.2, 0.5, 1.0); //light blue
                gl_Position = Projection * ModelView * vec4(ptPosition, 1.0);

                //use normalized device coordinates to calculate the PointSize of a vertex based on it's distance from the perspective camera.
                //https://www.gamedev.net/topic/574695-gl_points-distance-attenuation/#
                vec3 ndc = gl_Position.xyz / gl_Position.w ; // perspective divide.
                float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
                // 0 is far (at the far plane)
                gl_PointSize = ptSize*zDist ; // between 0 and 50 now.

            }
            """), GL_VERTEX_SHADER)

        fragment_shader = compileShader(dedent("""
            #version 450 core

            in vec3 _color;
            out vec4 FragColor;

            void main() {
                FragColor = vec4(_color, 1.0); //just pass a color to the vertex (results in a rectangle pixel)
            }
            """), GL_FRAGMENT_SHADER)

        self.program = compileProgram(vertex_shader, fragment_shader)

        #setup the vao and bind buffers (example: http://www.lighthouse3d.com/tutorials/glsl-tutorial/attribute-variables/ )
        self.vao = glGenVertexArrays(1)
        glBindVertexArray(self.vao)

        self.ptSize = glGenBuffers(1) #bind buffer for point sizes
        glBindBuffer(GL_ARRAY_BUFFER, self.ptSize) #GL_ARRAY_BUFFER is the buffer type we use to feed attributes
        ptSize_pointer = glGetAttribLocation(self.program, "ptSize") #get the location of attribute "ptSize" from self.program
        glBufferData(GL_ARRAY_BUFFER, self.sizes.nbytes, self.sizes, GL_STREAM_DRAW) #feed the buffer, and let OpenGL know that we don't plan to
        glEnableVertexAttribArray(ptSize_pointer) #Enable the attribute at that location
        glVertexAttribPointer(ptSize_pointer, 1, GL_FLOAT, GL_FALSE, 0, 0) #Tell OpenGL what the array contains:

        self.ptColor = glGenBuffers(1) #bind buffer for point colors
        glBindBuffer(GL_ARRAY_BUFFER, self.ptColor) #GL_ARRAY_BUFFER is the buffer type we use to feed attributes
        ptColor_pointer = glGetAttribLocation(self.program, "ptColor") #get the location of attribute "ptSize" from self.program
        glBufferData(GL_ARRAY_BUFFER, self.colors.nbytes, self.colors, GL_STREAM_DRAW) #feed the buffer, and let OpenGL know that we don't plan to
        glEnableVertexAttribArray(ptColor_pointer) #Enable the attribute at that location
        glVertexAttribPointer(ptColor_pointer, 3, GL_FLOAT, GL_FALSE, 0, 0) #Tell OpenGL what the array contains:

    def setPoints(self, modelview, projection):
        self.scale += 0.0005

        #create dataset https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
        theta = np.linspace(-4 * np.pi, 4 * np.pi, self.array_size)
        z = np.linspace(-2, 2, self.array_size)
        r = z**2 + 1
        x = r * np.sin(theta)
        y = r * np.cos(theta)
        plot = np.ascontiguousarray(np.dstack((x,y,z)) * self.scale, dtype=np.float)

        self.ptPosition = glGenBuffers(1) #bind buffer for positions and copy data into buffer
        glBindBuffer(GL_ARRAY_BUFFER, self.ptPosition) #GL_ARRAY_BUFFER is the buffer type we use to feed attributes
        ptPosition_pointer = glGetAttribLocation(self.program, "ptPosition") #get the location of attribute "ptSize" from self.program
        glBufferData(GL_ARRAY_BUFFER, plot.nbytes, plot, GL_STREAM_DRAW) #feed the buffer, and let OpenGL know that we don't plan to
        glEnableVertexAttribArray(ptPosition_pointer) #Enable the attribute at that location
        glVertexAttribPointer(ptPosition_pointer, 3, GL_FLOAT, GL_FALSE, 0, 0)#Tell OpenGL what the array contains:

        glUniformMatrix4fv(0, 1, False, projection)
        glUniformMatrix4fv(4, 1, False, modelview)

        glDrawElements(GL_POINTS, self.array_size, GL_UNSIGNED_INT, self.indices)

    def display_gl(self, modelview, projection):
        glClear(GL_COLOR_BUFFER_BIT) #| GL_DEPTH_BUFFER_BIT)
        glUseProgram(self.program)
        self.setPoints(modelview, projection)

    def dispose_gl(self):
        glDeleteProgram(self.program)
        self.program = 0

    def main(self):
        pygame.init()
        pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
        self.init_gl()

        projection = np.array([#the matrix generated captured while using HTC Vive
            [ 0.75752085,  0.        ,  0.        ,  0.],
            [ 0.        ,  0.68160856,  0.        ,  0.],
            [ 0.05516453, -0.00299519, -1.00040019, -1.],
            [ 0.        ,  0.        , -0.20008004,  0.]
        ])
        modelview = np.array([#the matrix generated captured while using HTC Vive
            [ 0.99030989,  0.04490654,  0.13141415,  0.],
            [-0.01430531,  0.9742285 , -0.22510922,  0.],
            [-0.13813627,  0.22104797,  0.9654305 ,  0.],
            [-0.12975544, -0.9294402 , -1.06236947,  1.]
        ])

        start_time = time.time()
        while time.time() - start_time < 5: #5 second animation
            self.display_gl( modelview, projection)
            pygame.display.flip()

if __name__ == '__main__':
    t = ColorCubeActor()
    t.main()

也再次感谢大家的帮助和患者!我知道我对 OpenGL 非常缺乏经验,非常感谢所有建议。


[更新]

很长一段时间以来,学习 OpenGL 可能是我尝试做的最困难的事情之一。我现在花了四天时间试图在 OpenGL 4.5 中设置缓冲区,但我几乎没有取得任何进展,我只是觉得自己陷入了困境。

这是我编写的一些代码的示例(它没有指定版本 4.5)。根据 Derhass 的建议,我尝试在此文件中使用 VBO,它们似乎可以工作,直到指定#version 450 core我得到的只是大量折旧错误和 1282 的位置。再次因为它不针对 OpenGL 4.5,我认为我不能将它与 OpenVR 一起使用(不知道为什么会这样?)。

在此处输入图像描述

#!/bin/env python
# coding: utf-8

import time
import numpy as np
from textwrap import dedent

from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram

import pygame
from pygame.locals import *

##############################################################################
# OpenGL funcs
##############################################################################
buffers=None
shader = None
def init_gl():
    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size

    global shader, buffers

    vertex_shader = compileShader(dedent('''

        uniform mat4 Projection = mat4(1);
        uniform mat4 ModelView = mat4(1);

        varying out vec3 _color;

        void main() {
            _color = gl_Color;
            gl_Position =  Projection * ModelView * gl_ModelViewProjectionMatrix * gl_Vertex;

            vec3 ndc = gl_Position.xyz / gl_Position.w ; // perspective divide.
            float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
            // 0 is far (at the far plane)
            gl_PointSize = 25*zDist ; // between 0 and 50 now.

        }
        '''), GL_VERTEX_SHADER)
    fragment_shader = compileShader(dedent('''

        in vec3 _color;

        void main() {
            gl_FragColor = vec4(_color, 1.0); //gl_Color;
        }
        '''), GL_FRAGMENT_SHADER)
    shader = compileProgram(vertex_shader, fragment_shader)

    buffers=create_vbo()

yaw=0
pitch=0
def draw():
    global yaw, pitch
    glClear(GL_COLOR_BUFFER_BIT)# | GL_DEPTH_BUFFER_BIT)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    yaw+=0.39
    pitch+=0.27
    glTranslatef(0.0, 0.0, 0.0)
    glRotatef(yaw, 0, 1, 0)
    glRotatef(pitch, 1, 0, 0)

    setPoints()
    glFlush()

##############################################################################
# vertices
##############################################################################
array_size = 100
scale = 0.15

#create dataset https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
theta = np.linspace(-4 * np.pi, 4 * np.pi, array_size)
z = np.linspace(-2, 2, array_size)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)

vertices = np.dstack((x,y,z)) * scale
colors = np.tile(np.array([0.0, 1.0, 0.0]), (array_size,1)) #a bunch of green vertices
indices=np.arange(array_size)


def create_vbo():
    buffers = glGenBuffers(3)

    glBindBuffer(GL_ARRAY_BUFFER, buffers[0])
    glBufferData(GL_ARRAY_BUFFER,
            vertices.nbytes,  # byte size
            (ctypes.c_float*len(vertices.flat))(*vertices.flat),
            GL_STREAM_DRAW)

    glBindBuffer(GL_ARRAY_BUFFER, buffers[1])
    glBufferData(GL_ARRAY_BUFFER,
            colors.nbytes, # byte size
            (ctypes.c_float*len(colors.flat))(*colors.flat),
            GL_STATIC_DRAW)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2])
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
            indices.nbytes, # byte size
            (ctypes.c_uint*len(indices.flat))(*indices.flat),
            GL_STATIC_DRAW)
    return buffers

def draw_vbo():
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glVertexPointer(3, GL_FLOAT, 0, None);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glColorPointer(3, GL_FLOAT, 0, None);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
    glDrawElements(GL_POINTS, indices.size, GL_UNSIGNED_INT, None);

    glDisableClientState(GL_COLOR_ARRAY)
    glDisableClientState(GL_VERTEX_ARRAY);


def setPoints():
    global shader

    glUseProgram(shader)
    draw_vbo()

    projection = np.array([#the matrix generated captured while using HTC Vive
        [ 0.75752085,  0.        ,  0.        ,  0.],
        [ 0.        ,  0.68160856,  0.        ,  0.],
        [ 0.05516453, -0.00299519, -1.00040019, -1.],
        [ 0.        ,  0.        , -0.20008004,  0.]
    ])
    modelview = np.array([#the matrix generated captured while using HTC Vive
        [ 0.99030989,  0.04490654,  0.13141415,  0.],
        [-0.01430531,  0.9742285 , -0.22510922,  0.],
        [-0.13813627,  0.22104797,  0.9654305 ,  0.],
        [-0.12975544, -0.9294402 , -1.06236947,  1.]
    ])

    glUniformMatrix4fv(glGetUniformLocation(shader, "Projection"), 1, False, projection)
    glUniformMatrix4fv(glGetUniformLocation(shader, "ModelView"), 1, False, modelview)

    glUseProgram(0)

##############################################################################
if __name__ == '__main__':

    pygame.init()
    pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)

    init_gl()

    start_time = time.time()
    while time.time() - start_time < 5: #5 second animation
        draw()
        pygame.display.flip()

所以我尝试将它重写为 Python Class() 但即使它看起来相同,由于某种原因我只看到一个顶点在移动,其余的谁知道在哪里:

#!/bin/env python
# coding: utf-8

import time
import numpy as np
from textwrap import dedent

from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram

import pygame
from pygame.locals import *


class ObjectActor(object):
    array_size = 100

    def __init__(self):
        self.buffers=None
        self.shader=None

        self.vertices = self.get_vertices()
        self.colors = np.tile(np.array([0.0, 1.0, 0.0]), (self.array_size,1)) #a bunch of green vertices
        self.indices = np.arange(self.array_size)

    def init_gl(self):
        ##############################################################################
        # OpenGL funcs
        ##############################################################################

        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size

        vertex_shader = compileShader(dedent('''

            uniform mat4 Projection = mat4(1);
            uniform mat4 ModelView = mat4(1);

            varying out vec3 _color;

            void main() {
                _color = gl_Color;
                gl_Position =  Projection * ModelView * gl_ModelViewProjectionMatrix * gl_Vertex;

                vec3 ndc = gl_Position.xyz / gl_Position.w ; // perspective divide.
                float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
                // 0 is far (at the far plane)
                gl_PointSize = 25*zDist ; // between 0 and 50 now.

            }
            '''), GL_VERTEX_SHADER)
        fragment_shader = compileShader(dedent('''

            in vec3 _color;

            void main() {
                gl_FragColor = vec4(_color, 1.0); //gl_Color;
            }
            '''), GL_FRAGMENT_SHADER)
        self.shader = compileProgram(vertex_shader, fragment_shader)

        self.create_vbo()

    def display_gl(self, modelview, projection):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.setPoints(modelview, projection)
        glFlush()

    def get_vertices(self):
        ##############################################################################
        # vertices
        ##############################################################################
        scale = 0.15
        theta = np.linspace(-4 * np.pi, 4 * np.pi, self.array_size)
        z = np.linspace(-2, 2, self.array_size)
        r = z**2 + 1
        x = r * np.sin(theta)
        y = r * np.cos(theta)
        return np.dstack((x,y,z)) * scale

    def create_vbo(self):
        self.buffers = glGenBuffers(3)

        glBindBuffer(GL_ARRAY_BUFFER, self.buffers[0])
        glBufferData(GL_ARRAY_BUFFER,
                self.vertices.nbytes,  # byte size
                (ctypes.c_float*len(self.vertices.flat))(*self.vertices.flat),
                GL_STREAM_DRAW)

        glBindBuffer(GL_ARRAY_BUFFER, self.buffers[1])
        glBufferData(GL_ARRAY_BUFFER,
                self.colors.nbytes, # byte size
                (ctypes.c_float*len(self.colors.flat))(*self.colors.flat),
                GL_STATIC_DRAW)

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.buffers[2])
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                self.indices.nbytes, # byte size
                (ctypes.c_float*len(self.indices.flat))(*self.indices.flat),
                GL_STATIC_DRAW)

    def draw_vbo(self):
        glEnableClientState(GL_VERTEX_ARRAY)
        glEnableClientState(GL_COLOR_ARRAY)

        glBindBuffer(GL_ARRAY_BUFFER, self.buffers[0])
        glVertexPointer(3, GL_FLOAT, 0, None)

        glBindBuffer(GL_ARRAY_BUFFER, self.buffers[1])
        glColorPointer(3, GL_FLOAT, 0, None)

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.buffers[2])
        glDrawElements(GL_POINTS, self.indices.size, GL_UNSIGNED_INT, None)

        glDisableClientState(GL_COLOR_ARRAY)
        glDisableClientState(GL_VERTEX_ARRAY)

    def setPoints(self, modelview, projection):
        glUseProgram(self.shader)

        self.draw_vbo()

        glUniformMatrix4fv(glGetUniformLocation(self.shader, "Projection"), 1, False, projection)
        glUniformMatrix4fv(glGetUniformLocation(self.shader, "ModelView"), 1, False, modelview)

        glUseProgram(0)

    def main(self):
        pygame.init()
        pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
        self.init_gl()

        projection = np.array([#the matrix generated captured while using HTC Vive
            [ 0.75752085,  0.        ,  0.        ,  0.],
            [ 0.        ,  0.68160856,  0.        ,  0.],
            [ 0.05516453, -0.00299519, -1.00040019, -1.],
            [ 0.        ,  0.        , -0.20008004,  0.]
        ])
        modelview = np.array([#the matrix generated captured while using HTC Vive
            [ 0.99030989,  0.04490654,  0.13141415,  0.],
            [-0.01430531,  0.9742285 , -0.22510922,  0.],
            [-0.13813627,  0.22104797,  0.9654305 ,  0.],
            [-0.12975544, -0.9294402 , -1.06236947,  1.]
        ])

        yaw=0
        pitch=0
        start_time = time.time()
        while time.time() - start_time < 5: #5 second animation

            glMatrixMode(GL_MODELVIEW)
            glLoadIdentity()
            yaw+=0.39
            pitch+=0.27
            glTranslatef(0.0, 0.0, 0.0)
            glRotatef(yaw, 0, 1, 0)
            glRotatef(pitch, 1, 0, 0)

            self.display_gl(modelview, projection)

            pygame.display.flip()

##############################################################################
if __name__ == '__main__':
    t = ObjectActor()
    t.main()

在这一点上,我肯定在考虑 PyOpenGL 的工作方式有问题或者我只是无法弄清楚如何使用它的可能性。无论哪种方式,它都是一个真正的无赖..

4

1 回答 1

0

您的代码无效并且很可能崩溃。

glVertexAttribPointer会将最后一个参数作为字节偏移量插入到当前绑定的GL_ARRAY_BUFFER对象中。如果您想指定一些客户端内存指针,您必须确保将该绑定目标设置为 0。但是,您的代码glBindBuffer(GL_ARRAY_BUFFER, self.vbo)之前会这样做。

Nowself.vbo实际上是一个有效缓冲区对象的名称,但您从未为其创建任何存储。结果是您只是为 GL 设置了一些完全无效的指针,当它试图取消引用它时确实会崩溃。

目前尚不清楚您使用的是哪个 OpenGL 上下文版本以及更重要的配置文件。在核心配置文件中,不再可能使用客户端顶点数组,您必须先将数据传输到 VBO。在兼容性配置文件或遗留上下文中,您可以通过确保glBindBuffer(GL_ARRAY_BUFFER,0)在设置属性指针之前解决此崩溃。

于 2017-04-09T17:09:28.837 回答