Page 1 of 1

PB 5.11:Memory access error with UpdateTerrainTileLayerBlend

Posted: Sat Jun 29, 2013 9:49 am
by Bananenfreak
Hello,

in my opinion, there is a bug with UpdateTerrainTileLayerBlend(). When you start my first code, there is no memory access error.
In the first code, the terraintexture will changed in the Y-direction. No error occures, the code is running perfectly.
But if you try to run the second code, an memory access error occures. Always on the 2. layer (No. 1) and always at the first cycle of the pyramided For:Next at the end of the code.
The only thing different is that in the second code the terraintexture will changed in X-direction.

PB 5.11, Win XP SP3

EDIT: You can choose any pictures you have for the terraintextures.

Code 1:

Code: Select all

EnableExplicit
;teilX = Tile in X direction
;teilY = Tile in Y direction
;stelle = point where the "action" is; in world units


;_________________
;|       |       |
;|  1/1  |  1/0  |
;|       |       |
;|_______|_______|
;|       |       |
;|  0/1  |  0/0  |
;|       |       |
;|_______|_______|


Structure Vektor3
  x.f
  y.f
  z.f
EndStructure


Global.i terrain, terrainX, terrainY, teilX, teilY, h, X, Y
Global.Vektor3 stelle
Global.f blendWert, ttpointy, ttpointx


#G_Heightmap = 513
#layerAnzahl = 2
#skalFaktor = 5
#weltGroesse = 2


Enumeration
  #Licht_0
EndEnumeration


InitEngine3D()
InitSprite()

