所以在这个网站的帮助下,我最近用pygame/pyopengl做了一个2d水模拟。我现在开始用我做的水纹理来纹理这个水模拟。但是,当我尝试这样做的时候,纹理似乎无论我做什么都不能正确地显示出来。它是在那里,但是它是伸展的和无序的。我想让纹理平铺而不被打破,我怎么才能得到它呢?
这是我的代码:
import pygame
import random
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
def loadTexture():
textureSurface = pygame.image.load('test_image.png')
textureData = pygame.image.tostring(textureSurface, "RGBA", 1)
width = textureSurface.get_width()
height = textureSurface.get_height()
glEnable(GL_TEXTURE_2D)
texid = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texid)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, textureData)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
return texid
def draw_water(polygon_points):
glBegin(GL_POLYGON)
for i in polygon_points:
glTexCoord2f(*i)
glVertex2f(*i)
glEnd()
class surface_water_particle():
def __init__(self, x,y):
self.x_pos = x
self.y_pos = y
self.target_y = y
self.velocity = 0
self.k = 0.04
self.d = 0.08
self.time = 1
def update(self):
x = self.y_pos - self.target_y
a = -(self.k * x + self.d * self.velocity)
if self.y_pos > self.target_y:
self.y_pos -= 0.1
if self.y_pos < self.target_y:
self.y_pos += 0.1
self.velocity = round(self.velocity)
self.y_pos += self.velocity
self.velocity += a
self.time += 1
class water_tile():
def __init__(self, x_start, x_end, y_start, y_end, segment_length):
self.springs = []
self.x_start = x_start
self.y_start = y_start
self.x_end = x_end
self.y_end = y_end - 10
for i in range(abs(x_end - x_start) // segment_length):
self.springs.append(surface_water_particle(i * segment_length + x_start, y_end))
def update(self, spread):
passes = 4 # more passes = more splash spreading
for i in range(len(self.springs)):
self.springs[i].update()
leftDeltas = [0] * len(self.springs)
rightDeltas = [0] * len(self.springs)
for p in range(passes):
for i in range(0, len(self.springs)):
if i > 0:
leftDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i - 1].y_pos)
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs):
rightDeltas[i] = spread * (self.springs[i].y_pos - self.springs[(i + 1)%len(self.springs)].y_pos)
self.springs[(i + 1)%len(self.springs)].velocity += rightDeltas[i]
for i in range(0, len(self.springs)):
if round (leftDeltas[i],12) == 0 or round (rightDeltas[i],12) == 0:
self.springs[i - 1].y_pos = self.y_end+10
if i > 0:
self.springs[i - 1].y_pos += leftDeltas[i]
if i < len(self.springs):
self.springs[(i + 1)%len(self.springs)].y_pos += rightDeltas[i]
def splash(self, index, speed):
if index >= 0 and index < len(self.springs):
self.springs[index].velocity = speed
def draw(self):
water_surface = pygame.Surface((abs(self.x_end-self.x_start), abs(self.y_start - self.y_end)), depth=8).convert_alpha()
water_surface.fill((0,0,0,100))
water_surface.set_colorkey((0,0,0,0))
polygon_points = []
polygon_points.append((self.x_start, 360-self.y_start))
for spring in range(len(self.springs)):
polygon_points.append((self.springs[spring].x_pos, 360-self.springs[spring].y_pos))
polygon_points.append((self.springs[len(self.springs) - 1].x_pos, 360-self.y_start))
return polygon_points
class water_object:
def __init__(self, x_start, x_end, y_start, y_end, segment_length, x_pos, y_pos):
self.water = water_tile(x_start,x_end,y_start,y_end,segment_length)
def update(self):
self.water.update(0.1)
self.polypoints = self.water.draw()
water_list = [water_object(0,276+16,64,0,16,0,20)]
def main():
pygame.init()
display = (640, 360)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, display[0], 0, display[1], -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
loadTexture()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == MOUSEBUTTONDOWN:
print (len(water.water.springs))
water.water.splash(random.randint(0, len(water.water.springs) - 1),50)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
for water in water_list:
water.update()
draw_water(water.polypoints)
pygame.display.flip()
pygame.time.wait(10)
if __name__ == "__main__":
main()
贝娄是我的纹理
1条答案
按热度按时间envsm3lx1#
如果你想用颜色填充水线下的区域,那么我建议生成一个
GL_TRIANGLE_STRIP
图元:请参见示例: