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

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

1

10.03.2014, 21:53

OpenGL - 2D Renderer

Hi,

mit Hilfe der rastertek.com-Tutorials versuche ich einen OpenGL Renderer für mein 2D Spiel zu schreiben.

Im Moment soll erstmal nur ein farbiges Rechteck gerendert werden. Leider funktioniert das nicht, es wird nur ein leeres, schwarzes Fenster angezeigt.
Hier mal die wichtigsten Methoden des Renderers.

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
//erstellen den Vertexbuffer, wird beim Erstellen des Renderers ausgeführt
void Grafics::Renderer::CreateVertexBuffer()
{
    this->MakeCurrent();

    // Generate an ID for the vertex buffer.
    glGenBuffers(1, &this->VertexBufferId);
    glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
    glBufferData(GL_ARRAY_BUFFER, Grafics::MaxVertices * sizeof(Grafics::VERTEX), NULL, GL_DYNAMIC_DRAW);

    glGenVertexArrays(1, &this->VertexArrayId);

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

    glEnableVertexAttribArray(0);  // Vertex position.
    glEnableVertexAttribArray(1);  // Vertex color.
    glEnableVertexAttribArray(2);  // Vertex Texture.

    // Specify the location and format of the position portion of the vertex buffer.
    glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Grafics::VERTEX), 0);

    // Specify the location and format of the color portion of the vertex buffer.
    glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
    glVertexAttribPointer(1, 4, GL_FLOAT, false, sizeof(Grafics::VERTEX), (unsigned char*)NULL + (3 * sizeof(float)));

    // Specify the location and format of the texture portion of the vertex buffer.
    glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
    glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Grafics::VERTEX), (unsigned char*)NULL + (7 * sizeof(float)));
}


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
//IndexBuffer anlegen
void Grafics::Renderer::CreateRectangleIndexBuffer()
{
    this->MakeCurrent();

    int indexcount = Grafics::MaxVertices / 4 * 6;

    GLushort *pIndices = new GLushort[indexcount];
    unsigned long n = 0;

    for (int i=0;i<indexcount;i+=6)
    {
        pIndices[i] = n;
        pIndices[i+1] = n+1;
        pIndices[i+2] = n+2;
        pIndices[i+3] = n+2;
        pIndices[i+4] = n+3;
        pIndices[i+5] = n;
        n += 4;
    }

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

    // Bind the index buffer and load the index data into it.
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->RectangleIndexBufferId);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexcount * sizeof(GLushort), pIndices, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Wird vor dem Rendern ausgeführt
bool Grafics::Renderer::BeforeRender()
{
    this->MakeCurrent();

    //ClearColor geändert?
    if (this->ChangeClearColor == true)
    {
        glClearColor(this->ClearColor.GetR(), this->ClearColor.GetG(), this->ClearColor.GetB(), this->ClearColor.GetAlpha());
        this->ChangeClearColor = false;
    }

    glViewport(0, 0, this->Width, this->Height); // Set the viewport size to fill the window  
    glClear(GL_COLOR_BUFFER_BIT); // Clear required buffers  

    return true;
}


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
bool Grafics::Renderer::Render()
{
    if (this->VerticesInBuffer > 0)
    {
        //ggf. Indexbuffer erstellen
        if (this->RectangleIndexBufferId == 0)
        {
            this->CreateRectangleIndexBuffer();
        }

        if (this->CurrentShaderChanged == true && this->CurrentShader->Init == true)
        {
            glUseProgram(this->CurrentShader->GetShaderProgram());
            this->CurrentShaderChanged = false;
        }

        // Bind the vertex buffer and load the vertex (position and color) data into the vertex buffer.
        glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
        glBufferData(GL_ARRAY_BUFFER, this->VerticesInBuffer * sizeof(Grafics::VERTEX), this->VertexData, GL_DYNAMIC_DRAW);
        glEnableClientState(GL_VERTEX_ARRAY);

        // Enable the two vertex array attributes.
        glEnableVertexAttribArray(0);  // Vertex position.
        glEnableVertexAttribArray(1);  // Vertex color.
        glDisableVertexAttribArray(2); // Vertex Texture

        //Rendern 
        glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->RectangleIndexBufferId);
        glBindVertexArray(this->VertexArrayId);

        // Render the vertex buffer using the index buffer.
        int indexcount = this->VerticesInBuffer / 4 * 6;
        glDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_SHORT, 0);
        
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(2);
    }

    this->VerticesInBuffer = 0;

    return true;
}


C-/C++-Quelltext

1
2
3
4
5
6
bool Grafics::Renderer::AfterRender()
{
    this->Render();
    SwapBuffers(this->DeviceContext);
    return true;
}


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
//Erstellen des ShaderProgram
bool Grafics::Shaders::ColorShader::Initialize(Grafics::Renderer* renderer)
{
    this->Renderer = renderer;

    const char* vertexShaderBuffer;
    const char* fragmentShaderBuffer;
    int status;

    std::string vsfile = ShaderPath + this->VShaderFile;
    std::string psfile = ShaderPath + this->FShaderFile;

    vertexShaderBuffer = LoadShaderSourceFile(vsfile.c_str());
    if(!vertexShaderBuffer)
    {
        return false;
    }

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

    //MakeCurrent
    this->Renderer->MakeCurrent();

    // Create a vertex and fragment shader object.
    this->VertexShader = glCreateShader(GL_VERTEX_SHADER);
    this->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

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

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

    // Compile the shaders.
    glCompileShader(this->VertexShader);
    glGetShaderiv(this->VertexShader, GL_COMPILE_STATUS, &status);
    if(status != 1)
    {
        this->ThrowShaderError(this->VertexShader);
        return false;
    }

    // Check to see if the fragment shader compiled successfully.
    glCompileShader(this->FragmentShader);
    glGetShaderiv(this->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.
        this->ThrowShaderError(this->FragmentShader);
        return false;
    }

    // Create a shader program object.
    this->ShaderProgram = glCreateProgram();

    // Attach the vertex and fragment shader to the program object.
    glAttachShader(this->ShaderProgram, this->VertexShader);
    glAttachShader(this->ShaderProgram, this->FragmentShader);

    // Bind the shader input variables.
    glBindAttribLocation(this->ShaderProgram, 0, "inputPosition");
    glBindAttribLocation(this->ShaderProgram, 1, "inputColor");

    // Link the shader program.
    glLinkProgram(this->ShaderProgram);

    // Check the status of the link.
    glGetProgramiv(this->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.
        this->ThrowLinkerError(this->ShaderProgram);
        return false;
    }

    this->Init = true;
    return true;
}



Und hier noch die Shader:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Vertex-Shader
#version 400

//Input Variables
in vec3 inputPosition;
in vec4 inputColor;

//Output Variables
out vec4 color;

void main()
{
gl_Position = vec4(inputPosition, 1.0f);
    color = inputColor;
}


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
//Fragment-Shader
#version 400

//Input Variables
in vec4 inputColor;

//Output Variables
out vec4 outputColor;

void main()
{
    outputColor = inputColor;
}


Das VertexData-Array wird bei jeder Frame neu befüllt. Die Werte darin sind soweit richtig, hab ich im Debugger geprüft.


Kann jemand einen Fehler finden?


Gruß

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Schwarzefee« (10.03.2014, 22:03)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

11.03.2014, 07:01

Ich muss so früh am morgen noch etwas blind sein. Sag mir mal eben, wo die Vertices in den Buffer kommen. Ich sehe irgendwie nur Indices.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

3

11.03.2014, 11:24

Hi,

die Vertices befinden sich im Array "this->VertexData".
In der Methode "Render()" kommen sie in den Buffer

C-/C++-Quelltext

1
2
glBindBuffer(GL_ARRAY_BUFFER, this->VertexBufferId);
glBufferData(GL_ARRAY_BUFFER, this->VerticesInBuffer * sizeof(Grafics::VERTEX), this->VertexData, GL_DYNAMIC_DRAW);


Die Vertices werden in folgender Methode in das Array geschrieben:

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
void Grafics::Renderer::DrawRectangle(Grafics::Primitives::Rectangle* rect)
{
    //ggf. aktuellen Vertexbuffer rendern
    if (this->CurrentRendering == RENDERING_PRIMITVE)
    {
        if (this->VerticesInBuffer > 0 &&
            (this->VerticesInBuffer+4 > Grafics::MaxVertices
            || this->CurrentPrimitiveTopology != PRIMITIVE_TRIANGLE))
        {
            this->Render();
        }
    }
    else
    {
        this->Render();
    }

    this->CurrentPrimitiveTopology = PRIMITIVE_TRIANGLE;
    this->CurrentRendering = RENDERING_PRIMITVE;

    unsigned int n = this->VerticesInBuffer;

    this->VertexData[n++] = *rect->GetVertex(0);
    this->VertexData[n++] = *rect->GetVertex(1);
    this->VertexData[n++] = *rect->GetVertex(2);
    this->VertexData[n++] = *rect->GetVertex(3);

    this->VerticesInBuffer += 4;
}


Gruß

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

11.03.2014, 15:04

Mal Backface Culling deaktiviert?
Geschaut, ob alle Transformationen überhaupt ein korrektes Ergebnis zulassen?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

5

11.03.2014, 15:33

Hi,

Backface Culling ist bereits aus.

C-/C++-Quelltext

1
glDisable(GL_CULL_FACE);


Was genau meinst du mit Transformationen? Im Moment soll nur ein Rechteck mit den Koordinaten -0.5x-0.5 bis 0.5x0.5 angezeigt werden.
Laut Debugger sind die Koordinaten richtig in den Vertices.


Gruß

Volker_Neff

Treue Seele

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

6

12.03.2014, 11:09

Schreib mal in den Fragment Shader statt in vec4 inputColor; sondern in vec4 color.
Die Variablen die vom Vertex Shader in den Fragment Shader übergeben werden müssen gleich bennant sein.

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

7

12.03.2014, 13:41

Hi,

Super vielen dank, das war der Fehler ;)


Gruß

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Schwarzefee« (12.03.2014, 13:52)


Werbeanzeige