Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Godot 3.1 telling me that lock() and get_pixel() are nonexistent functions

Tags:

godot

gdscript

I'm attempting to generate a height map from a noise texture. As far as I understand, in order to call get_pixel() on an image in this context, the image must first be locked. However, when I attempt to run the program, it exits with the error: Invalid call. Nonexistent function 'lock' in base 'StreamTexture'.

If I attempt to run it without locking the image, I get the error: Invalid call. Nonexistent function 'get_pixel' in base 'StreamTexture'.

I am certain that the instructions that I am following are for the same version of Godot I am running (3.1), so why is the engine telling me that lock() and get_pixel() are nonexistent functions?

My code is here:

extends Spatial

var width
var height
var heightData = {}
var vertices = PoolVector3Array()
var drawMesh = Mesh.new()

func _ready():
    var noiseTexture = load("res://noiseTexture.png")
    width = noiseTexture.get_width()
    height = noiseTexture.get_height()

    noiseTexture.lock()
    for x in range(0, width):
        for y in range(0, height):
            heightData[Vector2(x,y)] = noiseTexture.get_pixel(x,y).r
    noiseTexture.unlock()

    for x in range(0, width-1):
        for y in range(0, height-1):
            createQuad(x,y)

    var surfTool = SurfaceTool.new()
    surfTool.begin(Mesh.PRIMITIVE_TRIANGLES)

    for i in vertices.size():
        surfTool.add_vertex(vertices[i])

    surfTool.commit(drawMesh)
    $MeshInstance.mesh = drawMesh

func createQuad(x,y):
    #First half
    vertices.push_back(Vector3(x, heightData[Vector2(x,y)], -y))
    vertices.push_back(Vector3(x, heightData[Vector2(x,y+1)], -y-1))
    vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y+1)], -y-1))
    #Second Half
    vertices.push_back(Vector3(x, heightData[Vector2(x,y)], -y))
    vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y+1)], -y-1))
    vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y)], -y))

Any help is greatly appreciated.

EDIT - I have (tried) to implement the changes that were suggested in the comments (yet I still don't know what to do with the color variable) and have attached a screenshot of my resulting code, as well as some comments I have made to try and explain to myself why the process SHOULD be working (I think). It also shows my node structure, which is why I opted to display this as an image. However, when I try to run this, the program crashes with the error displayed.

HeightMap Fail

like image 975
Christopher Bennett Avatar asked Jan 27 '26 03:01

Christopher Bennett


1 Answers

Check the docs; StreamTexture does not have the method lock.

I think the class you are looking to use is Image. The Texture class is typically intended for drawing on the screen or applying to a Material

var noiseImage = Image.new()
noiseImage.load("res://noiseTexture.png")
noiseImage.lock() # Lock the image here
var color = noiseImage.get_pixel(10, 10) # Replace with your height map population

PS:

Just to let you know, I had a lot of issues with memory usage here so make sure you test that also (C# has bad garbage collector though). You might need to dispose of the image, surface tool, and array mesh (If you remove the terrain object) to maintain optimum performance.

like image 56
nathanfranke Avatar answered Jan 28 '26 18:01

nathanfranke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!