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

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

21

10.10.2013, 11:45

Ja ich möchte den Text Rendern, soweit hast du das richtig verstanden. Jetzt stimmt das sieht wirklich richtig aus, muss mich wohl mal wieder Verlesen haben. :dash: Das mit der UV Koordinaten muss ich mir wohl noch einmal angucken.
Was mich halt immer noch wundert ist das wenn jetzt sogar die Buffer stimmen, warum ich immer noch nichts sehe.

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

22

10.10.2013, 15:23

Versuch das ganze einfach noch mal von einfach zu komplex aufzubauen. Mal eine Linie oder sonst etwas bevor du "echte" Daten in die Buffer schreibst.
Renderst du überhaupt orthogonal oder wo soll der Text am Ende stehen? Zeig mal deine Renderfunktion dazu bitte. Ansonsten sieht mir dein Vorhaben etwas komisch aus. Willst du für jeden Buchstaben eine Textur verwenden oder wie kommst du auf so komische UV Koordinaten?
Naja wenn du möchtest schicke ich dir mal meine Textausgabe (2D) mit einem Texturatlas. Code lesen hilft dann ja doch des öfteren. Mein Ergebnis sieht so aus:


(Link)


Wenn du auf das Spielbrett oder in 3D rendern willst lässt sich das noch relativ leicht erweitern.

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

23

10.10.2013, 15:43

Das mit den UV Koordinaten hat sich geklärt. War ein einfacher Additions Fehler.
Ich möchte den Text fürs erste einfach nur in die Mitte des Screens in den 3D Raum rendern.
Meine Renderfunktion sieht so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void TextClass::RenderBuffer ()
{
    // Bind the vertex array object that stored all the information about the vertex and index buffers.
    OpenGL->glBindVertexArray(m_vertexArrayId);

    // Render the vertex buffer using the index buffer.
    glDrawElements(GL_QUADS, m_indexCount, GL_UNSIGNED_INT, 0);
    return;
}

So soll bei mir am Ende auch eigentlich aussehen. Menn du mir einmal deine Textausgabe schicken würdest wäre das sehr nett.

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

24

10.10.2013, 22:55

Hmm da fehlt doch noch einiges?
Textur muss gebunden werden, Shader muss gebunden werden (bin mir nicht sicher ob fixed function pipeline sonst genommen wird), alle arrays binden (ist das nur eins?), an Shader übergeben usw.

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
        m_shader->bind();
        m_shader->enableVertexAttribArrays(); // aktiviert alle

        for(std::vector<bb::Entity*>::iterator i = m_entities.begin(); i != m_entities.end(); i++){ // ignorieren
            sprite = static_cast<bb::Sprite*>((*i)->getComponent("Sprite")); // ignorieren

            if(sprite->m_visible && sprite->m_camera && sprite->m_mesh && sprite->m_texture){ // ignorieren
                sprite->calculateModelMatrix(); // Verschiebung, Skalierung, ...
                sprite->m_camera->calculateOrthoMatrix(); // zum orthogonalem rendern

                sprite->m_texture->bind(GL_TEXTURE0); // Textur
                m_shader->sendUniform4x4("pmv", (sprite->m_camera->m_orthoMatrix*sprite->m_modelMatrix).getArray()); // Matrizen übergeben (kombiniert projection*model*view)
                m_shader->sendUniform("texture0", 0); // Textur an Shader binden

                sprite->m_mesh->getIndexBuffer()->bind(); // alle Buffer binden (auch an Shader)
                sprite->m_mesh->getVertex2Buffer()->bind();
                sprite->m_mesh->getVertex2Buffer()->vertexAttribPointer(m_shader->getAttribLocation("vertex0"), 2, GL_FLOAT, false, 0, 0);
                sprite->m_mesh->getTexCoordBuffer()->bind();
                sprite->m_mesh->getTexCoordBuffer()->vertexAttribPointer(m_shader->getAttribLocation("texCoord0"), 2, GL_FLOAT, false, 0, 0);

                glDrawElements(GL_TRIANGLES, sprite->m_mesh->getIndexCount(), GL_UNSIGNED_INT, 0); // renderaufruf

                sprite->m_texture->unbind();
            }

            sprite = 0; // ignorieren
        }

        m_shader->disableVertexAttribArrays();
        m_shader->unbind();


Was die entsprechenden Methodenaufrufe für OpenGL Funktionen aufrufen ist denke ich klar...

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

