[OpenGL] Anfänger: 2D Rendern

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

[OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

da ich auch Spieleprogrammierer.de noch keine zündende Idee bekommen habe, versuche ich hier mal mein Glück.
Vielleicht hat ja jemand eine Idee.

Im Prinzip möchte ich nur eine ganz simple 2D Texture rendern.

Mein Programm ist folgendermaße aufgebaut:

INIT:

Code: Alles auswählen

[...] OpenGL initialisieren [...]
[...] Shader Erstellen [...]
glBindAttribLocation(this->ShaderProgram, 0, "vertex0");
glBindAttribLocation(this->ShaderProgram, 1, "texCoord0");

[...] IndexBuffer erstellen[...]
[...] PositionsBuffer erstellen [...]
[...] TextureCoordsBuffer erstellen [...]
RENDERN:

Code: Alles auswählen

glUseProgram(this->ShaderProgram);

[...] IndexBuffer binden [...]

[...] PositionsBuffer binden [...]
glVertexAttribPointer(location_von_vertex0, 2 , GL_FLOAT, false, 0, 0);

[...] TextureCoordsBuffer binden [...]
glVertexAttribPointer(location_von_texCoord0, 2 , GL_FLOAT, false, 0, 0);

[...] Texture binden [...]

int loc_von_pm = glGetAttribLocation(this->ShaderProgram,"pm");
pm = Ortho_matrix * ModelMatrix;
glUniformMatrix3fv(loc_von_pm, 1, false, glm::value_ptr(pm));

glDrawElements(GL_TRIANGLES, IndexBuffer->Size, GL_UNSIGNED_INT, 0);

[...] alles unbinden [...]

SwapBuffers(this->WindowContext);
Meine Shader sind ganz simpel:

Code: Alles auswählen

//VertexShader
#version 330

uniform mat3 pm;

in vec2 vertex0;
in vec2 texCoord0;

out vec2 texCoords;

void main()
{
	texCoords = texCoord0;
	gl_Position = vec4(pm * vec3(vertex0, 1.0), 1.0);
}

Code: Alles auswählen

//FragmentShader
#version 330

uniform sampler2D texture0;
uniform vec4 textcolor;

in vec2 texCoords;

out vec4 outputColor;

void main(){
	outputColor = texture(texture0, texCoords);
	outputColor = outputColor * textcolor;
}
Ich habe schon alles mögliche Versucht, aber der Bildschirm bleibt schwarz.
Testweise habe ich als pm eine Idenity Matrix an den Shader übergeben.
Ich hab im Shader auch schon die Farbe auf vec4(1,1,1,1) und die gl_Position auf (0,0,1,1) gestellt.

Laut GLSLDevil gibts auch keine OpenGL Fehler.


Hat jemand irgend einen Ansatz, was hier falsch läuft?



Gruß
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von antisteo »

Wenn du die Farbe auf weiß gesetzt hast und immer noch nichts zu sehen ist, sind die Tris nicht im sichtbaren Bereich.
Das kann an 3 möglichen Gründen liegen:
a) die Perspektivenmatrix ist falsch aufgesetzt (hast du ja irgendwie ausgeschlossen)
b) die Vertices liegen außerhalb der Bildfläche
c) die Z-Werte sind nicht im Bereich des Z-Puffers. Probiere einfach mal die negativen Z-Werte für die Vertices.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,
b) die Vertices liegen außerhalb der Bildfläche
Das hatte ich auch gedacht, allerdings hab ich im VertexShader mal

Code: Alles auswählen

gl_Position = vec4(0,0,1,1);
gesetzt. Da hätte ja zumindest ein Pixel in der Mitte des Bildschirms gerendert werden müssen.
c) die Z-Werte sind nicht im Bereich des Z-Puffers. Probiere einfach mal die negativen Z-Werte für die Vertices.
Das wäre durchaus eine Möglichkeit, die ich noch nicht getestet hab.
Ich werd es heut Abend gleich mal testen


Gruß
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von dot »

Die default Compare Funktion für den Depth Test in OpenGL ist GL_LESS. Wenn du deinen z-Buffer mit 1 clearest, dann werden Dinge mit einem Tiefenwert von exakt 1 den Depth-Test failen... ;)
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

ich hab testweise

Code: Alles auswählen

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
und

Code: Alles auswählen

glDisable(GL_DEPTH_TEST);
probiert, beides hat nichts gebracht.
Ich hab im Shader auch die Z-Werte auch mal auf -1.0 gestellt.
Hat alles nichts gebracht.

Woran kann das sonst liegen?

Ich hänge testweise mal ein GL-Trace Log für die erste Frame von GLDLDevil an.
Kann damit jemand erkennen, ob ich irgendwas wichtiges vergessen habe?



Gruß
Dateianhänge
trace.txt
GLSLDevil Trace Log
(30.46 KiB) 256-mal heruntergeladen
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Schrompf »

Mit -1 hast Du Dir genauso ein Ei gelegt wie mit +1. Die Z-Werte Deiner Dreiecke liegen am Ende im Clip Space zwischen 0.0 und 1.0. Dreiecke mit Z bei -1 werden sofort weggeschnitten. Nimm doch z.B. mal 0.5.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

danke für die Antwort.

Ich hatte auch 0.0 und 0.5 schon probiert, ging beides auch nich ...



Gruß
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von dot »

Sowohl -1 als auch 1 sollten immer noch in den sichtbaren Bereich fallen. Wie siehts denn mit Culling aus bzw. zeig doch einfach mal die Koordinaten deiner Vertices... ;)

Ansonsten hier einfach mal ein Vertex Shader, der direkt ein Fullscreen Triangle erzeugt:

Code: Alles auswählen

#version 330

uniform vec4 pos;

out vec2 t;

void main()
{
	vec2 p = vec2((gl_VertexID & 0x1), (gl_VertexID & 0x2) * 0.5f);
	gl_Position = vec4(p * 4.0f - 1.0f, 0.0f, 1.0f);
	t = 2.0f * p;
}
Einfach leeres VAO binden und glDrawArrays(GL_TRIANGLES, 3) machen... ;)
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

Wenn ich im FragmentShader

Code: Alles auswählen

outputColor = vec4(1,1,1,1);
schreibe, ist der Bildschirm schonmal Weis (wie erwartet), bzw. kann ich auch an den Fragment-Shader ne Farbe übergeben.
Das ist schonmal ein kleiner Fortschritt ;)

Die Daten des Positions- und TextureCoords Buffer sind auch richtig. Die Die Positions-Koordinaten sind in px angegeben, die TextureCoordinaten zwischen 0 und 1.
Möglicherweise liegt es an meiner Buffer-Füll-Methode?

Code: Alles auswählen

bool Buffer::Vector2Buffer::Fill(std::vector<glm::vec2> data, const unsigned int use)
{
  if (data.size())
  {
    this->Bind();
    glBufferData(this->Target, data.size()*sizeof(glm::vec2), &data[0], use);
    this->Unbind();

    this->BufferSize = data.size();
    this->Loaded = true;

    return true;
  }
  return false;
}
An den Vertex-Shader übergebe ich als pm nur die Orthologische Matrix (die sieht auch richtig aus), [0][0] und [1][1] sind Werte ~0.002, [2][2] ist -1.
Das ist die 2. mögliche Fehlerquelle:

Code: Alles auswählen

void Shaders::AbstractShader::sendUniform3x3(const std::string &name, glm::mat3 matrix)
{
  glUniformMatrix3fv(this->GetUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix));
}
An sonsten weis ich keinen Rat mehr, woran es noch liegen könnte ...


Gruß
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Schrompf »

Wenn der FragmentShader eine Konstante ausgibt, siehst Du was? Na das ist doch prima.

Ein Denkfehler fällt mir gerade auf: die Vertex-Positionen sind NICHT in Bildschirmkoordinaten, also keine Pixel. Die sind im Screen Space oder Clip Space - ich weiß gerade nicht den korrekten Begriff. Für OpenGL (und DirectX auch) gilt hier:

X geht von -1 (linke Bildschirmkante) bis +1 (rechte Bildschirmkante)
Y geht von -1 (untere Bildschirmkante) bis +1 (obere Bildschirmkante) - Achtung: das ist im Vergleich zu Pixelkoordinaten kopfüber!
Z geht von -1 (direkt an der Bildschirmoberfläche) bis +1 (tief in den Bildschirm rein)

Dein Test-Dreieck sollte also X und Y irgendwo im Bereich -1 bis +1 haben. +-0.5f seien empfohlen. Für Z würde ich für alle Vertizes einen konstanten Wert nehmen, z.B. 0.5f.

Jetzt sehe ich gerade, dass Du eine passende Projektionsmatrix benutzt. Sorry, damit ist das hinfällig. Allerdings brauchst Du für homogene Matrizen 4 Spalten. Du lädst aber in Deinem Beispielcode nur eine 3x3-Matrix hoch. Damit müsste alle Dreiecke einen halben Bildschirm nach rechts versetzt rauskommen. Bedenke auch, dass Du der Grafikkarte unbedingt einen Vierervektor als Position gibst. Die Grafikkarte macht mit der Position nachher pos.xyz / pos.w. Also sieh zu, dass Deine Projektionsmatrix oder Dein Shader für .w einen sinnvollen Wert >0 bis 1.0 ausspuckt. Eine orthogonale Projektion spuckt an der Stelle immer 1 aus, was die perspektivische Division der GPU quasi ausschaltet.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von antisteo »

Raven280438 hat geschrieben:Hi,

Wenn ich im FragmentShader

Code: Alles auswählen