OpenScreen(1920, 1080, 32, "Test_Blend_0", #PB_Screen_SmartSynchronization)

;- Licht
CreateLight(#Licht_0 ,RGB(190, 190, 190), 500, 500, 500, #PB_Light_Point)
SetLightColor(#Licht_0, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4)) 
AmbientColor(RGB(255*0.2, 255*0.2,255*0.2))

;- Terrain Definition
SetupTerrains(LightID(#Licht_0), 10, #PB_Terrain_NormalMapping)

terrain = CreateTerrain(#PB_Any, #G_Heightmap, 100, #skalFaktor, #layerAnzahl, "terrain", "Dat")

AddTerrainTexture(terrain, 0, 1, "Gras_0.png", "Gras_0_Normal.png")       ;-Terraintexturen
AddTerrainTexture(terrain, 1, 1, "Steinstrasse_0_1.png", "Steinstrasse_0_1_Normal.png")

TerrainLocate(terrain, 50, 0, 50 + 100 * (#weltGroesse - 1))        ;Gesamtes Terrain wird so positioniert, dass die linke untere Ecke auf 0/0 liegt.

For terrainX = 0 To #weltGroesse - 1
  For terrainY = 0 To #weltGroesse - 1
    DefineTerrainTile(terrain, terrainX, terrainY, "heightmap.png", #False, #False)
  Next
Next

BuildTerrain(terrain)


teilX = 0
teilY = 1
stelle\x = 50
stelle\z = 99.99
stelle\y = TerrainHeight(terrain, stelle\x, stelle\z)
ttpointx = TerrainTilePointX(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)
ttpointy = TerrainTilePointY(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)

For h = 0 To #layerAnzahl - 1       ;1024, weil die LayerBlendmapgröße 1024 beträgt.
  blendWert = GetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024)
  
  If blendWert = 1
    SetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024, 0.0)
  EndIf
Next

SetTerrainTileLayerBlend(terrain, teilX, teilY, 1, ttpointx * 1024, 1024 - ttpointy * 1024, 1.0)


teilX = 0
teilY = 0
stelle\x = 50
stelle\z = 100.01
stelle\y = TerrainHeight(terrain, stelle\x, stelle\z)
ttpointx = TerrainTilePointX(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)
ttpointy = TerrainTilePointY(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)

For h = 0 To #layerAnzahl - 1       ;1024, weil die LayerBlendmapgröße 1024 beträgt.
  blendWert = GetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024)
  
  If blendWert = 1
    SetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024, 0.0)
  EndIf
Next

SetTerrainTileLayerBlend(terrain, teilX, teilY, 1, ttpointx * 1024, 1024 - ttpointy * 1024, 1.0)


For X = 0 To 1
  For Y = 1 To 0 Step -1
    Debug Str(X) + "..." + Str(Y)
    UpdateTerrainTileLayerBlend(terrain, X, Y, 1)       ;-<-- Error, Speicheradresse blablabla.
    UpdateTerrainTileLayerBlend(terrain, X, Y, 0)
  Next Y
Next X

End


Code 2:

Code: Select all

EnableExplicit


Structure Vektor3
  x.f
  y.f
  z.f
EndStructure


Global.i terrain, terrainX, terrainY, teilX, teilY, h, X, Y
Global.Vektor3 stelle
Global.f blendWert, ttpointy, ttpointx


#G_Heightmap = 513
#layerAnzahl = 2
#skalFaktor = 5
#weltGroesse = 2


Enumeration
  #Licht_0
EndEnumeration


InitEngine3D()
InitSprite()

OpenScreen(1920, 1080, 32, "Test_Blend_0", #PB_Screen_SmartSynchronization)

;- Licht
CreateLight(#Licht_0 ,RGB(190, 190, 190), 500, 500, 500, #PB_Light_Point)
SetLightColor(#Licht_0, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4)) 
AmbientColor(RGB(255*0.2, 255*0.2,255*0.2))

;- Terrain Definition
SetupTerrains(LightID(#Licht_0), 10, #PB_Terrain_NormalMapping)

terrain = CreateTerrain(#PB_Any, #G_Heightmap, 100, #skalFaktor, #layerAnzahl, "terrain", "Dat")

AddTerrainTexture(terrain, 0, 1, "Gras_0.png", "Gras_0_Normal.png")       ;-Terraintexturen
AddTerrainTexture(terrain, 1, 1, "Steinstrasse_0_1.png", "Steinstrasse_0_1_Normal.png")

TerrainLocate(terrain, 50, 0, 50 + 100 * (#weltGroesse - 1))        ;Gesamtes Terrain wird so positioniert, dass die linke untere Ecke auf 0/0 liegt.

For terrainX = 0 To #weltGroesse - 1
  For terrainY = 0 To #weltGroesse - 1
    DefineTerrainTile(terrain, terrainX, terrainY, "heightmap.png", #False, #False)
  Next
Next

BuildTerrain(terrain)


teilX = 0
teilY = 1
stelle\z = 50
stelle\x = 99.99
stelle\y = TerrainHeight(terrain, stelle\x, stelle\z)
ttpointx = TerrainTilePointX(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)
ttpointy = TerrainTilePointY(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)

For h = 0 To #layerAnzahl - 1       ;1024, weil die LayerBlendmapgröße 1024 beträgt.
  blendWert = GetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024)
  
  If blendWert = 1
    SetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024, 0.0)
  EndIf
Next

SetTerrainTileLayerBlend(terrain, teilX, teilY, 1, ttpointx * 1024, 1024 - ttpointy * 1024, 1.0)


teilX = 1
teilY = 1
stelle\z = 50
stelle\x = 100.01
stelle\y = TerrainHeight(terrain, stelle\x, stelle\z)
ttpointx = TerrainTilePointX(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)
ttpointy = TerrainTilePointY(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)

For h = 0 To #layerAnzahl - 1       ;1024, weil die LayerBlendmapgröße 1024 beträgt.
  blendWert = GetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024)
  
  If blendWert = 1
    SetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttpointx * 1024, 1024 - ttpointy * 1024, 0.0)
  EndIf
Next

SetTerrainTileLayerBlend(terrain, teilX, teilY, 1, ttpointx * 1024, 1024 - ttpointy * 1024, 1.0)


For X = 0 To 1
  For Y = 1 To 0 Step -1
    Debug Str(X) + "..." + Str(Y)
    UpdateTerrainTileLayerBlend(terrain, X, Y, 1)       ;-<-- Error, Speicheradresse blablabla.
    UpdateTerrainTileLayerBlend(terrain, X, Y, 0)
  Next Y
Next X

End


Greets,

Bananenfreak

Re: PB 5.11:Memory access error with UpdateTerrainTileLayerB

Posted: Fri Jul 05, 2013 9:56 am
by Bananenfreak
Could someone confirm the problem, please? Thanks.

Re: PB 5.11:Memory access error with UpdateTerrainTileLayerB

Posted: Fri Jul 05, 2013 9:54 pm
by Comtois

Code: Select all

    UpdateTerrainTileLayerBlend(terrain, X, Y, 0)
layer should be 1 or higher (since bottom layer has no blending). If Layer = 0, PB does nothing.

Code: Select all

SetTerrainTileLayerBlend(terrain, teilX, teilY, 1, ttpointx * 1024, 1024 - ttpointy * 1024, 1.0)
x and y must be smaller than the size of the image texture. You can get the size of the image with the function TerrainTileLayerMapSize(terrain, tx, ty)

Code: Select all

Size = TerrainTileLayerMapSize(0, tx, ty)

Re: PB 5.11:Memory access error with UpdateTerrainTileLayerB

Posted: Sat Jul 06, 2013 9:36 am
by Bananenfreak
Thank you for your reply.

1. I don´t understand, why the layer has to be 1 or higher? First Layer is 0?!

2. I´m searching for the problem in my code.

Code: Select all

ttPoint\x = TerrainTilePointX(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)
          ttPoint\y = TerrainTilePointY(terrain, teilX, teilY, stelle\x, stelle\y, stelle\z)
          
          blendWert = GetTerrainTileLayerBlend(terrain, teilX, teilY, h, ttPoint\x * 1024, 1024 - ttPoint\y * 1024)


TerrainTilePointX/Y() returns a value between 0 and smaller 1...

3. Thank you, i have missed the forest for the trees :D

Solution: I changed the value 1024 to 1023 and it works fine. But I don´t understand, what you mean with
layer should be 1 or higher (since bottom layer has no blending). If Layer = 0, PB does nothing.
Could you please send me a PM?
Thread can be closed, sorry, my mistake :)

Re: PB 5.11:Memory access error with UpdateTerrainTileLayerB

Posted: Sun Jul 07, 2013 9:15 am
by Bananenfreak
Ah, i got it last night (:D). For the first Layer (no. 0) it´s equal if its blendvalue is 1 or 0 no one cares, because the layers above are higher in rank. You can only see the first layer if the others all have a blendvalue of 0.

In my case, but in others, where the first layer has a blendvalue of 0.5 and the others, too, you can see all layers.

So, why the first layer should have no blending?!

Re: PB 5.11:Memory access error with UpdateTerrainTileLayerB

Posted: Mon Jul 08, 2013 10:44 am
by Comtois
Bananenfreak wrote:In my case, but in others, where the first layer has a blendvalue of 0.5 and the others, too, you can see all layers.
You can change the first layer from 0 to 1, you will get the same result.
So, why the first layer should have no blending?!
Ogre blend layer n+1 with layer n. So Layer 0 has nothing to blend

Re: PB 5.11:Memory access error with UpdateTerrainTileLayerB

Posted: Mon Jul 08, 2013 9:11 pm
by Comtois
Each layer after the first layer in a terrain has a blend map which expresses how it is alpha blended with the layers beneath. Internally, this blend map is packed into one channel of an RGB or RGBA texture in order to use the smallest number of samplers, but this class allows a caller to manipulate the data more easily without worrying about this packing. Also, the values you use to interact with the blend map are floating point, which gives you full precision for updating, but in fact the values are packed into 8-bit integers in the actual blend map.
Extracted from
http://www.ogre3d.org/docs/api/html/cla ... ndMap.html