OpenGL - Stack overflow nếu tôi làm, Stack underflow nếu tôi không!


7

Tôi đang học lớp đa phương tiện ở trường đại học và chúng tôi đang "học" OpenGL như một phần của lớp. Tôi đang cố gắng tìm ra cách máy ảnh OpenGL so với modelview hoạt động, và vì vậy tôi đã tìm thấy ví dụ này . Tôi đang cố gắng chuyển ví dụ sang Python bằng các liên kết OpenGL - nó khởi động OpenGL nhanh hơn rất nhiều, vì vậy, để kiểm tra, nó sẽ đẹp hơn rất nhiều - nhưng tôi tiếp tục gặp phải lỗi tràn ngăn xếp với glPushMatrix trong mã này:

  def cube(): 
      for x in xrange(10):
          glPushMatrix()
          glTranslated(-positionx[x + 1] * 10, 0, -positionz[x + 1] * 10); #translate the cube
          glutSolidCube(2); #draw the cube
          glPopMatrix();

Theo tài liệu tham khảo này , điều đó xảy ra khi ngăn xếp ma trận đầy.

Vì vậy, tôi nghĩ, "tốt, nếu nó đầy, hãy để tôi bật ma trận ra khỏi đỉnh ngăn xếp, và sẽ có chỗ". Tôi đã sửa đổi mã thành:

  def cube(): 
      glPopMatrix()
      for x in xrange(10):
          glPushMatrix()
          glTranslated(-positionx[x + 1] * 10, 0, -positionz[x + 1] * 10); #translate the cube
          glutSolidCube(2); #draw the cube
          glPopMatrix();

Và bây giờ tôi nhận được một lỗi tràn bộ đệm - điều này rõ ràng xảy ra khi ngăn xếp chỉ có một ma trận.

Vì vậy, tôi chỉ đang chờ đợi trong sự hiểu biết của tôi? Hoặc có một số cách để tăng kích thước ngăn xếp ma trận?

Ngoài ra, nếu bất cứ ai có một số tài liệu tham khảo (trực tuyến) tốt (ví dụ, v.v.) để hiểu cách các ma trận máy ảnh / mô hình hoạt động cùng nhau, tôi sẽ chân thành đánh giá cao chúng!

Cảm ơn!

BIÊN TẬP:

Đây là pastebin của mã đầy đủ: http://pastebin.com/QXxNisuA


2
Đó có phải là toàn bộ mã của bạn? Bạn có chắc chắn rằng bạn không thực hiện thêm glPushMatrix nào không có glPopMatrix tương ứng không? Bạn có chắc chắn rằng không chỉ ảnh hưởng đến hướng dẫn glPushMatrix?
r2d2rigo

Vâng, chúng tôi cần phải xem mã khác của bạn. Bạn đang thiết lập ma trận chiếu ở đâu? Bạn đã chuyển sang chế độ GL_MODELVIEW chưa? (Ngăn xếp ma trận chiếu cực kỳ nhỏ.)
TheBuzzSaw

Chắc chắn tránh mẫu mã thứ hai của bạn. Có một glPopMatrix chỉ trôi nổi ở đó mà không có glPushMatrix tương ứng chắc chắn sẽ dẫn đến một dòng chảy. Mẫu mã đầu tiên của bạn trông ổn; phải có một vấn đề trong phần còn lại của mã của bạn.
TheBuzzSaw

Tôi đã xóa câu trả lời của tôi vì nó có lỗi. Tôi đã giả định điều gì đó không đúng sự thật.
Notabene

1
Tại sao bạn không hỏi điều này trên Stack'Flow ?
Mateen Ulhaq

Câu trả lời:


9

Đã chỉnh sửa để thêm: hiện tại điều này không quan trọng vì nó vẫn hoạt động tốt và giúp việc học OpenGL dễ dàng hơn nhưng hãy lưu ý rằng toàn bộ hệ thống ngăn xếp ma trận không được dùng trong OpenGL 3.x và hơn thế nữa. Một sự thay thế có thể là GLM .

Mã trong pastebin của bạn thậm chí không chạy cho tôi.

Cụ thể, các chỉ số danh sách của bạn trong chức năng hiển thị nằm ngoài phạm vi (danh sách của bạn có 10 phần tử: danh sách python bắt đầu từ 0; bạn lập chỉ mục từ 0 + 1 đến 10 + 1).

Tôi nghĩ rằng bạn cũng có một số quả cầu bị thiếu trong chức năng xử lý chuột nhưng đó có thể là do tôi di chuyển mã xung quanh trong một nỗ lực để ít nhất làm cho nó trông giống như con trăn;)

