OpenGL الأساسي ، المخازن المؤقتة في قمة الرأس و Pyglet

StackOverflow https://stackoverflow.com/questions/4618892

  •  30-09-2019
  •  | 
  •  

سؤال

تحرير: وجدت Rotoglup المشكلات في الكود الخاص بي ، مع إضافة التظليلات التي قمت بإزالتها أكملت الحل. انظر إجابتي أدناه للحصول على الكود الصحيح (مع التظليل).

أهلاً بكم !

أحاول أن أتعلم بعض أساسيات OpenGL الحديثة من هذا البرنامج التعليمي.

أود أن أفعل ذلك مع Python/Pyglet بدلاً من C ++. أعلم أن Pyglet يمكنه تجريد جزء كبير من المستوى المنخفض. أريد أن أفهم بعض الأساسيات قبل الانتقال إلى إخفاءها خلف طبقات من التجريد.

مشكلتي بسيطة للغاية: الرمز أدناه يرسم نقطة واحدة فقط بدلاً من 3 أتوقع. الكود الخاص بي هو ، بقدر ما أستطيع أن أقول ، مطابق لـ C ++ في البرنامج التعليمي ، باستثناء إزالة قمة التظليل (تم ذلك عبر عبر gletools في بيثون) ، والذي يبدو أنه لا يوجد فرق في مشكلتي.

إن تبسيط الأشياء إلى نقطة واحدة يوضح سلوكًا لا أفهمه (يبدو أن الإحداثي الأول هو الوحيد الذي يؤثر على أي شيء) ، مما دفعني إلى اعتقادي بأنني أخفقت ببساطة في فهم شيء أساسي للغاية حول Pyglet ، OpenGL ، أو حتى 3D بشكل عام: P

إليك الرمز ذي الصلة:

import pyglet
from pyglet.gl import *

window = pyglet.window.Window()

positionBufferObject = GLuint()
vao = GLuint()

vertexPositions = [0.0, 0.0, 0.0,
                   0.25, 0.0, 0.0,
                   1.75, 1.75, 0.0]

vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)

@window.event
def on_draw():
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
    glDrawArrays(GL_POINTS, 0, 3)
    glDisableVertexAttribArray(0)

glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)

glClearColor(0.0, 0.0, 0.0, 0.0)
pyglet.app.run()
هل كانت مفيدة؟

المحلول

glDrawArrays(GL_POINTS, 0, 1)

تعليمات لرسم نقطة واحدة ، في البرنامج التعليمي الخاص بك ، 1 هو 3:

glDrawArrays(GL_POINTS, 0, 3)

لاحظ أيضًا أن المكون الرابع (W) من رؤوسك يجب أن يكون 1 ، وليس 0:

  vertexPositions = [0.0, 0.0, 0.0, 1.0,
                     0.25, 0.0, 0.0, 1.0,
                     1.75, 1.75, 0.0, 1.0]

بدلاً من ذلك ، يمكنك إزالة مكون W ،

  vertexPositions = [0.0, 0.0, 0.0,
                     0.25, 0.0, 0.0,
                     1.75, 1.75, 0.0]

وتغيير المكالمة التالية إلى:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)

شيء آخر ، لست خبيرًا في Pyglet ، لكن من الممكن أن تأخذ Glbufferdata ، مثل نظيرها C ، حجمها في البايتات ، وليس في عناصر. كل تعويم يجري 4 بايت ، يمكنك المحاولة:

glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)

نصائح أخرى

لقد حصلت أخيرًا على هذا بشكل صحيح!

يبدو أنني كنت مضللاً من خلال حقيقة أن العبث مع الرؤوس ، والألوان ، و glvertexattribpointer أدت أحيانًا إلى عرض نقطة واحدة. يبدو أن هذا حادث: مع التصحيحات التي توفرها إجابة Rotoglup ، لا يوجد شيء على الإطلاق. هذا هو السلوك "الصحيح" للرمز في سؤالي الأصلي.

جرد من أخطائي في حال يساعد أي شخص:

  • قم بتعيين الإحداثيات W إلى 0 ، بدلاً من 1 ، في عداد المفقودين تمامًا التفسيرات لتحويل الفضاء في البرنامج التعليمي.

  • إعطاء glbufferdata حجم المخزن المؤقت في القمم عندما يتوقع بايت.

  • إزالة قمة الرأس وشظايا الشظايا (لتبسيط الكود مع البحث عن المسألتين أعلاه). هذا يضمن أنه لن يتم تقديم أي شيء على الإطلاق ... باستثناء (عربات التي تجرها الدواب؟) نقطة واحدة كنت أحصل عليها أحيانًا.

بالنسبة للسجل ، يعرض الرمز أدناه مثلثًا واحدًا ، مع تمرير التظليل ، فيما آمل أن يكون محدثًا وتصحيح OpenGL. المتطلبات هي pyglet و gletools.

import pyglet
from pyglet.gl import *
from gletools import ShaderProgram, FragmentShader, VertexShader

window = pyglet.window.Window()

positionBufferObject = GLuint()

vertexPositions = [0.75, 0.75, 0.0, 1.0,
                   0.75, -0.75, 0.0, 1.0,
                   -0.75, -0.75, 0.0, 1.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)

program = ShaderProgram(
    FragmentShader('''
    #version 330
    out vec4 outputColor;
    void main()
    {
       outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    }'''),
    VertexShader('''
    #version 330
    layout(location = 0) in vec4 position;
    void main()
    {
        gl_Position = position;
    }''')
)

@window.event
def on_draw():
    with program:
        glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
        glDrawArrays(GL_TRIANGLES, 0, 3)
        glDisableVertexAttribArray(0)

glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)

pyglet.app.run()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top