I am making a little game in python, which renders cubes. There are unexpected lines between cubes, and they disappear when we get closer.
My code:
# imports
import glfw
from OpenGL.GL import *
from OpenGL.GLU import *
# internal imports
from core.renderer import *
from player import *
from constants import *
if not glfw.init():
raise Exception("glfw can not be initialized!")
if __name__ == "__main__":
window = glfw.create_window(800, 500, "PyCraft", None, None)
glfw.make_context_current(window)
renderer = TerrainRenderer(window)
player = Player(window)
renderer.texture_manager.add_from_folder("assets/textures/block/")
renderer.texture_manager.save("atlas.png")
renderer.texture_manager.bind()
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
if not DEV_MODE and not USING_RENDERDOC:
glEnable(GL_FOG)
glFogfv(GL_FOG_COLOR, (GLfloat * int(8))(0.5, 0.69, 1.0, 10))
glHint(GL_FOG_HINT, GL_DONT_CARE)
glFogi(GL_FOG_MODE, GL_LINEAR)
glFogf(GL_FOG_START, 30)
glFogf(GL_FOG_END, 100)
# get window size
def get_window_size():
width, height = glfw.get_window_size(window)
return width, height
def _setup_3d():
w, h = get_window_size()
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
try:
gluPerspective(70, w / h, 0.1, 1000)
except ZeroDivisionError:
pass
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def _update_3d():
_setup_3d()
glViewport(0, 0, *get_window_size())
storage = TerrainMeshStorage(renderer)
def add_cube(renderer, x, y, z):
X, Y, Z = x + 1, y + 1, z + 1
renderer.add((x, Y, Z, X, Y, Z, X, Y, z, x, Y, z), renderer.texture_manager.get_texture("grass"))
renderer.add((x, y, z, X, y, z, X, y, Z, x, y, Z), renderer.texture_manager.get_texture("dirt"))
renderer.add((x, y, z, x, y, Z, x, Y, Z, x, Y, z), renderer.texture_manager.get_texture("grass_side"))
renderer.add((X, y, Z, X, y, z, X, Y, z, X, Y, Z), renderer.texture_manager.get_texture("grass_side"))
renderer.add((x, y, Z, X, y, Z, X, Y, Z, x, Y, Z), renderer.texture_manager.get_texture("grass_side"))
renderer.add((X, y, z, x, y, z, x, Y, z, X, Y, z), renderer.texture_manager.get_texture("grass_side"))
for x in range(-10, 10):
for z in range(-10, 10):
add_cube(storage, x, -1, z)
renderer.add_mesh(storage)
# mainloop
while not glfw.window_should_close(window):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
if not USING_RENDERDOC:
_update_3d()
glClearColor(0.5, 0.7, 1, 1.0)
if not USING_RENDERDOC:
player.update()
renderer.render()
glfw.poll_events()
glfw.swap_buffers(window)
glfw.terminate()
I expect the output to be a fully solid lime surface but I get these lines as you can see in the screenshot. I have tried using GL_LINE_SMOOTH
among other things, but they don;t work.
As mentioned in an answer here, I found out the solution.
My code for binding the image in the TextureManager
class:
def bind(self):
import pygame
texSurface = pygame.image.load(self.save_path)
texData = pygame.image.tostring(texSurface, "RGBA", 1)
width = texSurface.get_width()
height = texSurface.get_height()
texid = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texid)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, texData)
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_LINEAR)
return texid
I used option 1 in the answer of the linked question, and changed the min filter to GL_NEAREST
instead of GL_LINEAR
.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
-> glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)