Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

11

09.10.2012, 15:14

Sind die Koordinaten der Eckpunkte denn exakt die gleichen? Wenn dem so wäre, dürfte es eigentlich keine Kanten geben. Oder vielleicht stimmt was mit den Texturkoordinaten nicht?

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

12

09.10.2012, 15:27

Es liegen immer 2 vertices exakt übereinander. Ich hab also pro Tile 6 vertices. Das muss so sein da ich einen Texturatlas verwende und sonst ein vertice irgendwie w Texturkoordinaten haben müsste. Ich poste später mal Code.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

13

09.10.2012, 15:35

Und wie werden die Koordinaten dieser Vertices berechnet? Steckt auch exakt die gleiche Berechnung dahinter, bzw. wird auch exakt das gleiche Ergebnis zweimal benutzt, oder werden die Koordinaten jeweils neu berechnet? Sobald die Floatwerte nicht aufs letzte Bit übereinstimmen, kann es Probleme geben. Und das kann bei floats schnell passieren, sobald die beiden Werte auch nur durch zwei leicht verschiedene Ausdrücke berechnet werden, auch wenn diese rein mathematisch äquivalent sind, kann es da schon zu Unterschieden kommen. Z.B. weil bestimmte Operationen in anderer Reihenfolge durchgeführt werden und dadurch anders gerundet wird. Angenommen du hast z.B. eine Formel für die linke und eine für die rechte Ecke. Die rechte Ecke des einen Tile entspricht der linken des nächsten Tile. Da du aber zwei verschiedene Ausdrücke hast, wird die rechte Ecke des einen Tile nicht unbedingt exakt der linken Ecke des nächsten Tile entsprechen und schon hast du ein Problem...

Wobei natürlich noch nicht gesagt ist, dass das auch tatsächlich dein Problem hier ist. Wie sehen diese Kanten denn eigentlich aus? Sind sie stark abhängig von der Kameraposition etc.?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (09.10.2012, 15:40)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

14

10.10.2012, 00:31

