Repeating OpenGL-es texture bound to hills in cocos2d 2.0

人盡茶涼 提交于 2019-11-28 20:45:22

The triangle strip you generate for the visible part of the terrain will have texture coordinates which increase from left to right. When these get very large, you will have precision issues.

For your UV coordinates, you need to subtract the same value from all the coordinates in your triangle strip. Generally, take the integer part of the lowest coordinate (probably the far-left or first coordinate in your case), and subtract that from all the UVs you generate. Or use it as a baseline to generate the others, whichever you prefer.

So if the left hand side of the screen has a U value of 100.7 and the right hand side has a U value of 129.5, you actually want to output values ranging from 0.7 to 29.5. (if you still have precision issues, you might squeak out a bit more by centring the range on zero, using negative co-ords).

The alternative, if you need to have a discontinuity in the texture coordinates within a single strip, and to get maximum precision, is to introduce degenerate triangles, which are zero-area, and thus don't get rendered, while you change the tex-coords. You do that by repeating vertices, but with the adjusted tex-coords, before continuing.

Based on your code above, I'd suggest something like this:

// This line should happen only once per-strip. 
float U_Off = floor(pt0.x / 512);

// The inner loop then looks like this:
for (int j=1; j<hSegments+1; j++) {
    pt1.x = p0.x + j*dx;
    pt1.y = ymid + ampl * cosf(da*j);
    _borderVertices[_nBorderVertices++] = pt1;
    float xTex0 = pt0.x/512 - U_Off;
    float xTex1 = pt1.x/512 - U_Off;

    _hillVertices[_nHillVertices] = CGPointMake(pt0.x, 0);
    _hillTexCoords[_nHillVertices++] = CGPointMake(xTex0, 1.0);
    _hillVertices[_nHillVertices] = CGPointMake(pt1.x, 0);
    _hillTexCoords[_nHillVertices++] = CGPointMake(xTex1, 1.0);

    _hillVertices[_nHillVertices] = CGPointMake(pt0.x, pt0.y);
    _hillTexCoords[_nHillVertices++] = CGPointMake(xTex0, 0.0);
    _hillVertices[_nHillVertices] = CGPointMake(pt1.x, pt1.y);
    _hillTexCoords[_nHillVertices++] = CGPointMake(xTex1, 0.0);

    pt0 = pt1;
}

This is just my guess... Not a solution, but a possible explanation.

I tried to trace how you are generating your mesh. At first I though you were doing some kind of intentional degeneration (as you are using a triangle strip, and using 4 vertices for each 2 triangles). But you are creating your mesh like this, right?.

3 ___ 4-7___ 8
| \    | \   |
|  \   |  \  |
1 ___ 2-5 __ 6

This creates triangles 123, [234], 345, [456], 567, [678]... and so on (note [] means reversed). So, you see that you are overlapping half of the triangles. I suppose the last triangle drawn is seen and the other is hidden... providing z is exactly 0 you are not having any artifact. When 4 = 7, and 2 = 5, which is when you are not modifying your texutre coordinate, everything works fine, as that, one way or another reduces to the following (which would be the correct way of doing it if you traspose it - acbdef). Translated to coordinates - same coordinate, same point it's like this:

c ___ d ___ f
| \   | \   |
|  \  |  \  |
a ___ b ___ e

In the log you posted, you write 4 points at a time, right? So, in the 13th cycle of the "for" you generate this vertexes: (14*3 = 52):

    [52]    CGPoint (x=0.939453,y=1) //1
    [53]    CGPoint (x=1.00586,y=1)  //2
    [54]    CGPoint (x=0.939453,y=0) //3
    [55]    CGPoint (x=1.00586,y=0)  //4

    [56]    CGPoint (x=0.00585938,y=1) //5

That makes 5 triangles. In particular 2 are of interest here: [234] and 345. 234 is ok, but 345 must be hiding it (because it renders after the other¿?. Try using an depth test function like GL_GREATER just to avoid it to render and see if i'm right on this one). Well, 345 is not right, it maps the texture from x= 0.07 to 1.00. So, even if you corrected 234, 345 is still drawn over your correct triangle. That should explain your background reversed thing.

So, that was what i think is the problem (wouldn't happen if you didn't normalize your texture coordinates like in the tutorial).

Do I still have to write the solution?? :/

To begin with, I'd suggest you generated your mesh like what i draw at second place (a,b,c...). Then continue with a solution. A dirty solution would be to degenarte the evil triangle 345. That would be to repeat point 4 one time (i'm a little dizzy rigth now, could be wrong )- Anyway this is not a good solution, you are mixing orientations and overlapping triangles. Each for iteration you should only add

        _hillVertices[_nHillVertices] = CGPointMake(pt0.x, 0);
        _hillTexCoords[_nHillVertices++] = CGPointMake(xTex0, 1.0);

        _hillVertices[_nHillVertices] = CGPointMake(pt0.x, pt0.y);
        _hillTexCoords[_nHillVertices++] = CGPointMake(xTex0, 0.0);

Let me think a clean solution, or let somebody write it for me - Providing this is in fact, the problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!