outputColor = vec4(1,1,1,1);
schreibe, ist der Bildschirm schonmal Weis (wie erwartet), bzw. kann ich auch an den Fragment-Shader ne Farbe übergeben.
Moooment. Das hast du doch im Anfangspost ausgeschlossen. Du solltest nicht zu viel auf einmal einmal programmieren, denn wenn du mehrere Fehler machst, siehst du keine Besserung, wenn du nur einen Fehler behebst.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

ich hab jetzt eine mat4x4 als Orthologische Matrix mit glm berechnet.

Mein Shader sieht dazu so aus:

Code: Alles auswählen

#version 330

uniform mat4 pm;

in vec2 vertex0;
in vec2 texCoord0;

out vec2 texCoords;

void main()
{
	texCoords = texCoord0;
	gl_Position = pm * vec4(vertex0, 0.5, 0.5);
}
Nach wie vor bleibt der Bildschirm schwarz ...
antisteo hat geschrieben:Du solltest nicht zu viel auf einmal einmal programmieren, denn wenn du mehrere Fehler machst, siehst du keine Besserung, wenn du nur einen Fehler behebst.
Das Problem ist, viel einfach geht es kaum noch ;)
Ich will im Moment einfach nur ein paar Rechtecke mit einer Texture rendern...

Kann man irgendwie Shader debuggen? Vielleicht hab ich ja irgendwo bei der Übergabe CPU->GPU einen Fehler, und die Buffer haben falsche Werte...

Gruß
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Schrompf »

NVidia NSight. Setzt aber Windows, Visual Studio und eine NVidia-Grafikkarte voraus.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2367
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Jonathan »

Ansonsten, wenn es ganz hart kommt: Such dir ein Tutorial mit Beispielcode und schau nach ob der geht. Und dann guck dir an, was die anders machen, bzw. ändere den Tutorialcode Stück für Stück um, bis er so aussieht wie dein Code und dann sie nach, wo es aufhört zu funktionieren.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

läuft NVidia NSight auch mit VS-Express?
Windows und Nvidia Graka ist vorhanden.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

ich hab mein Progamm jetzt mal aufs Minimalste reduziert. Einfach ein Dreieck in Weiß rendern.

Code: Alles auswählen

this->vec2Buffer = new Buffer::Vector2Buffer();
std::vector<glm::vec2> vec2Data = std::vector<glm::vec2>();
vec2Data.push_back(glm::vec2(0,0.5));
vec2Data.push_back(glm::vec2(0.5, -0.5));
vec2Data.push_back(glm::vec2(-0.5, -0.5));
this->vec2Buffer->Fill(vec2Data, GL_STATIC_DRAW);

this->indexBuffer = new Buffer::IndexBuffer();
std::vector<unsigned int> intData = std::vector<unsigned int>();
intData.push_back(0);
intData.push_back(1);
intData.push_back(2);
this->indexBuffer->Fill(intData,GL_STATIC_DRAW);

Code: Alles auswählen

this->indexBuffer->Bind();
this->vec2Buffer->Bind();
this->vec2Buffer->vertexAttribPointer(this->TextShader->GetAttribLocation("vertex0"), 2, GL_FLOAT, false, 0, 0);

glDrawElements(GL_TRIANGLES, this->indexBuffer->GetSize(), GL_UNSIGNED_INT, 0);
Selbst das funktioniert schon nicht. Kann es an meinder Buffer-Füll-Methode liegen?

Code: Alles auswählen

bool Buffer::Vector2Buffer::Fill(glm::vec2* data, const unsigned int numelements, const unsigned int use)
{
	if (data)
	{
		this->Bind();
		glBufferData(this->Target, numelements*2, &data[0].x, use);
		this->Unbind();

		this->BufferSize = numelements * 2;

		this->Loaded = true;

		return true;
	}
	return false;
}

bool Buffer::Vector2Buffer::Fill(std::vector<glm::vec2> &data, const unsigned int use)
{
	if (data.size())
	{
		return this->Fill(&data[0], data.size(), use);
	}

	return false;
}
Oder mach ich vielleicht schon bei der Initialisierung was falsch?

Code: Alles auswählen