Also das ganze ist noch pervers hässlich. Aber es funktioniert so weit. Und es kann schon gut sein das es an Präzisionsfehlern liegt.
Nicht zu viel meckern, aber hier:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
void Tilemap3D::create(unsigned int width, unsigned int height, float* heightMap, unsigned int* textureMap){
    m_size[0] = width;
    m_size[1] = height;

    // Anzahl Buffer
    unsigned int buffer[] = {m_size[0]/m_cut[0], m_size[1]/m_cut[1]};

    if(m_cut[0] > m_size[0]){
        buffer[0] = 1;
    }
    else if(m_size[0]%m_cut[0] != 0){
        buffer[0]++;
    }

    if(m_cut[1] > m_size[1]){
        buffer[1] = 1;
    }
    else if(m_size[1]%m_cut[1] != 0){
        buffer[1]++;
    }

    // Buffergröße bestimmen
    m_bufferSize.resize(buffer[0]*buffer[1]);

    for(unsigned int i = 0; i < buffer[0]*buffer[1]; i++){
        m_bufferSize[i] = 0;
    }

    unsigned int column = 0, row = 0;

    for(unsigned int x = 0; x < m_size[0]; x++){
        row = 0;
        
        if(x%m_cut[0] == 0 && x != 0){
            column += buffer[1];
        }

        for(unsigned int y = 0; y < m_size[1]; y++){
            if(y%m_cut[1] == 0 && y != 0){
                row++;
            }
            
            m_bufferSize[column+row]++;
        }
    }

    m_vertices.resize(buffer[0]*buffer[1]);
    m_texCoords.resize(buffer[0]*buffer[1]);
    m_normals.resize(buffer[0]*buffer[1]);

    for(unsigned int i = 0; i < buffer[0]*buffer[1]; i++){
        m_vertices[i].resize(m_bufferSize[i]*6);
        m_texCoords[i].resize(m_bufferSize[i]*6);
        m_normals[i].resize(m_bufferSize[i]*6);
    }
    
    // Buffer befüllen
    column = 0;
    row = 0;
    vertex* triangle = new vertex[4];
    texCoord edge;
    vec2 tc = vec2(1.0f/float(m_textures[0]), 1.0f/float(m_textures[1]));
    vec3 a, b, n;

    for(unsigned int i = 0; i < buffer[0]*buffer[1]; i++){
        m_bufferSize[i] = 0;
    }
    
    for(unsigned int x = 0; x < m_size[0]; x++){
        row = 0;
        
        if(x%m_cut[0] == 0 && x != 0){
            column += buffer[1];
        }

        for(unsigned int y = 0; y < m_size[1]; y++){
            if(y%m_cut[1] == 0 && y != 0){
                row++;
            }

            // Vertex
            triangle[0] = vertex(float(x), float(y), heightMap[x*(m_size[1]+1)+y]);
            triangle[1] = vertex(float(x)+1.0f, float(y), heightMap[(x+1)*(m_size[1]+1)+y]);
            triangle[2] = vertex(float(x), float(y)+1.0f, heightMap[x*(m_size[1]+1)+y+1]);
            triangle[3] = vertex(float(x)+1.0f, float(y)+1.0f, heightMap[(x+1)*(m_size[1]+1)+y+1]);

            m_vertices[column+row][m_bufferSize[column+row]] = triangle[0];
            m_vertices[column+row][m_bufferSize[column+row]+1] = triangle[1];
            m_vertices[column+row][m_bufferSize[column+row]+2] = triangle[2];

            m_vertices[column+row][m_bufferSize[column+row]+3] = triangle[1];
            m_vertices[column+row][m_bufferSize[column+row]+4] = triangle[3];
            m_vertices[column+row][m_bufferSize[column+row]+5] = triangle[2];
            
            // Texturkoordinate
            edge = m_tiles[textureMap[x*m_size[1]+y]];

            m_texCoords[column+row][m_bufferSize[column+row]] = texCoord(edge.s, edge.t-tc.y);
            m_texCoords[column+row][m_bufferSize[column+row]+1] = texCoord(edge.s+tc.x, edge.t-tc.y);
            m_texCoords[column+row][m_bufferSize[column+row]+2] = texCoord(edge.s, edge.t);

            m_texCoords[column+row][m_bufferSize[column+row]+3] = texCoord(edge.s+tc.x, edge.t-tc.y);
            m_texCoords[column+row][m_bufferSize[column+row]+4] = texCoord(edge.s+tc.x, edge.t);
            m_texCoords[column+row][m_bufferSize[column+row]+5] = texCoord(edge.s, edge.t);

            // Normale
            a = vec3(triangle[1].x, triangle[1].y, triangle[1].z)-vec3(triangle[0].x, triangle[0].y, triangle[0].z);
            b = vec3(triangle[2].x, triangle[2].y, triangle[2].z)-vec3(triangle[0].x, triangle[0].y, triangle[0].z);
            n = a.cross(b);
            n.normalize();

            m_normals[column+row][m_bufferSize[column+row]] = vertex(n.x, n.y, n.z);
            m_normals[column+row][m_bufferSize[column+row]+1] = m_normals[column+row][m_bufferSize[column+row]];
            m_normals[column+row][m_bufferSize[column+row]+2] = m_normals[column+row][m_bufferSize[column+row]];

            a = vec3(triangle[1].x, triangle[1].y, triangle[1].z)-vec3(triangle[3].x, triangle[3].y, triangle[3].z);
            b = vec3(triangle[2].x, triangle[2].y, triangle[2].z)-vec3(triangle[3].x, triangle[3].y, triangle[3].z);
            n = a.cross(b);
            n.normalize();

            m_normals[column+row][m_bufferSize[column+row]+3] = vertex(n.x, n.y, n.z);
            m_normals[column+row][m_bufferSize[column+row]+4] = m_normals[column+row][m_bufferSize[column+row]];
            m_normals[column+row][m_bufferSize[column+row]+5] = m_normals[column+row][m_bufferSize[column+row]];
                        
            m_bufferSize[column+row] += 6;
        }
    }

    delete[] triangle;
    
    // Buffer erstellen
    m_vertexBuffer.resize(buffer[0]*buffer[1]);
    m_texCoordBuffer.resize(buffer[0]*buffer[1]);
    m_normalBuffer.resize(buffer[0]*buffer[1]);

    for(unsigned int i = 0; i < m_vertexBuffer.size(); i++){
        glGenBuffers(1, &m_vertexBuffer[i]);
        glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*m_vertices[i].size(), &m_vertices[i][0], GL_STATIC_DRAW);

        glGenBuffers(1, &m_texCoordBuffer[i]);
        glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*m_texCoords[i].size(), &m_texCoords[i][0], GL_STATIC_DRAW);

        glGenBuffers(1, &m_normalBuffer[i]);
        glBindBuffer(GL_ARRAY_BUFFER, m_normalBuffer[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*m_normals[i].size(), &m_normals[i][0], GL_STATIC_DRAW);
    }
}