25

10.10.2013, 23:50

Ok jetzt bin ich langsam überfragt.
Wenn ich irgendwo völligen Quatsch gemacht habe sag mir das bitte. Bin dem Tutorial bis jetzt immer so halb blind gefolgt und das ist das erste was ich etwas wirklich auf eigene Faust in OpenGL schreibe.
Als allererstes mache ich aus dem Text Vertexes mit UV-Koordinaten. Die werden dann in einen Vektor geschrieben. Jeder Buchstabe bekommt eine Struktur in der X,Y,Z,U,V als float Arrays liegen.

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
bool TextClass::CreateText ()
{
    //local
    float width = this->PosX;
    Windowsize* wz = Input->GetWindowsize ();

    for (unsigned int i = 0; i < Text.size(); i++)
    {
        char Symbol;
        TextModel* Model;

        Symbol = Text[i];
        for (unsigned int z = 0; z < TextUVdata.size(); z++)
        {
            if (Symbol == TextUVdata[z]->symbol)
            {
                Model = new TextModel;
                Model->Symbol = Symbol;

                //Point 1
                Model->x[0] = width;
                Model->y[0] = this->PosY;
                Model->z[0] = this->PosZ + TextUVdata[z]->hight * wz->Pixel_in_float_height;
                Model->u[0] = TextUVdata[z]->x;
                Model->v[0] = TextUVdata[z]->y + TextUVdata[z]->h;
                //Point 2
                Model->x[1] = width;
                Model->y[1] = this->PosY;
                Model->z[1] = this->PosZ;
                Model->u[1] = TextUVdata[z]->x;
                Model->v[1] = TextUVdata[z]->y;
                //Point 3
                Model->x[2] = width + TextUVdata[z]->width * wz->Pixel_in_float_width;
                Model->y[2] = this->PosY;
                Model->z[2] = this->PosZ;
                Model->u[2] = TextUVdata[z]->x + TextUVdata[z]->w;
                Model->v[2] = TextUVdata[z]->y;
                //Point 4
                Model->x[3] = width + TextUVdata[z]->width * wz->Pixel_in_float_width;
                Model->y[3] = this->PosY;
                Model->z[3] = this->PosZ + TextUVdata[z]->hight * wz->Pixel_in_float_height;
                Model->u[3] = TextUVdata[z]->x + TextUVdata[z]->w;
                Model->v[3] = TextUVdata[z]->y + TextUVdata[z]->h;
                

                //Set new width
                width = width + TextUVdata[z]->width * wz->Pixel_in_float_height;
            }
        }
        Textmodel.push_back(Model);
    }
    return true;
}

Da nach wird der Vektor wieder ausgelesen und die Vertexe und UV-Koordinaten werden mit Normalen versehen und wieder in einer Struktur gepackt. Etwas anders wird der Indexbuffer gehandhabt der ist ein einfaches unsigned int Array. Die Daten werden dann als VBO gebunden und danach noch einmal an den Shader übergeben. Zum Schluss kommt noch der Indexbuffer.

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
bool TextClass::CreateBuffer ()
{
    VertexType* vertices;
    unsigned int* indices;

    int m_vertexCount = this->Textmodel.size () *4;
    this->m_indexCount = this->Textmodel.size () *4;

    // Create the vertex array.
    vertices = new VertexType[m_vertexCount];
    if(!vertices)
    {
        return false;
    }

    // Create the index array.
    indices = new unsigned int[m_indexCount];
    if(!indices)
    {
        return false;
    }

    // Load the vertex array and index array with data.
    unsigned int c = 0;
    int t = 0;
    while (c < this->Textmodel.size ())
    {
        for (int z = 0; z < 4; z++)
        {
            vertices[t].x  = Textmodel[c]->x[z];
            vertices[t].y  = Textmodel[c]->y[z];
            vertices[t].z  = Textmodel[c]->z[z];
            vertices[t].tu = Textmodel[c]->u[z];
            vertices[t].tv = Textmodel[c]->u[z];
            vertices[t].nx = 0;
            vertices[t].ny = 1;
            vertices[t].nz = 0;

            indices[t] = t;
            t = t + 1;
        }
        c = c + 1;
    }

    // Allocate an OpenGL vertex array object.
    OpenGL->glGenVertexArrays(1, &m_vertexArrayId);

    // Bind the vertex array object to store all the buffers and vertex attributes we create here.
    OpenGL->glBindVertexArray(m_vertexArrayId);

    // Generate an ID for the vertex buffer.
    OpenGL->glGenBuffers(1, &m_vertexBufferId);

    // Bind the vertex buffer and load the vertex (position, texture, and normal) data into the vertex buffer.
    OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
    OpenGL->glBufferData(GL_ARRAY_BUFFER, m_vertexCount * sizeof(VertexType), vertices, GL_STATIC_DRAW);

    // Enable the three vertex array attributes.
    OpenGL->glEnableVertexAttribArray(0);  // Vertex position.
    OpenGL->glEnableVertexAttribArray(1);  // Texture coordinates.
    OpenGL->glEnableVertexAttribArray(2);  // Normals.

    // Specify the location and format of the position portion of the vertex buffer.
    OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
    OpenGL->glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(VertexType), 0);

    // Specify the location and format of the texture coordinate portion of the vertex buffer.
    OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
    OpenGL->glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(VertexType), (unsigned char*)NULL + (3 * sizeof(float)));

    // Specify the location and format of the normal vector portion of the vertex buffer.
    OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
    OpenGL->glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(VertexType), (unsigned char*)NULL + (5 * sizeof(float)));

    // Generate an ID for the index buffer.
    OpenGL->glGenBuffers(1, &m_indexBufferId);

    // Bind the index buffer and load the index data into it.
    OpenGL->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferId);
    OpenGL->glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount* sizeof(unsigned int), indices, GL_STATIC_DRAW);
    
    // Now that the buffers have been loaded we can release the array data.
    delete [] vertices;
    vertices = 0;

    delete [] indices;
    indices = 0;

    return true;
}