bool DeviceContext::Initialize(HWND hwnd, float width, float height, bool fullscreen)
{
	this->WindowHandle = hwnd;
	this->Width = width;
	this->Height = height;
	this->Fullscreen = fullscreen;

	this->WindowContext = GetDC(this->WindowHandle);

	//falls es das erste Window ist, globalen Rendering-Context erstellen
	if (this->GetGraphics()->GetRenderingContext() == 0)
	{
		PIXELFORMATDESCRIPTOR pfd;
		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD  
		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
		pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels  
		pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)  
		pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)  
		pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD  

		int nPixelFormat = ChoosePixelFormat(this->WindowContext, &pfd); // Check if our PFD is valid and get a pixel format back  
		if (nPixelFormat == 0)
		{
			THROW_GraphicsException("error_choosepixelformat","Pixelformat konnte nicht ausgewählt werden!",0);
			return false;  
		}
	
		BOOL bResult = SetPixelFormat(this->WindowContext, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD  
		if (!bResult)
		{
			THROW_GraphicsException("error_setpixelformat","Pixelformat konnte nicht gesetzt werden!",bResult);
			return false;
		}

		HGLRC tempOpenGLContext = wglCreateContext(this->WindowContext); // Create an OpenGL 2.1 context for our device context  
		wglMakeCurrent(this->WindowContext, tempOpenGLContext); // Make the OpenGL 2.1 context current and active  

		//Init Glew
		GLenum error = glewInit(); // Enable GLEW  
		if (error != GLEW_OK) // If GLEW fails  
		{
			THROW_GraphicsException("error_loadglew","GLEW konnte nicht initialisiert werden!",error);
			return false;
		}

		int attributes[] = {  
			WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3  
			WGL_CONTEXT_MINOR_VERSION_ARB, 2, // Set the MINOR version of OpenGL to 2  
			WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Set our OpenGL context to be forward compatible  
			0
		};

		if (wglewIsSupported("WGL_ARB_create_context") == 1) 
		{
			this->RenderingContext = wglCreateContextAttribsARB(this->WindowContext, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes  
			wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active  
			wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context  
			wglMakeCurrent(this->WindowContext, this->RenderingContext); // Make our OpenGL 3.0 context current  
		}
		else 
		{  
			this->RenderingContext = tempOpenGLContext; // If we didn't have support for OpenGL 3.x and up, use the OpenGL 2.1 context  
		}

		int glVersion[2] = {-1, -1}; // Set some default values for the version  
		glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); // Get back the OpenGL MAJOR version we are using  
		glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); // Get back the OpenGL MAJOR version we are using  

		this->STEngine->GetGraphics()->SetOpenGLVersion(glVersion[0], glVersion[1]);

		glEnable(GL_TEXTURE_2D);
		glShadeModel(GL_SMOOTH);

		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);
		glEnable(GL_BLEND);

		//VSync ausmachen
		wglSwapIntervalEXT(0);
	}
	else 
	{
		this->RenderingContext = this->GetGraphics()->GetRenderingContext();
	}

	//Viewport setzen
	this->Resize(width, height);
	
	this->Loaded = true;

	return true;
}
Findet jemand einen Fehler?


Gruß
kristof
Beiträge: 91
Registriert: 19.01.2009, 13:05

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von kristof »

Hm, minimal würde ich das jetzt nicht gerade nennen. Schmeiss doch diese ganzen Wrapper-Klassen erstmal raus. Ausserdem ist nicht ersichtlich in welcher Reihenfolge du was machst. Die Reihenfolge, in der Dinge gemacht werden, spielt bei OpenGL aber mitunter eine sehr wichtige Rolle ;)
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Schrompf »

An Deinem Beispielcode sehe ich hier auf die Schnelle: glBufferData nimmt nach meinem Wissen die Größe der Daten in Bytes. Also 2*numelements*sizeof(float). Du lädst nur 2*numelements hoch, also nur 6 Byte anstatt 24.

Ich halte es allerdings auch für einen Fehler, schon mit Wrapperklassen anzufangen, bevor Du überhaupt weißt, wie das alles funktioniert.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

ich hab jetzt nochmal komplett von null angefangen, ohne Wrapper-Klassen.
Ein einfaches Programm, um ein weißes Dreieck zu rendern.

//OpenGL Klasse

Code: Alles auswählen

#include "stdafx.h"
#include "opengl.h"

MyOpenGLContext::MyOpenGLContext()
{

}

MyOpenGLContext::MyOpenGLContext(HWND hwnd)
{
	this->CreateContext(hwnd);
}

MyOpenGLContext::~MyOpenGLContext()
{
	wglMakeCurrent(this->DeviceContext, 0); // Remove the rendering context from our device context  
	wglDeleteContext(this->RenderContext); // Delete our rendering context  
  
	ReleaseDC(this->WindowHandle, this->DeviceContext); // Release the device context from our window  
}