Wenn euch das zuviel ist sagt was, ich machs euch dann kürzer.
Die beiden Parameter sind Arrays, das für die Texturen ist aXb groß, das für die Höhen (a+1)X(b+1). Erst wird bestimmt wie viele Buffer anhand eines "cuts" benötigt werden. Dann werden die Vertices usw. erstellt und in die passenden Arrays geschrieben. Danach werden noch schlicht die Buffer erstellt.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

15

10.10.2012, 01:50

Hm, also ich vermute mal, dass das eher an falschen Texturkoordinaten liegt. Kann es sein, dass die Farbe der Kanten mit der Farbe der umliegenden Pixel in der Tilemap zu tun hat?

Edit: Nachdem ich mir deinen Screenshop mal in Paint unter der Lupe angeschaut hab, bin ich sogar ziemlich sicher, dass das so ist...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

16

10.10.2012, 10:07

Naja wirklich "falsch" sind sie ja nicht, ich benutze GL_LINEAR für die Textur, kann dann gut sein das z.B. bei einem anliegendem leerem Feld das weiß ist ein Stück mitgenommen wird. Ich probier das mal mit GL_NEAREST.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

17

10.10.2012, 10:36

Mit GL_NEAREST wirst du wohl kaum Freude haben, denn das wird nicht besonders toll aussehen, zumindest wenn deine Kamera frei beweglich ist. Wenn du so einen Look anstrebst, würd ich dir empfehlen, die Kamera auf eine fixe Höhe und Ausrichtung zu beschränken. Wenn du die Höhe variieren willst, solltest du wohl zumindest Mip-Mapping verwenden, was aber mit einer Tile-Map wohl wieder potentiell problematisch ist.

Im Prinzip gibt es zwei Lösungen für dein Problem:

1) Du clampest die Texturkoordinaten manuell im FragmentShader auf den richtigen Bereich.

2) Du machst um jedes Tile in der Tilemap einen einen Pixel breiten Rahmen mit den Farbwerten vom Rand des Tile (also du kopierst jeweils rund um das Tile herum die Farbwerte vom den Randpixeln um einen Pixel nach draußen), dann wird bilineare Interpolation immer die gewünschten Werte liefern.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

18

10.10.2012, 11:13

Ich denke ich versuche das mit den Texturkoordinaten. Eigentlich reicht es ja schon diese einfach einen Pixel immer nach innen zu schieben, also das Quadrat das momentan vom Texturatlas genommen wird etwas kleiner zu machen so das man einen Rand hat.

Wie würde man das im FragmentShader machen?

PS: Bin momentan am Arbeiten und hab daher erst am Wochenende mal richtig Zeit...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

19

10.10.2012, 14:47

Wie würde man das im FragmentShader machen?

Naja, das Problem ist, dass infolge der Rasterisierung, sobald das Dreieck nichtmehr genau am Pixelraster ausgerichtet ist (was bei einer 3D Perspektive wohl praktisch immer der Fall ist), an den Randpixeln Texturkoordinaten entstehen können, die nichtmehr innerhalb deines gewünschten Ausschnittes liegen. Alles was du also tun musst, ist im FragmenShader die Texturkoordinaten auf den gewünschten Ausschnitt zu begrenzen, also wenn sie außerhalb liegen abschneiden...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

20

10.10.2012, 23:04

Achso, hmm naja klingt sehr einfach. Ich guck mal was besser funktioniert ;)
Hoffentlich packt mich morgen nicht wieder die Programmierfaulheit vor der Arbeit...

Werbeanzeige