[C & OpenGL]Kontexte unter Windows

FBIagent

Erfahrenes Mitglied
Hallo,

ich wollte mich ein wenig in OpenGL unter C einarbeiten und habe mir dazu eine kleine Abstraktion für das Fenster- und Kontextmanagement geschrieben.

Erstellen von Fenstern und Kontexten klappt auch wunderbar, nur bleibt bei der Kontexterstellung viel unklar, was ich mit hilfe des Internets leider nicht lösen konnte.

(Das untere ist nur auf Windows bezogen)

Bis version 2.1 war alles abwärtskomptibel(zumindest per Definition). Wenn ich nun einen OpenGL 3+ Kontext erstellen möchte, steht auf einigen Seiten beschrieben, dass ich einen "Alten" Kontext erstellen muss um einen "Neuen" Kontext erstellen zu können. Allerdings gibt mir glGetString(GL_VERSION) nach einem einfachen wglCreateContext "3.3.0" zurück(höchst mögliche Version auf meiner GeForce GTX260). Nun ist das ja schon ein "Neuer" Kontext.

Was ist denn nun dran an der Behauptung "Alt für Neu"? Eventuell aus Kompatibilitätsgründen doch zwei mal einen Kontext erstellen? (Ich gehe jetzt davon aus das "Core" und "Compatibility" Modus bei der Grafikkarte keinen unterschied macht, nur die Definition ändert sich, aber Grafikkarten werden wohl bis 1.0 abwärtskompatibel bleiben und alte Funktionen in allen Kontexten unterstützen?)
 
Zuletzt bearbeitet:
Hallo,

lieber spät als nie:

Grundsätzlich wüsste ich keinen Grund mehr als einen Kontext zu erstellen außer einem: Multisampling.

Es ist so, dass der wgl-Kontext kein Multisampling zur Verfügung stellt. Um so einen Kontext mit Multisampling zu erstellen, benötigt es aber OpenGL-Funktionen, die erst verfügbar sind, wenn ein Kontext besteht. Daher erstellt man erst einen einfachen Kontext, baut dann einen Kontext, der Multisampling unterstützt und wirft den alten dann weg.

Was die Funktionalität der einzelnen Kontextversionen angeht, ist es durch das Core-Compatibility-Profile Konzept so, dass im Core-Profile die Funktionen drin sind, die mit der aktuellen API unterstützt werden. Im Compatibility-Profile ist der ganze Rest drin. So wie es aussieht bleibt das auch noch eine ganze Weile so, sodass man eigentlich keine Gedanken an die Kontext-Version verlieren muss.

Ich hab vor einiger Zeit mal so eine Funktion gebaut, die ein GL-Fenster mit Multisampling-Kontext erzeugt. Wenn du mir deine Mail gibst, würd ich dir die Funktion mal zumailen. Ist aber eine c++ Funktion

schöne Grüße
 
Halli hallo,

danke für deinen Beitrag, das hat mir schon enorm weitergeholfen, dass macht für mich jetzt alles auch mehr Sinn.

Leider musste ich meine kleine Schnittstelle "wegen Windows" nun etwas umschreiben und konnte Fenster- und Kontext-Erstellung nicht trennen.

Nun weis ich auch das man bei der WGL extension WGL_ARB_create_context angeben kann, welche version man braucht, und ob es sich um ein Core- oder Kompatibilitäts-Kontext handeln soll.

Alles in allem ist das ein ganz schönes wirrwar geworden, wobei der Initialisierungscode der Verwendenden Anwendung um einiges kürzer wurde.

C:
#include "cgl.h"
#include "cgl_window.h"
#include "cgl_context.h"

#include <Windows.h>
#include <stdio.h>
#include <gl/gl.h>

static void WndSizeChanged(CGLWND wnd, int fullscreen, int width, int height);
static int WndClosing(CGLWND wnd);
static void WndClose(CGLWND wnd);

static void RenderFrame(CGLWND wnd);

int main(int argc, char** argv)
{
	CGLWND wnd;
	CGLCTX ctx;

	UNREFERENCED_PARAMETER(argc);
	UNREFERENCED_PARAMETER(argv);

	if (cglInit() != 0)
	{
		fprintf(stderr, "cglInit() failed!\n");
		getchar();
		return 1;
	}

	if (cglCreate(0, 0, 800, 600, "OpenGL Window", &WndSizeChanged, &WndClosing, &WndClose, GLV_2, 0, 0, &wnd, &ctx) != 0)
	{
		fprintf(stderr, "cglCreate() failed!\n");
		getchar();
		return 2;
	}

	cglwSetFullscreen(wnd, 0, 0);

	fprintf(stdout, "%s\n", glGetString(GL_VENDOR));
	fprintf(stdout, "%s\n", glGetString(GL_RENDERER));
	fprintf(stdout, "OpenGL %s\n", glGetString(GL_VERSION));

	// set the clear colour to a dark blue
	glClearColor(0, 0, 0.25, 0);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthRange(0.0f, 1.0f);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	cglwEnterRenderLoop(wnd, &RenderFrame);
	cglcSelect(NULL, NULL);
	cglcDelete(ctx);
	cglwDelete(wnd);
	getchar();
	return 0;
}

void WndSizeChanged(CGLWND wnd, int fullscreen, int width, int height)
{
	fprintf(stdout, "%s: ", __FUNCTION__);

	if (cglwIsHidden(wnd))
	{
		// When a window got hidden, the renderframe callback is not called anymore
		fprintf(stdout, "HIDDEN\n");
	}
	else
	{
		// adjust ogl viewport
		glViewport(0, 0, width, height);
		fprintf(stdout, "%s, %dx%d\n", fullscreen ? "fullscreen" : "windowed", width, height);
	}
}

int WndClosing(CGLWND wnd)
{
	UNREFERENCED_PARAMETER(wnd);

	// TODO: Ask the user if he really want's to quit, if not, return 1
	fprintf(stdout, "%s\n", __FUNCTION__);
	return 0;
}

void WndClose(CGLWND wnd)
{
	fprintf(stdout, "%s\n", __FUNCTION__);
	cglwLeaveRenderLoop(wnd);
}

void RenderFrame(CGLWND wnd)
{
	UNREFERENCED_PARAMETER(wnd);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glRotatef(1, 1, 1, 1);

	// Triangle
	glBegin(GL_TRIANGLES);
	glColor3f(1.0f, 0.0f, 0.0f);
	glVertex3f(0.0f, 0.5f, 0.0f);
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex3f(-0.5f, -0.5f, 0.0f);
	glColor3f(0.0f, 0.0f, 1.0f);
	glVertex3f(0.5f, -0.5f, 0.0f);
	glEnd();
}

Den gesammten Code habe ich als ZIP-Datei angehängt.

Anmerkung: Die Vollbildumschaltung mit [ALT+ENTER] funktioniert bei mir unter Windows 7 wunderbar, nur unter Windows 8 wurde mir berichtet, das das nicht so ganz funktioniert.
 

Anhänge

  • cgl.zip
    30,6 KB · Aufrufe: 16
Zuletzt bearbeitet:

Neue Beiträge

Zurück