bool MyOpenGLContext::CreateContext(HWND hwnd)
{
	this->WindowHandle = hwnd;

	this->DeviceContext = GetDC(hwnd);

	PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)  
	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD  
	pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class  
	pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window  
	pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels  
	pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)  
	pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)  
	pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD  

	int nPixelFormat = ChoosePixelFormat(this->DeviceContext, &pfd); // Check if our PFD is valid and get a pixel format back  
	if (nPixelFormat == 0) // If it fails  
	{
		return false;
	}
  
	BOOL bResult = SetPixelFormat(this->DeviceContext, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD  
	if (!bResult) // If it fails  
	{
		return false;  
	}

	HGLRC tempOpenGLContext = wglCreateContext(this->DeviceContext); // Create an OpenGL 2.1 context for our device context  
	wglMakeCurrent(this->DeviceContext, tempOpenGLContext); // Make the OpenGL 2.1 context current and active  


	GLenum error = glewInit(); // Enable GLEW  
        if (error != GLEW_OK) // If GLEW fails  
	{
		return false;  
	}

	int attributes[] = {  
		WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3  
		WGL_CONTEXT_MINOR_VERSION_ARB, 2, // Set the MINOR version of OpenGL to 2  
		WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Set our OpenGL context to be forward compatible  
		0  
	}; 

	if (wglewIsSupported("WGL_ARB_create_context") == 1) { // If the OpenGL 3.x context creation extension is available  
		this->RenderContext = wglCreateContextAttribsARB(this->DeviceContext, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes  
		wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active  
		wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context  
		wglMakeCurrent(this->DeviceContext, this->RenderContext); // Make our OpenGL 3.0 context current  
    }  
    else 
	{
		this->RenderContext = tempOpenGLContext; // If we didn't have support for OpenGL 3.x and up, use the OpenGL 2.1 context  
    }  

	int glVersion[2] = {-1, -1}; // Set some default values for the version  
	glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); // Get back the OpenGL MAJOR version we are using  
	glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); // Get back the OpenGL MAJOR version we are using  

	glDisable(GL_CULL_FACE),
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_STENCIL_TEST);

	this->Shader = new AbstractShader();
	bool shaderinit = this->Shader->InitShader("DefaultShader.vs", "DefaultShader.fs");

	this->IndexBuffer = 0;
	this->PositionBuffer = 0;

	return true;
}

void MyOpenGLContext::SetupScene()
{
	glClearColor(0.4f, 0.6f, 0.9f, 0.0f);

	//IndexBuffer
	glGenBuffers(1, &this->IndexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->IndexBuffer);
	unsigned int indices[] = { 0,1,2 };
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	//PositionBuffer
	glGenBuffers(1, &this->PositionBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, this->PositionBuffer);
	static const float g_vertex_buffer_data[] = {
		0.0f, 0.5f,
		0.5f, -0.5f,
		-0.5f,  -0.5,
	};
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

	int loc = this->Shader->GetAttribLocation("vertex0");
	glVertexAttribPointer(loc, 2, GL_FLOAT, false, 0, 0);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void MyOpenGLContext::ResizeWindow(int width, int height)
{
	this->WindowWidth = width;
	this->WindowHeight = height;
}

void MyOpenGLContext::RenderScene()
{
	glViewport(0, 0, this->WindowWidth, this->WindowHeight); // Set the viewport size to fill the window  
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers  

	this->Shader->Bind(); // Bind our shader

	glEnableVertexAttribArray(this->Shader->GetAttribLocation("vertex0"));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->IndexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, this->PositionBuffer);

	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
  
	this->Shader->Unbind(); // Unbind our shader  

	SwapBuffers(this->DeviceContext); // Swap buffers so we can see our rendering    
}
//Shader Klasse

Code: Alles auswählen

#include "stdafx.h"
#include "AbstractShader.h"

AbstractShader::AbstractShader()
{
	this->VertexShader = NULL;
	this->FragmentShader = NULL;
	this->ShaderProgram = NULL;
}

AbstractShader::~AbstractShader()
{
	if (this->FragmentShader != NULL)
	{
		glDetachShader(this->ShaderProgram, this->FragmentShader);
		glDeleteShader(this->FragmentShader);
	}

	if (this->VertexShader != NULL)
	{
		glDetachShader(this->ShaderProgram, this->VertexShader);
		glDeleteShader(this->VertexShader);
	}

	if (this->ShaderProgram != NULL)
	{
		glDeleteProgram(this->ShaderProgram);
	}
}

bool AbstractShader::InitShader(std::string vertexshader, std::string fragmentshader)
{
	this->ShaderProgram = glCreateProgram();
	this->VertexShader = glCreateShader(GL_VERTEX_SHADER);
	this->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

	std::string vertexshaderpath = "./Resources/Shaders/" + vertexshader;

	//Vertex-Shader erstellen
	std::string vertexbuffer = this->readFile(vertexshaderpath);
	if (vertexbuffer.empty())
	{
		return false;
	}
	const char* tmp = static_cast<const char*>(vertexbuffer.c_str());
	glShaderSource(this->VertexShader, 1, (const char**)&tmp, 0);
	glCompileShader(this->VertexShader);
	int result;
	glGetShaderiv(this->VertexShader, GL_COMPILE_STATUS, &result);
	if(!result)
	{
		this->OutputShaderLog(this->VertexShader);
		return false;
	}

	//Fragment-Shader erstellen
	std::string fragshaderpath = "./Resources/Shaders/" + fragmentshader;
	std::string fragmentbuffer = this->readFile(fragshaderpath);
	if (fragmentbuffer.empty())
	{
		return false;
	}
	tmp = static_cast<const char*>(fragmentbuffer.c_str());
	glShaderSource(this->FragmentShader, 1, (const char**)&tmp, 0);
	glCompileShader(this->FragmentShader);
	glGetShaderiv(this->FragmentShader, GL_COMPILE_STATUS, &result);
	if(!result)
	{
		this->OutputShaderLog(this->FragmentShader);
		return false;
	}

	glAttachShader(this->ShaderProgram, this->VertexShader);
	glAttachShader(this->ShaderProgram, this->FragmentShader);

	glBindAttribLocation(this->ShaderProgram, 0, "vertex0");

	glLinkProgram(this->ShaderProgram);

	glGetProgramiv(this->ShaderProgram, GL_LINK_STATUS, &result);
	if(!result)
	{
		this->OutputProgramLog(this->ShaderProgram);
		return false;
	}

	return true;
}