Habe ich das so richtig verstanden oder mache ich einen Fehler?
So nun zum Rendern. Als erstes als erstes übergebe ich meiner TextureUnitClass die Worldmatrix, die Art mit welchem Shader ich arbeiten möchte(sind im Moment nur zwei, einer der nur Farben verarbeitet und einer der die fixed Pipeline darstellt) und zum Schluss kommt der Textureunit. Ist auch das so richtig oder macht man das anders, bzw. geht das vielleicht so gar nicht? Hab da nehmlich noch so ein Problem, was sich vielleicht gleich mit lösen lässt :D. Danach wir die eigentliche RenderFunktion aufgerufen die die Buffer rendern sollte.

C-/C++-Quelltext

1
2
3
4
5
6
void TextClass::Render (float* worldmatrix)
{
    TextureUnit->Render (worldmatrix, ShaderLight, Unit);
    RenderBuffer ();
    return;
}

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void TextClass::RenderBuffer ()
{
    // Bind the vertex array object that stored all the information about the vertex and index buffers.
    OpenGL->glBindVertexArray(m_vertexArrayId);

    // Render the vertex buffer using the index buffer.
    glDrawElements(GL_QUADS, m_indexCount, GL_UNSIGNED_INT, 0);
    return;
}

Wenn wir schon grade dabei sind, jetzt einmal angenommen das sei kein Text sondern iergent etwas anders, ein Gegner zum Beispiel. Der müsste sich ja bewegen müssen, wie würde ich am besten ein Objekt verschieben oder drehen? Eine neu Matrix anlegen die manipulieren und dann mit der Worldmatrix multiplizieren? Oder mach man das anders besser?
Zum Schluss wird aufgeräumt und die Buffer wieder gelert.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void TextClass::ShutdownBuffers()
{
    // Disable the two vertex array attributes.
    this->OpenGL->glDisableVertexAttribArray(0);
    this->OpenGL->glDisableVertexAttribArray(1);
    
    // Release the vertex buffer.
    this->OpenGL->glBindBuffer(GL_ARRAY_BUFFER, 0);
    this->OpenGL->glDeleteBuffers(1, &m_vertexBufferId);

    // Release the index buffer.
    this->OpenGL->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    this->OpenGL->glDeleteBuffers(1, &m_indexBufferId);

    // Release the vertex array object.
    this->OpenGL->glBindVertexArray(0);
    this->OpenGL->glDeleteVertexArrays(1, &m_vertexArrayId);

    return;
}

Ich glaube das war jetzt alles. Ich danke dir noch einmal sehr dafür das du dir Zeit genommen hast und mir hilfst.
Lg Volker

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

26

11.10.2013, 12:13

Ich würde dir empfehlen dir das ganze noch mal anzusehen. Nicht deinen Code den du jetzt hast sondern allgemein das Konzept dahinter.
Ich möchte dir ja keine Komplettlösungen geben, deshalb auch immer nur die Code ausschnitte, aber das du z.B. nur eine ID für deine Buffer hast (m_vertexArrayId) ist schon mal blödsinn. Zudem löscht du in deiner ShutdownBuffers Methode die Buffer komplett und entbindest sie nicht nur... (es sieht so aus als wolltest du diese im render call aufrufen, machst du aber auch nicht).
Das ganze ist also noch durcheinander und unvollständig.

Hier noch mal das allgemeine vorgehen:

1. Daten laden/generieren: aus Datei oder so wie du es gerade möchtest generiert und in arrays schreiben.
2. Buffer erstellen und füllen:

C-/C++-Quelltext

1
2
3
glGenBuffers(1, &m_vertexBufferID);
glBindBuffer(m_vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*vertices, &data[0], GL_STATIC_DRAW);


Dabei brauchst du für jeden Buffer eine ID, also m_vertexBufferID austauschen wenn du die anderen erstellst. Wie du glBufferData nutzt steht hier. Das ganze machst du dann drei mal und du solltest Index, TexCoord und Vertexbuffer haben. Das glEnableVertexAttribArray() ist hier z.B. noch nicht nötig. Beim Index array nimmst du GL_ELEMENT_ARRAY_BUFFER, nur als Hinweis.

3. Shader laden und compilieren: wie das geht schaust du dir am besten noch mal an andere Stelle an. Aber es sieht im Prinzip so aus wie das Buffer erstellen.
4. Textur laden: sieht ebenfalls (funktioniert in OpenGL alles ähnlich) so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
glGenTextures(1, &m_textureID);
glBindTexture(GL_TEXTURE_2D, m_textureID);

glTexImage2D(GL_TEXTURE_2D,
         0,
         GL_RGB,
         width,
         height,
         0,
         GL_RGB,
         GL_UNSIGNED_BYTE,
         &data[0]);


Wie du die Funktionen wieder genau benutzt lässt sich schnell googlen...

5. Rendern: und am Ende renderst du in deinem render loop jedes Bild. Das funktioniert dann (in etwa) so:

Shader binden
glEnableVertexAttrib... (z.B. 0-3 für Index, Vertex, TexCoords)
Matrizen berechnen (model, view, projection/ortho -> Google)
Textur binden
Matrix/Matrizen übergeben, Textur übergeben (an welche du mit GL_TEXTUREx gebunden hast, also z.B. sendUniform("texture0", 0) bei GL_TEXTURE0)
Buffer binden, bei Vertex und TexCoord außerdem dem Shader über glVertexAttribPointer mitteilen wie die Daten übergeben werden sollen: glVertexAttribPointer(attibLocation, 2, GL_FLOAT, false, 0, 0); (hier z.B. 2 als size, für 2D Koordinaten/UVs)
Rendercall: glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
Alles wieder entbinden (glBind...(id, 0))

So und damit sollte es dann laufen ;)
Den Shader Teil solltest du dir dringend noch mal ansehen. Selbst wenn man mit OpenGL 3/4 noch eine fixed function pipeline (ohne Shader) nutzen kann (ich weiß es nicht), wird es irgendwann nötig diese zu beherrschen. Ist auch nicht all zu schwer.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (11.10.2013, 12:19)


Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

27

11.10.2013, 16:31

