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
没有评论:
发表评论