void AbstractShader::OutputShaderLog(unsigned int shaderID)
{
	std::vector<char> infoLog;
	GLint infoLen;

	glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLen);
	infoLog.resize(infoLen);
	glGetShaderInfoLog(shaderID, infoLog.size(), &infoLen, &infoLog[0]);
}

void AbstractShader::OutputProgramLog(unsigned int programID)
{
	std::vector<char> infoLog;
	GLint infoLen;
	GLint result;

	glGetProgramiv(programID, GL_LINK_STATUS, &result);

	if(result)
	{
		return;
	}

	glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLen);
	infoLog.resize(infoLen);
	glGetProgramInfoLog(programID, infoLog.size(), &infoLen, &infoLog[0]);
}

std::string AbstractShader::readFile(const std::string &filename)
{
	std::ifstream file(filename.c_str());

	if(!file.good())
	{
		//THROW_GraphicsException("error_readingfile","The Shader-Sourcefile could not be read",0);
		return std::string();
	}

	std::string stringBuffer(std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>()));
	
	return stringBuffer;
}

void AbstractShader::Bind()
{
	glUseProgram(this->ShaderProgram);
}

void AbstractShader::Unbind()
{
	glUseProgram(NULL);
}

unsigned int AbstractShader::GetAttribLocation(const std::string &name)
{
	return glGetAttribLocation(this->ShaderProgram, name.c_str());
}
main.cpp

Code: Alles auswählen

#include "stdafx.h"
#include "main.h"

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{   
	switch (message) {  
		case WM_SIZE: // If our window is resizing  
		{  
			OpenGL->ResizeWindow(LOWORD(lParam), HIWORD(lParam)); // Send the new window size to our OpenGLContext  
			break;  
		}    
		case WM_DESTROY:  
		{  
			PostQuitMessage(0);  
			break;  
		}  
	}  
  
	return DefWindowProc(hWnd, message, wParam, lParam);  
}

bool CreateNewWindow(LPCWSTR title, int width, int height)
{
	WNDCLASS windowClass;  
	HWND hWnd;  
	DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;  
  
	hInstance = GetModuleHandle(NULL);  
  
	windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  
	windowClass.lpfnWndProc = (WNDPROC) WndProc;  
	windowClass.cbClsExtra = 0;  
	windowClass.cbWndExtra = 0;  
	windowClass.hInstance = hInstance;  
	windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);  
	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);  
	windowClass.hbrBackground = NULL;  
	windowClass.lpszMenuName = NULL;  
	windowClass.lpszClassName = title;  
  
	if (!RegisterClass(&windowClass)) 
	{  
		return false;  
	}

	OpenGL = new MyOpenGLContext();

	hWnd = CreateWindowEx(dwExStyle, title, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, width, height, NULL, NULL, hInstance, NULL);  
	
	OpenGL->CreateContext(hWnd); // Create our OpenGL context on the given window we just created  
  
	ShowWindow(hWnd, SW_SHOW);  
	UpdateWindow(hWnd);  

	return true;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{  
    MSG msg;  

	/** 
	The following 6 lines of code do conversion between char arrays and LPCWSTR variables 
	which are used in the Windows API. 
	*/  
	char *orig = "OpenGL 3 Project"; // Our windows title  
	size_t origsize = strlen(orig) + 1;  
	const size_t newsize = 100;  
	size_t convertedChars = 0;  
	wchar_t wcstring[newsize];  
	mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);  

	CreateNewWindow(wcstring, 500, 500); // Create our OpenGL window  
  
	OpenGL->SetupScene(); // Setup our OpenGL scene  

	while (running)  
	{  
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
		{ // If we have a message to process, process it  
			if (msg.message == WM_QUIT) 
			{  
				running = false; // Set running to false if we have a message to quit  
			}  
			else 
			{  
				TranslateMessage(&msg);  
				DispatchMessage(&msg);  
			}  
		}  
		else 
		{ // If we don't have a message to process  
			OpenGL->RenderScene(); // Render our scene (which also handles swapping of buffers)  
		}  
	}  
  
	return (int) msg.wParam;  
}  
Alle Werte sind so wie sie sein sollten, GLSLDevil hat auch nichts auszusetzen.

Trotzdem wird nichts gerendert. Irgendwas grundsätzliches mach ich falsch.
Kann mir jemand sagen, was?


Gruß
kristof
Beiträge: 91
Registriert: 19.01.2009, 13:05

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von kristof »