Danke für deine sehr ausführliche Erklärung. Ich probiere das grade mit meinem Code zu verstehen. Die Sache sieht bei mir aufgrund der Spiellogik ein wenig anders aus (oder falsch ?( ) Also noch einmal der komplette Durchlauf. Als erstes erstelle ich eine Kamera, dann eine Lichtquelle und die beiden Shader. Einmal der ColorShader und der TextureShader. Beide haben eine eigene Klasse und werden aus dieser heraus erstellt. Jeder dieser Shader besteht aus einem Vertex- und einem PixelShader. Dann wird die TextureUnitClass erstellt die sich um das Verwalten der TextureUnits kümmert. Zum Schluss wird die eigentliche GameClass geladen die sich um das erstellen der drei Modelle und das spätere Rendern kümmert.
Editieren
Im Moment sind es drei Modelle, das Spielfeld, der Affe als Spielfiguren Platzhalter und der Text. Jedes dieser Modelle hat seine eigene Texture. das Spielfeld und die Spielfigur haben die gleichen Funktionen zum Erstellen der Textur und des Modells wie der Text.
Dann zum Rendern. Über meine GraficsClass wird zu erst die Scene reseted und die Buffer gelöscht. Dann wird die durch die Kamera die ViewMatrix. Als Nächstes lasse ich mir über meine OpenGLClass die World- und ProjectionMatrix und von der Kamera die ViewMatrix übergeben. Nun werden die Licht Daten an die Renderfunktion übergeben. Und alle Matrixen und Lichtinformationen werden an die TextureUnitClass übergeben.
Diese wählt dann mithilfe der übergebenden Shaderart und des TextureUnits den Shader aus bevor gerendert wird.
Zu erst jetzt der Code zum Laden der Textur. Ich lade nur 32bit TGA dateien.

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
bool TextureClass::LoadTarga(OpenGLClass* OpenGL, char* filename, unsigned int textureUnit, bool wrap)
{
    int error, width, height, bpp, imageSize;
    FILE* filePtr;
    unsigned int count;
    TargaHeader targaFileHeader;
    unsigned char* targaImage;


    // Open the targa file for reading in binary.
    error = fopen_s(&filePtr, filename, "rb");
    if(error != 0)
    {
        return false;
    }

    // Read in the file header.
    count = fread(&targaFileHeader, sizeof(TargaHeader), 1, filePtr);
    if(count != 1)
    {
        return false;
    }

    // Get the important information from the header.
    width = (int)targaFileHeader.width;
    height = (int)targaFileHeader.height;
    bpp = (int)targaFileHeader.bpp;

    // Check that it is 32 bit and not 24 bit.
    if(bpp != 32)
    {
        return false;
    }

    // Calculate the size of the 32 bit image data.
    if (bpp == 32)
    {
        imageSize = width * height * 4;
    }

    // Allocate memory for the targa image data.
    targaImage = new unsigned char[imageSize];
    if(!targaImage)
    {
        return false;
    }

    // Read in the targa image data.
    count = fread(targaImage, 1, imageSize, filePtr);
    if(count != imageSize)
    {
        return false;
    }
    
    // Close the file.
    error = fclose(filePtr);
    if(error != 0)
    {
        return false;
    }


    // Set the unique texture unit in which to store the data.
    OpenGL->glActiveTexture(GL_TEXTURE0 + textureUnit);

    // Generate an ID for the texture.
    glGenTextures(1, &m_textureID);

    // Bind the texture as a 2D texture.
    glBindTexture(GL_TEXTURE_2D, m_textureID);

    // Load the image data into the texture unit.
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, targaImage);


    // Set the texture color to either wrap around or clamp to the edge.
    if(wrap)
    {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    }
    else
    {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    }

    // Set the texture filtering.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    // Generate mipmaps for the texture.
    OpenGL->glGenerateMipmap(GL_TEXTURE_2D);

    // Release the targa image data.
    delete [] targaImage;
    targaImage = 0;

    // Set that the texture is loaded.
    loaded = true;

    return true;
}

Als nächstes die Funktion zum rendern in der GraficsClass

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
bool GraphicsClass::Render()
{
    float worldMatrix[16];
    float viewMatrix[16];
    float projectionMatrix[16];

    float lightDirection[3];
    float diffuseLightColor[4];
    float ambientLight[4];

    // Clear the buffers to begin the scene.
    m_OpenGL->BeginScene(0.0f, 0.0f, 0.0f, 1.0f);

    // Generate the view matrix based on the camera's position.
    m_Camera->Render();

    // Get the world, view, and projection matrices from the opengl and camera objects.
    m_OpenGL->GetWorldMatrix(worldMatrix);
    m_Camera->GetViewMatrix(viewMatrix);
    m_OpenGL->GetProjectionMatrix(projectionMatrix);

    // Get the light properties.
    m_Light->GetDirection(lightDirection);
    m_Light->GetDiffuseColor(diffuseLightColor);
    m_Light->GetAmbientLight(ambientLight);
    
    // Set the light shader as the current shader program and set the matrices that it will use for rendering.
    m_TextureUnit->SetNewShaderInformation(m_LightShader, m_ColorShader, m_OpenGL, worldMatrix, viewMatrix, projectionMatrix, lightDirection, diffuseLightColor, ambientLight);

    //Render Game Models and other Stuff
    m_Game->Render (worldMatrix);

    // Present the rendered scene to the screen.
    m_OpenGL->EndScene();

    return true;
}

