2020年12月25日星期五

pyopengl/opengl weird ghosting effect deleted triangles showing up even after deletion

the dozens of you out there using pyopengl and the extremely advanced c++ opengl programmers, (seriouly guys, really gotta appreciate the work you guys put in to opengl projects), I am in a bit of a predicament. I am quite new to graphics programming, ive taken on making a game as a sort of side project, and most problems i have been able to debug, however, this one exceeds my knowledge, i have tried everything i can think of.

in a nutshell, im writing vertexes for a cube into a vbo that i have setup correctly with a glbuffersubdata() call every frame, i then use gldrawarrays() and opengl does its thing and sends pixel data to a doublebuffer screen setup which i cycle through using a pygame.dislplay.flip() call. however in some cases, my game will delete some cubes, so after a certain time, it will send less cube data through the glbuffersubdata() call then the previous frame, resulting in the deleted cubes pixel data not being fully overwritten, creating a wierd artifact, where the game is not updating this cube, so its just a static overlay that follows the users camera perspective. i want to get rid of this artifact, but i cant.

first thing that came into mind, was if the the deleted cubes vertex data is not being overwritten, then why dont i just clear the pixel buffer, the alegeed colourbuffer and then send the new vertex data after that, so that only the new and intended verticies are renderes, however, this leads to even more artifacts, such as screen flickering black.

another thing that i thought about was to use the nnumber of triangles to render preset on the gldrawarrays() method, where for those who dont know, the final arguement, takes in the number of triangles i want to render out of all the hundreds of triangels i have sent opengl, so if i have 100 trianglees in my vbo but i set this arguement to 10 it will only render 10, similllarly if i render 0 i should get a black screen, after which i can clear the pixel data and then send new verticies, adnd render the new ones, however none of these were without additional artifacts, and just messing around some of the things i tried added in artifacts without even fixing the original ghosting artifact.

My hope is in you, those who are patient enough to read up till this point and bear wiht my ramblling, heres my code, sorry its in python, however,i fell the logic blocks arent too unrecognisable to a c++ programmer. bear in mind this is a whole entire game and there is a lot of unrelevant code to my opengl issue heres the code snippet where the problem i think lies:

if len(models) > 0:              models2 = (ctypes.c_float*len(models))(*models2)              print(len(models))              glBufferSubData(GL_ARRAY_BUFFER, 0, len(models)*4, models2)              glDrawArrays(GL_TRIANGLES,0,len(models))              pygame.display.flip()              sleep(1/fps/2)            else:              glDrawArrays(GL_TRIANGLES,0,0)              pygame.display.flip()              sleep(1/fps/2)              glDrawArrays(GL_TRIANGLES,0,0)              pygame.display.flip()  

and here is my simple incomplete game at the moment:

import pygame  from PIL import Image  import math  import ctypes  import numpy as np  from pygame.locals import *  from OpenGL.GL import shaders  from OpenGL.GL import *  from time import sleep  import random    def rotation(angle_xy,angle_yz,angle_xz):      angle = math.radians(angle_xy)      angle1 = math.radians(angle_yz)      angle2 = math.radians(angle_xz)        xy_matrix = np.array([[math.cos(angle),math.sin(angle),0,0],                            [-1*math.sin(angle),math.cos(angle),0,0],                            [0,0,1,0],                            [0,0,0,1]])      yz_matrix = np.array([[1,0,0,0],                            [0,math.cos(angle1),math.sin(angle1),0],                            [0,-1*math.sin(angle1),math.cos(angle1),0],                            [0,0,0,1]])      xz_matrix = np.array([[math.cos(angle2),0,math.sin(angle2),0],                            [0,1,0,0],                            [-1*math.sin(angle2),0,math.cos(angle2),0],                            [0,0,0,1]])                     matrix = np.dot(yz_matrix,xz_matrix,)      matrix = np.dot(xy_matrix,matrix)              return(matrix)    def translate(x,y,z):      matrix = np.array([[1,0,0,x],                            [0,1,0,y],                            [0,0,1,z],                            [0,0,0,1]])      return(matrix)    def perspective(fov,far):      global aspect_ratio       perspective_matrix = np.array([[aspect_ratio*(2/math.tan(math.radians(fov))),0,0,0],                                     [0,2/math.tan(math.radians(fov)),0,0],                                     [0,0,far/(far-1),-1*far/(far-1)],                                     [0,0,1,0]])      return(perspective_matrix)  def world_position(o_xy,o_yz,o_xz,tx,ty,tz,t_xy,t_yz,t_xz):      global fov,far,cam,bearing      matrix = np.dot(rotation(t_xy-bearing[0],t_yz-bearing[1],t_xz-bearing[2]),                     (np.dot(translate(tx,ty,tz),                     rotation(o_xy,o_yz,o_xz))))              return(matrix)        def set_view_bearing(angle_xy,angle_yz,angle_xz):      global bearing      bearing=[angle_xy,angle_yz,angle_xz]        def final_display_position(vertex,o_xy,o_yz,o_xz,tx,ty,tz,t_xy,t_yz,t_xz):      global fov,far,cam,bearing      obj = vertex      obj.extend([1.0])      matrix = np.dot(perspective(fov,far),                     (np.dot(world_position(o_xy,o_yz,o_xz,tx,ty,tz,t_xy,t_yz,t_xz),obj)))      return(matrix/matrix[-1])    def set_fov(new_fov):      global fov      fov = new_fov    def set_cam(x,y,z):      global cam      cam = [x,y,z]    def set_render_distance(value):      global far      far = value    def set_aspect_ratio(x,y):      global aspect_ratio      aspect_ratio = y/x    def accelerate(currentspeed,targetspeed,resolution):      acceleration = (targetspeed - currentspeed) / resolution      return(acceleration)    def createcube():      global defaultdistance        cube1 = [0,0,0]      cube2 = []      cube = []      physics = []      physics1 = []      obj = []      newcube = []        randomx = random.uniform(-1,1)      randomy = random.uniform(-0.75,0.75)        for i in range (3):          for y in range(2):              for x in range(2):                  cube1[i] = 0                  cube1[i-1] = y                   cube1[i-2] = x                   cube1[0] += abs(randomx)                  cube1[1] += abs(randomy)                  cube1[2] += defaultdistance                    if randomx < 0:                      cube1[0] = cube1[0]*-1                  if randomy < 0:                      cube1[1] = cube1[1]*-1                    for f in cube1:                      f -= 0.5                                      cube1.extend([x,y])                  cube2.extend([cube1])                  cube1 = [0,0,0]                    cube2.insert(-1,cube2[1])          cube2.insert(-2,cube2[2])          cube.extend(cube2)          physics.append(cube2)          cube2 = []                    for x in cube:              newcube.extend(x)         for i in range(3):          for t in range(3):              if t != i:                  obj.extend([(physics[i][0][t],physics[i][5][t])])          obj.extend([physics[i][0][i]])          physics1.append(obj)          obj = []                        ##    for i in range(0,len(newcube),6):  ##        physics = [(),(),newcube]      return(newcube , physics1)                defaultdistance = 3     def main():      streak = 0      reach = 5      pointer1 = [0,0,reach]      pointer = pointer1      cubespawnrate = 0.5 #cubes spawned per second      fps = 15 #target fps      sensitivity = -300      x=0      y=1      z=2      pygame.init()      display = [1000,500]      pygame.display.set_mode(display, DOUBLEBUF|OPENGL)      set_fov(45)      set_render_distance(50)      set_view_bearing(0,0,0)      set_cam(0,0,0)      set_aspect_ratio(display[0],display[1])      models1 = []      physics = []      defaultspeed = 3 #in m/s      speed = defaultspeed      multiplier = 1      streak = 0      accellerationresolution = 10      defaultstartlimit = 5      movemmentresolution = fps                 x , phys = createcube()      models1.append(x)      physics.append(phys)      models = []      for t in models1:          models.extend(t)      models2 = []      models2.extend(models)                  for i in range(0,len(models),5):              models2[i:i+3] = final_display_position(models[i:i+3],0,0,0,0,0,0,0,0,0)[0:3]                                            vertex_shader="""      #version 430      in vec3 position;      in vec2 texturecoordinate;      out vec2 texcoordinate;      void main()      {          gl_Position = vec4(position,1.0);          texcoordinate = texturecoordinate;                }      """      fragment_shader="""      #version 430      precision mediump float;      in vec2 texcoordinate;      uniform sampler2D texturergbadata;      out vec4 colour;                  void main()      {          //g =                     colour = texture2D(texturergbadata,texcoordinate);          //colour = vec4(1.0f,1.0f,0.5f,1.0f);      }      """        shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),                                              OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))        VBO=glGenBuffers(1)      glBindBuffer(GL_ARRAY_BUFFER,VBO)      glBufferData(GL_ARRAY_BUFFER,18000,None,GL_STATIC_DRAW)        position = glGetAttribLocation(shader,"position")      glVertexAttribPointer(position, 3, GL_FLOAT, False, 20, ctypes.c_void_p(0))      glEnableVertexAttribArray(position)        width = 200      height = 151        image = Image.open('box.png')        rgbadata = list(image.getdata())      length = len(rgbadata)      newlist = []            for i in range(height):          for s in range(width):              newlist.extend(rgbadata[-2:-1])              rgbadata.pop(-1)        rgbadata.extend(newlist)                 texture = glGenTextures(1)      glBindTexture(GL_TEXTURE_2D, texture)      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,                   GL_UNSIGNED_BYTE, rgbadata)        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)        texturecoordinate = glGetAttribLocation(shader,"texturecoordinate")        glEnableVertexAttribArray(texturecoordinate)        glVertexAttribPointer(texturecoordinate, 2, GL_FLOAT, False, 20,ctypes.c_void_p(12))              texture = glGetUniformLocation(shader, "texturergbadata")      glActiveTexture(GL_TEXTURE0)    ##      ##    colour = glGetAttribLocation(shader,"colour")  ##    glVertexAttribPointer(colour, 3, GL_FLOAT, False, 20, ctypes.c_void_p(12))  ##    glEnableVertexAttribArray(colour)        glEnable(GL_DEPTH_TEST)            glUseProgram(shader)        camx=0      camz=0        glClearColor(0.0, 0.0, 0.0, 1.0)      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)            i=0      escape = 0      debounce = 0      viewdirection = [0,0]      timer = 0            while True:          while escape == 0:              for event in pygame.event.get():                  pass              pygame.mouse.set_visible(True)                            mousex , mousey = pygame.mouse.get_pos()    #           cube spawning                if timer >= fps/cubespawnrate:                  x , phys = createcube()                  models1.append(x)                  physics.append(phys)                  models = []                    for t in models1:                      models.extend(t)                                    models2 = []                  models2.extend(models)                                timer = 0              else:                  timer += 1                      #           speed        ##            for i in physics:  ##                i[2][2] -= speed/movemmentresolution  ##  ##            for t in models1:  ##                for i in range(2,len(t),5):  ##                    t[i] -= speed/movemmentresolution  ##  ##            models = []  ##            for t in models1:  ##                models.extend(t)  ##              ##  ###           acceleration  ##  ##            if speed != speed + accelerate(speed , speed * multiplier , 1):  ##                speed += accelerate(speed , speed * multiplier , accelerationresolution)  ##                length = len(models)                    #           collision detection              objectindex = 0              for i in physics:                  collision = 0                  print(pointer)                  for s in range(3):                      list1 = [0,1,2]                      list1.pop(s)                      try:                          t = i[s][2]/pointer[s]                      except:                          print('no colision')                          continue                                                intersection = list([t*x for x in pointer])                      print(intersection)                      h = 0                      #if math.sqrt((math.sqrt(intersection[0]**2 + intersection[1]**2))**2 + intersection[2]**2) <= reach:                      for p in list1:                          g = intersection[p]                          if g >= i[s][h][0] and g <= i[s][h][1]:                              h += 1                          if h == 2:                              print('we have a collision')                              collision += 1                  if collision >= 1:                          print('deleting',objectindex,'th/nd/rd/st cube')                          print(len(models1),len(physics))                          models1.pop(objectindex)                          physics.pop(objectindex)                          models = []                          for t in models1:                              models.extend(t)                          streak += 1                                    else:                      streak = 0                      multiplier = 1                  objectindex += 1    #           cube deletion                            models2 = []              for i in range(0,len(models),5):                                                                models2.extend(final_display_position(models[i:i+3],0,0,0,0,0,0,0,0,0)[0:3])                      models2.extend(models[i+3:i+5])                                                                          #viewdirection[1],-1*viewdirection[0]              print(len(models),len(models2))              set_view_bearing(0,-1*viewdirection[1],viewdirection[0])              pointer.extend([1])              pointer = list(np.dot(rotation(0,-1*viewdirection[1],viewdirection[0]),pointer1)[0:3])                                               if len(models) > 0:                  models2 = (ctypes.c_float*len(models))(*models2)                  print(len(models))                  glBufferSubData(GL_ARRAY_BUFFER, 0, len(models)*4, models2)                  glDrawArrays(GL_TRIANGLES,0,len(models))                  pygame.display.flip()                  sleep(1/fps/2)                        else:                  glDrawArrays(GL_TRIANGLES,0,0)                  pygame.display.flip()                  sleep(1/fps/2)                  glDrawArrays(GL_TRIANGLES,0,0)                  pygame.display.flip()                                                                                 viewdirection[0] += (mousex - (display[0]/2))/(2-(sensitivity/100))              viewdirection[1] += (mousey - (display[1]/2))/(2-(sensitivity/100))                if viewdirection[0] > 30:                  viewdirection[0] = 30              elif viewdirection[0] < -30:                  viewdirection[0] = -30              if viewdirection[1] > 20:                  viewdirection[1] = 20              elif viewdirection[1] < -20:                  viewdirection[1] = -20                                                       pygame.mouse.set_pos(display[0]/2,display[1]/2)              sleep(1/fps/2)                                                    ##        mousemovementx , mousemovementy = pygame.mouse.get_rel()                                                                      #pygame.mouse.set_pos(int(display[0]/2),int(display[1]/2))              keyspressed = pygame.key.get_pressed()              if keyspressed[K_ESCAPE]:                  print('escape pressed')                  debounce = 1                  print(debounce)              #print(mousex , mousey)              elif keyspressed[K_ESCAPE] == False and debounce > 0:                  print('debounce initiated,halt started')                  escape = 1                  debounce = 0              else:                  debounce = 0                                                   while escape == 1:                                         for event in pygame.event.get():                  pass              pygame.mouse.set_visible(True)              keyspressed = pygame.key.get_pressed()              if keyspressed[K_ESCAPE]:                  print('escape pressed')                  debounce = 1                  print(debounce)              #print(mousex , mousey)              elif keyspressed[K_ESCAPE] == False and debounce > 0:                  print('debounce initiated,halt stopped')                  escape = 0                  debounce = 0              else:                  debounce = 0                            for event in pygame.event.get():              if event.type == KEYDOWN and event.key == K_w:                  camz += 10              elif event.type == KEYDOWN and event.key == K_a:                  camx -= 10              elif event.type == KEYDOWN and event.key == K_s:                  camz -= 10                  print('hello')              elif event.type == KEYDOWN and event.key == K_d:                  camx += 10                             main()                
https://stackoverflow.com/questions/65453155/pyopengl-opengl-weird-ghosting-effect-deleted-triangles-showing-up-even-after-de December 26, 2020 at 10:06AM

没有评论:

发表评论