Dù sao, với các bản sửa lỗi này, mã được hiển thị bên dưới DOES hoạt động với tôi, không có dấu hiệu của ngăn xếp ma trận GL dưới / tràn!

import sys
from math import sin, cos
from random import randint
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
#angle of rotation
xpos= ypos= zpos= xrot= yrot= angle= lastx= lasty = 0

#positions of the cubes
positionz = []
positionx = []

def init():
    global positionz, positionx
    glEnable(GL_DEPTH_TEST) #enable the depth testing
    glEnable(GL_LIGHTING) #enable the lighting
    glEnable(GL_LIGHT0) #enable LIGHT0, our Diffuse Light
    glShadeModel(GL_SMOOTH) #set the shader to smooth shader

    positionx = [randint(0, 10) for x in xrange(10)]
    positionz = [randint(0, 10) for x in xrange(10)]

def camera():
    global xrot, yrot, xpos, ypos, zpos
    glRotatef(xrot,1.0,0.0,0.0)  #rotate our camera on teh x-axis (left and right)
    glRotatef(yrot,0.0,1.0,0.0)  #rotate our camera on the y-axis (up and down)
    glTranslated(-xpos,-ypos,-zpos) #translate the screen to the position of our camera

def display():
    global angle
    glClearColor(0.0,0.0,0.0,1.0) #clear the screen to black
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) #clear the color buffer and the depth buffer
    glLoadIdentity()
    camera()
    for x in xrange(10):
        glPushMatrix()
        glTranslated(-positionx[x] * 10, 0, -positionz[x] * 10) #translate the cube
        glutSolidCube(2) #draw the cube
        glPopMatrix()
    glutSwapBuffers() #swap the buffers
    angle += angle #increase the angle

def reshape(w, h):
    glViewport(0, 0, w, h); #set the viewport to the current window specifications
    glMatrixMode(GL_PROJECTION); #set the matrix to projection

    glLoadIdentity();
    gluPerspective(60, w / h, 1.0, 1000.0)
    #set the perspective (angle of sight, width, height, , depth)
    glMatrixMode(GL_MODELVIEW); #set the matrix back to model

def keyboard (key, x, y):
    global xrot, xpos, ypos, zpos, xrot, yrot, angle, lastx, lasty, positionz, positionx
    if (key=='q'):
        xrot += 1
        if (xrot >360):
            xrot -= 360
    if (key=='z'):
        xrot -= 1;
        if (xrot < -360): xrot += 360
    if (key=='w'):
        yrotrad = (yrot / 180 * 3.141592654)
        xrotrad = (xrot / 180 * 3.141592654)
        xpos += float(sin(yrotrad))
        zpos -= float(cos(yrotrad))
        ypos -= float(sin(xrotrad))
    if (key=='s'):
        yrotrad = (yrot / 180 * 3.141592654)
        xrotrad = (xrot / 180 * 3.141592654)
        xpos -= float(sin(yrotrad))
        zpos += float(cos(yrotrad))
        ypos += float(sin(xrotrad))
    if (key=='d'):
        yrotrad = (yrot / 180 * 3.141592654)
        xpos += float(cos(yrotrad)) * 0.2
        zpos += float(sin(yrotrad)) * 0.2
    if (key=='a'):
        yrotrad = (yrot / 180 * 3.141592654)
        xpos -= float(cos(yrotrad)) * 0.2
        zpos -= float(sin(yrotrad)) * 0.2
    if (key==27):
        sys.exit(0)

def mouseMovement(x, y):
    global lastx, lasty, xrot, yrot
    diffx=x-lastx #check the difference between the current x and the last x position
    diffy=y-lasty #check the difference between the current y and the last y position
    lastx=x #set lastx to the current x position
    lasty=y #set lasty to the current y position
    xrot += float(diffy) #set the xrot to xrot with the addition of the difference in the y position
    yrot += float(diffx) #set the xrot to yrot with the addition of the difference in the x position

glutInit()
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(500, 500)
glutInitWindowPosition (100, 100)
glutCreateWindow("A basic OpenGL Window")
init()
glutDisplayFunc(display)
glutIdleFunc(display)
glutReshapeFunc(reshape)
glutPassiveMotionFunc(mouseMovement)
#check for mouse movement
glutKeyboardFunc (keyboard)
glutMainLoop()

4
Bạn vừa làm bài tập về nhà của họ! Họ sẽ tìm hiểu những gì đã sai và làm thế nào để sửa nó, hoặc họ sẽ chỉ sao chép và dán và di chuyển trên?
Sẽ

1
Vì vậy, quá hữu ích là một lý do để bỏ phiếu? Và sửa chữa những gì về cơ bản là một lỗi duy nhất là "làm bài tập về nhà của họ"? Nếu bạn nhìn vào mã đầy đủ mà OP đưa vào pastebin, bạn sẽ lưu ý rằng tôi chỉ di chuyển mã xung quanh để tôi có thể đọc nó dễ dàng hơn và thay đổi hai chỉ số sai đó ...
Bethor

1
Đây thực sự hữu ích - vấn đề wasnt tôi
Wayne Werner

Câu trả lời này thực sự hữu ích và cũng có rất ít liên quan đến bài tập về nhà thực tế của tôi. Như tôi đã đăng ban đầu, tôi muốn tìm hiểu cách thức hoạt động của máy ảnh - điều đó có nghĩa là tôi sẽ loay hoay với mã này. Bethor đã trả lời câu hỏi của tôi (đó là lỗi một lần, được tích hợp vào ví dụ mã gốc), và vượt lên trên và làm sạch mã. Do đó được chấp nhận. (drat SO để tự động đăng nhận xét của tôi và cắt thời gian của tôi tắt trước khi tôi có thể soạn thảo một lời nhận xét đàng hoàng)
Wayne Werner

Rất nhiều mã :)
daemonfire300

1

OpenGL có thể lưu trữ và khôi phục ma trận trên ngăn xếp bằng cách sử dụng glPushMatrixglPopMatrix. Điều rất quan trọng là mỗi lần đẩy có một cửa sổ bật lên tương ứng - nếu bạn đẩy nhiều hơn số lần bật, bạn sẽ được thông báo khi tất cả các bản vẽ kết thúc mà bạn đang tràn vào ngăn xếp. Nếu bạn bật nhiều hơn bạn đẩy, bạn sẽ được thông báo ngay lập tức rằng bạn đang tràn vào ngăn xếp. Đây là cách OpenGL cho phép bạn bản địa hóa các lỗi lập trình.

Vì vậy, đảm bảo rằng tất cả các đẩy ở khắp mọi nơi có một pop tương ứng.

Bất cứ nơi nào bạn đẩy, đảm bảo có một cửa sổ bật lên tương ứng trong lối ra của khối mã đó.

Nếu mã của bạn đang ném một ngoại lệ (nghĩa là lặp đi lặp lại trong giới hạn trong mảng của bạn?), Có thể bạn cần đặt pop trong một khối cuối cùng, ví dụ:

def cube():
    for x in xrange(10):
        try:
            glPushMatrix()
            # draw something
        finally:
            glPopMatrix()
            # I'm trusting some code further out will catch and display your actual error now

Điều này sẽ không khắc phục được vấn đề vì như bạn đã lưu ý, vấn đề đang lặp lại ngoài giới hạn, như tôi đã nêu trong câu trả lời của mình rằng bạn đã bỏ phiếu. Ngoài ra, điều này sẽ không giúp anh ta thấy câu trả lời thực tế của mình; vì ngoại lệ không được phát hiện, tập lệnh vẫn sẽ chấm dứt. Vì vậy, -1, nếu tôi có thể bỏ phiếu, đặc biệt là hình thức tồi tệ nhất có thể cố gắng chôn vùi câu trả lời trước đó của tôi!
Bethor

Ngoại lệ từ ngăn xếp GL phát hiện ngăn xếp không cân bằng là điều ngăn anh ta nhìn thấy ngoại lệ nguyên nhân gốc. Cũng giống như cách anh ta nhìn thấy bản báo cáo rằng anh ta có một ngăn xếp không cân bằng trong thiết bị đầu cuối, giờ anh ta sẽ thấy rằng anh ta có một ngoại lệ ngoài giới hạn.
Sẽ

Đủ công bằng; Tôi vẫn không chắc chắn làm thế nào anh ấy nhìn thấy một ngăn xếp tràn mặc dù. Mã trong pastebin của anh ấy tăng IndexError tại vị trí thích hợp để tôi cài đặt Python 2.7 và PyOpenGL mới nhất và chạy chính xác sau khi sửa lỗi này. Trên hết, mã của anh ta không đẩy nhiều hơn nó xuất hiện, theo như tôi có thể nói khi đọc nó.
Bethor

1
Nó phụ thuộc vào việc triển khai OpenGL; có vẻ như rõ ràng rằng việc triển khai OpenGL của anh ta đang tích cực tính vào mã gọn gàng của nó đang được kích hoạt bởi ngoại lệ.
Sẽ

Điểm tốt ! Mặc dù ngoại lệ đã kích hoạt tất cả có lẽ vẫn còn hiển thị với OP, tôi đoán rằng anh ta chỉ nhìn thấy cái cuối cùng và không tìm kiếm nguyên nhân gốc rễ.
Bethor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.