Und die Funktion in der TextureUnitClass zum auswählen des Shaders.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void TextureUnitClass::Render(float* worldMatrix, unsigned int Shader, unsigned int TextureUnit)
{
    switch (Shader)
    {
    case ShaderLight:
        {
            LightShaderPointer->SetShader(OpenGL);
            LightShaderPointer->SetShaderParameters(this->OpenGL, worldMatrix, this->viewMatrix, this->projectionMatrix, TextureUnit,
                                                    this->lightDirection, this->diffuseLightColor, this->ambientLight);
            break;
        }
    case ShaderColor:
        {
            ColorShaderPointer->SetShader(OpenGL);
            ColorShaderPointer->SetShaderParameters(this->OpenGL, worldMatrix, this->viewMatrix, this->projectionMatrix);
            break;
        }
    }
    return;
}

Funktion zum laden und compilieren des TextureShaders.

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
bool LightShaderClass::InitializeShader(char* vsFilename, char* fsFilename, OpenGLClass* OpenGL, HWND hwnd)
{
    const char* vertexShaderBuffer;
    const char* fragmentShaderBuffer;
    int status;


    // Load the vertex shader source file into a text buffer.
    vertexShaderBuffer = LoadShaderSourceFile(vsFilename);
    if(!vertexShaderBuffer)
    {
        return false;
    }

    // Load the fragment shader source file into a text buffer.
    fragmentShaderBuffer = LoadShaderSourceFile(fsFilename);
    if(!fragmentShaderBuffer)
    {
        return false;
    }

    // Create a vertex and fragment shader object.
    m_vertexShader = OpenGL->glCreateShader(GL_VERTEX_SHADER);
    m_fragmentShader = OpenGL->glCreateShader(GL_FRAGMENT_SHADER);

    // Copy the shader source code strings into the vertex and fragment shader objects.
    OpenGL->glShaderSource(m_vertexShader, 1, &vertexShaderBuffer, NULL);
    OpenGL->glShaderSource(m_fragmentShader, 1, &fragmentShaderBuffer, NULL);

    // Release the vertex and fragment shader buffers.
    delete [] vertexShaderBuffer;
    vertexShaderBuffer = 0;
    
    delete [] fragmentShaderBuffer;
    fragmentShaderBuffer = 0;

    // Compile the shaders.
    OpenGL->glCompileShader(m_vertexShader);
    OpenGL->glCompileShader(m_fragmentShader);

    // Check to see if the vertex shader compiled successfully.
    OpenGL->glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, &status);
    if(status != 1)
    {
        // If it did not compile then write the syntax error message out to a text file for review.
        OutputShaderErrorMessage(OpenGL, hwnd, m_vertexShader, vsFilename);
        return false;
    }

    // Check to see if the fragment shader compiled successfully.
    OpenGL->glGetShaderiv(m_fragmentShader, GL_COMPILE_STATUS, &status);
    if(status != 1)
    {
        // If it did not compile then write the syntax error message out to a text file for review.
        OutputShaderErrorMessage(OpenGL, hwnd, m_fragmentShader, fsFilename);
        return false;
    }

    // Create a shader program object.
    m_shaderProgram = OpenGL->glCreateProgram();

    // Attach the vertex and fragment shader to the program object.
    OpenGL->glAttachShader(m_shaderProgram, m_vertexShader);
    OpenGL->glAttachShader(m_shaderProgram, m_fragmentShader);

    // Bind the shader input variables.
    OpenGL->glBindAttribLocation(m_shaderProgram, 0, "inputPosition");
    OpenGL->glBindAttribLocation(m_shaderProgram, 1, "inputTexCoord");
    OpenGL->glBindAttribLocation(m_shaderProgram, 2, "inputNormal");

    // Link the shader program.
    OpenGL->glLinkProgram(m_shaderProgram);

    // Check the status of the link.
    OpenGL->glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &status);
    if(status != 1)
    {
        // If it did not link then write the syntax error message out to a text file for review.
        OutputLinkerErrorMessage(OpenGL, hwnd, m_shaderProgram);
        return false;
    }

    return true;
}

Ich hoffe du kannst was mit den informationen etwas anfangen.
Danke

Werbeanzeige