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ß