Beim überfliegen des codes hab ich nicht gesehen, dass du ein Vertex Array Object verwendest. Soweit ich weiss ist das aber ab 3.x zwingend notwendig. Ich bin mir allerdings gerade nicht ganz sicher ob das nur so war wenn man ein Core Profile verwendet.
Versuch mal, bevor du deine Buffer erzeugst:

Code: Alles auswählen

GLint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Natürlich solltest du dir auch was dazu durchlesen, wozu VAOs da sind ;) Sind echt praktisch.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Spiele Programmierer »

Ja, nur wenn man Core Profile verwendet.
Natürlich trotzdem oder sogar gerade deswegen empfehlenswert.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

danke für eure Antworten.

Was genau ist ein Core Profile? Davon hab ich bis jetzt noch nichts gehört?! Keine Ahnung ob ich das verwende oder nicht ;)

Mit einem VAO hatte ich schonmal ein bisschen rumexperimentiert, hatte aber auch nichts gebracht.

Wozu genau ist ein VAO eigendlich da? Ist das nur ne "Zusammenfassung" von verschiedenen Buffern, dh. man muss nichtmehr alle Buffer binden, sondern nur das entsprechende VAO?

Ich werd mich heut Abend nochmal etwas genauer damit beschäftigen, mal sehn ...


Gruß
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Spiele Programmierer »

Ein Core Profile ist eine abgespecktere "Variante" der OpenGL API und wurde mit Version 3.2 eingeführt. Man hatte einfach festgestellt das viele Funktionen eigentlich unnötig sind und bloß aus Gründen der Abwärtskompatiblität vorhanden waren. Also hat man das Core Profile eingeführt in welchen alle veralteten Features nicht mehr zur Verfügung stehen. Alle älteren Features des sogenannten Compatibility Profiles wurden dabei die Extension "ARB_compatibility" geschoben und sind nicht mehr teil des Cores. Als Sicht eines Programmierers ist das sehr wichtig um nicht massenhaft veraltete Funktionen zu nutzen ohne es überhaupt mitzubekommen.

Wenn du nichts davon weißt, heißt das wahrscheinlich in etwa soviel, wie das du kein Core Profile nutzt. Aus Kompatibilitätsgründen ist ein Kontext ohne spezielle Einstellungen erstmal ein Compatibility Context. Sonst würde ja alle alte Software die veraltete Funktionen nutzt, schlicht da es noch gar nichts anderes gab, ihren Dienst versagen.

Ein VAO ist ein "Vertex Array Object" und speichert deine Buffereinstellungen. Also welche Buffer gerade gebunden sind kannst du in diesen Buffer hinterlegen. Dann muss nur noch dieses Objekt wieder gebunden werden und alle Einstellungen zu den verwendeten Buffern der Vertexattribute sind wiederhergestellt. Da mit dieser Funktionalität das Rendern ohne VAO irgendwie überflüssig ist, weil man das gleiche ja schon mit den neueren VAOs funktioniert, wurde es in OpenGL 3.1 das Rendern ohne VAO entfernt.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Hi,

dank eurer Hilfe bin ich wieder ein Stück weiter gekommen.

Wenn ich ein Dreieck mit den Koordinaten

Code: Alles auswählen

std::vector<glm::vec2> vec2;
vec2.push_back(glm::vec2(0.0f, 0.5));
vec2.push_back(glm::vec2(0.5, -0.5));
vec2.push_back(glm::vec2(-0.5, -0.5));
rendere, funktioniert alles wie gewünscht.

Wenn ich jetzt allerdings ne Projektions-Matrix dazu bringe, bleibt der Bildschirm wieder leer

Code: Alles auswählen

std::vector<glm::vec2> vec2;
vec2.push_back(glm::vec2(0.0f, 100));
vec2.push_back(glm::vec2(100, -100));
vec2.push_back(glm::vec2(-100, -100));

[...]
this->OrthoProjectionMatrix = glm::ortho(0.0f, width, height, 0.0f, 0.0f, 100.0f);

[...]

