A new look at texture mapping geomipterrain - same old prob

I realize Praios has a similar thread going, but he is using a different approach, and I don’t really understand how to use the code he posted.

Simply put, I’m trying to map textures to a geomipterrain using a grayscale “alpha” map.

Starting with code rdb (pro-rsoft) posted a while back: codepad.org/agsXeq6y I can get partway there. The issue is once I go past a certain number of textures it errors out. I have been told that as long as I enable the Shader Generator there should not be a hardware limitation.

Here is the output from 1 too many textures:

DirectStart: Starting the game.
Known pipe types:
  glxGraphicsPipe
(all display modules loaded.)
:gobj(error): created-shader: (20) : error C5102: output semantic attribute "TEXCOORD" has too big of a numeric index (8)
:gobj(error): created-shader: (22) : error C5102: output semantic attribute "TEXCOORD" has too big of a numeric index (9)
:gobj(error): created-shader: (23) : error C5102: input semantic attribute "TEXCOORD" has too big of a numeric index (8)
:gobj(error): Shader encountered an error.
:gobj(error): created-shader: (20) : error C5102: output semantic attribute "TEXCOORD" has too big of a numeric index (8)
:gobj(error): created-shader: (22) : error C5102: output semantic attribute "TEXCOORD" has too big of a numeric index (9)
:gobj(error): created-shader: (23) : error C5102: input semantic attribute "TEXCOORD" has too big of a numeric index (8)
:gobj(error): created-shader: (20) : error C5041: cannot locate suitable resource to bind parameter "l_eye_position"
:gobj(error): created-shader: (22) : error C5041: cannot locate suitable resource to bind parameter "l_eye_normal"

I’m using a function for adding texture to ensure I’m adding each texture the same way every time. Here is my current testing code. I’ve tried to make it as clean, short, and easy to read as possible. Near the bottom you can see where I add lights and textures. Any 4 of the textures alone will work, any 3 textures plus one or both lights work. More than that and I get the errors above.

import direct.directbase.DirectStart


from pandac.PandaModules import *

render.setShaderAuto()


def addtex(texture, alpha, stage, SORT):
	ts =  TextureStage(stage)
	ts.setSort(SORT)
	ts.setMode(TextureStage.MReplace)
	root.setTexture(ts, texture)
	root.setTexScale(ts, 32, 32)

	stage2 = stage + "-alpha"
	
	ts = TextureStage(stage2)
	ts.setSort(SORT + 5)
	root.setTexture(ts, alpha)
	ts.setCombineRgb(TextureStage.CMInterpolate, TextureStage.CSPrevious, TextureStage.COSrcColor,
											 TextureStage.CSLastSavedResult, TextureStage.COSrcColor,
											 TextureStage.CSTexture, TextureStage.COSrcColor)
	ts.setSavedResult(True)


# lights
ambient = Vec4(0.34, 0.3, 0.3, 1)
alight = AmbientLight('alight')
alight.setColor(ambient)
alnp = render.attachNewNode(alight)

dlight = DirectionalLight('dlight')
dlight.setColor(VBase4(0.8, 0.8, 0.5, 1))
dlnp = render.attachNewNode(dlight)
dlnp.setHpr(0, -60, 0)


# Set up the GeoMipTerrain
terrain = GeoMipTerrain("genTerrain")
terrain.setHeightfield("land_test_Heightmap.png")
terrain.setBlockSize(64)
terrain.setBruteforce(1)		 
		
# Store the root NodePath for convenience
root = terrain.getRoot()
root.reparentTo(render)
root.setScale(2)
root.setSz(200)
terrain.generate()

######  Load textures and alpha maps
tex0 = loader.loadTexture('land_test_Mat_all.jpg')
tex1 = loader.loadTexture('land_test_Mat_1a.png')
tex2 = loader.loadTexture('land_test_Mat_2a.png')
tex3 = loader.loadTexture('land_test_Mat_3a.png')
tex4 = loader.loadTexture('land_test_Mat_4a.png')
tex5 = loader.loadTexture('land_test_Mat_5a.png')
tex6 = loader.loadTexture('land_test_Mat_6a.png')
tex7 = loader.loadTexture('land_test_Mat_7a.png')

alp1 = loader.loadTexture('land_test_Alpha_1a.png')
alp2 = loader.loadTexture('land_test_Alpha_2a.png')
alp3 = loader.loadTexture('land_test_Alpha_3a.png')
alp4 = loader.loadTexture('land_test_Alpha_4a.png')
alp5 = loader.loadTexture('land_test_Alpha_5a.png')
alp6 = loader.loadTexture('land_test_Alpha_6a.png')
alp7 = loader.loadTexture('land_test_Alpha_7a.png')


#### Any combination of 4 or less textures
#### or 3 textures plus lighting (1 or both) works

render.setLight(alnp)
render.setLight(dlnp)

addtex(tex1, alp1, "stage1", 10)
addtex(tex2, alp2, "stage2", 20)
addtex(tex3, alp3, "stage3", 30)
addtex(tex4, alp4, "stage4", 40)
addtex(tex5, alp5, "stage5", 50)
addtex(tex6, alp6, "stage6", 60)
addtex(tex7, alp7, "stage7", 70)

run()

My Config.prc (minus white-space and commented lines), I’ve played around with settings, this is how it currently is.

load-display pandagl
win-origin 50 50
win-size 800 600
fullscreen #f
framebuffer-hardware #t
framebuffer-software #f
depth-bits 1
color-bits 1
alpha-bits 1
stencil-bits 1
multisamples 1
notify-level warning
default-directnotify-level warning
model-path    $MAIN_DIR
model-path    /usr/share/panda3d
model-path    /usr/share/panda3d/models
want-directtools  #f
want-tk           #f
want-pstats            #f
show-frame-rate-meter  #t
audio-library-name p3openal_audio
use-movietexture #t
hardware-animated-vertices #f
model-cache-dir $USER_APPDATA/.panda3d/cache
model-cache-textures #f
basic-shaders-only #f
sync-video #f

Python 2.6.5
Panda3d 1.7.0
Linux Mint 9 (ubuntu 10.4)
nVidia GTS250

I can try to post links to the images, but in my testing any grayscale images for heightmap and alpha maps, and any color images for textures all do the same thing.

in my code i put an individual texture on each tile - no multitexturing so there is still room for bumpmaps and the like.
its not exactly fast but its simple, i think.
i commented my code so its hopefully more understandeable.

Right - manually placing individual textures on each tile may be the only option to get past what appears to be an 8 texture stages limitation. I’m hoping there is an easy way around this limitation based on past comments in other threads. Using this basic process it’s easy for me to conceptualize - simply lay down a new texture over everything, then use an alpha map to select between the new texture and the previously saved texture stage texture. It automatically handles scaling of the alpha map, blending gray area edges between textures, and more important, scaling/tiling of the texture. The setTexScale() is really handy.

Ultimately, I want to texture each tile of a geomipterrain with a properly scaled texture based on an alpha map. Then blend a full map texture on top of that. Using a generated full map texture from L3DT really adds a lot of depth and realism as well as blending away the obvious patterns from repeating textures, and still allows the detail from individual textures. Finally, things such as roads and other non-terrain generator features will replace/overlay existing textures, also based on alpha maps.

I’ll take another look at your code Praios and see if I can understand it. I’m being stubborn and not moving on until I get this resolved. It’s also a big part of why I took a break during the summer and haven’t looked at panda3d anything for months.