glUniformMatrix4fv(0, 1, false, glm::value_ptr(this->OrthoProjectionMatrix));
Laut gDEBugger gibt es öffters den Fehler
Debug String: Detected error: The debugged process asked for an extension function pointer (glUniformMatrix4fv) from one render context, but called this function pointer in another render context (context #2)
Was genau bedeutet das? Ich hab eigendlich nur 1 RenderContext...

Hier mal die Methode, wie ich OpenGL initialisiere:

Code: Alles auswählen

bool Graphics::DeviceContext::Initialize(HWND hwnd, float width, float height, bool fullscreen)
{
	this->WindowHandle = hwnd;
	this->Width = width;
	this->Height = height;
	this->Fullscreen = fullscreen;

	this->WindowContext = GetDC(this->WindowHandle);
	

	//falls es das erste Window ist, globalen Rendering-Context erstellen
	if (this->GetGraphics()->GetRenderingContext() == 0)
	{
		PIXELFORMATDESCRIPTOR pfd;
		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD  
		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
		pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels  
		pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)  
		pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)  
		pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD  

		int nPixelFormat = ChoosePixelFormat(this->WindowContext, &pfd); // Check if our PFD is valid and get a pixel format back  
		if (nPixelFormat == 0)
		{
			return false;  
		}
	
		BOOL bResult = SetPixelFormat(this->WindowContext, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD  
		if (!bResult)
		{
			return false;
		}

		HGLRC tempOpenGLContext = wglCreateContext(this->WindowContext); // Create an OpenGL 2.1 context for our device context  
		wglMakeCurrent(this->WindowContext, tempOpenGLContext); // Make the OpenGL 2.1 context current and active  

		//Init Glew
		GLenum error = glewInit(); // Enable GLEW  
		if (error != GLEW_OK) // If GLEW fails  
		{
			THROW_GraphicsException("error_loadglew","GLEW konnte nicht initialisiert werden!",error);
			return false;
		}

		int attributes[] = {  
			WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3  
			WGL_CONTEXT_MINOR_VERSION_ARB, 2, // Set the MINOR version of OpenGL to 2  
			WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,*/ // Set our OpenGL context to be forward compatible  
			WGL_CONTEXT_CORE_PROFILE_BIT_ARB, //Core-Profile
			0
		};

		if (wglewIsSupported("WGL_ARB_create_context") == 1) 
		{
			this->RenderingContext = wglCreateContextAttribsARB(this->WindowContext, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes  
			wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active  
			wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context  
			wglMakeCurrent(this->WindowContext, this->RenderingContext); // Make our OpenGL 3.0 context current  
		}
		else 
		{  
			this->RenderingContext = tempOpenGLContext; // If we didn't have support for OpenGL 3.x and up, use the OpenGL 2.1 context  
		}

		int glVersion[2] = {-1, -1}; // Set some default values for the version  
		glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); // Get back the OpenGL MAJOR version we are using  
		glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); // Get back the OpenGL MAJOR version we are using  

		this->GetGraphics()->SetOpenGLVersion(glVersion[0], glVersion[1]);

		glEnable(GL_TEXTURE_2D);
		glShadeModel(GL_SMOOTH);

		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);
		glEnable(GL_BLEND);

		//VSync ausmachen
		wglSwapIntervalEXT(0);
	}
	else 
	{
		this->RenderingContext = this->STEngine->GetGraphics()->GetRenderingContext();
	}

	//Viewport setzen
	this->Resize(width, height);
	
	this->Loaded = true;

	return true;
}
Die Initialisierung hab ich von www.swiftless.com, ist da was falsch dran?


Gruß



EDIT:
Ich hab den Teil nach

Code: Alles auswählen

if (wglewIsSupported("WGL_ARB_create_context") == 1)
mal rausgenommen, der Fehler ist jetzt weg. Trotzdem wird noch nichts angezeigt.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Raven280438 »

Trotzdem wird noch nichts angezeigt
Damit meine ich, das ganze Fenster ist in der Farbe des Dreiecks.
Gerendert wird also schon was, nurt stimmt irgendwas mit den Koordinaten nicht...
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Schrompf »

Ich finde jetzt Deinen VertexShader-Code nicht im bisherigen Thread, aber ich würde mal raten:

- Du machst dort irgendwas mit Zweit-Kontext und vorherigem Kontext löschen - alle nachfolgenden Operationen und so auch glew-Einrichtung sollten dann nur danach passieren

- Du lädst die Matrix falsch hoch. GLM benutzt laut meinem fixen Googlen column major layout, OpenGL erwartet im Shader aber row major. Probiere mal, die Matrix transponiert hochzuladen.

- Du benutzt die Matrix im Shader falsch. Eigentlich sollte es, wenn Du dort final angekommen bist, wie ganz normale Matrix-Vektor-Multiplikation aussehen: final_pos = YourMatrix * vertex_pos;
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2367
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [OpenGL] Anfänger: 2D Rendern

Beitrag von Jonathan »

Du kannst [ code = cpp ] als Code Tag benutzen um den Code leserlicher zu machen.

Zu Matrizen: Ich lade sie so hoch

Code: Alles auswählen

void Shader::SetUniform(unsigned int Location, const glm::mat4& Value)
{
	glUniformMatrix4fv(Location, 1, false, value_ptr(Value));
}
und es funktioniert. Zu dem Boolean sagt die Doku:
transpose: Specifies whether to transpose the matrix as the values are loaded into the uniform variable. Must be GL_FALSE.
Und ich gebe im Shader auch nicht an, dass die Matrix transponiert ist (wenn ich mich recht entsinne konnte man das nämlich).

Soweit ich weiß ist glEnable(GL_TEXTURE_2D); nur für die Fixed-Function-Pipeline, wenn du also Shader benutzt hat es überhaupt keinen Effekt. Du hast halt Texturen wenn du sie an den Shader bindest und dort benutzt, ansonsten nicht.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten