Window Creation in Win 7

Started by
29 comments, last by Dim_Yimma_H 8 years ago

GLEW is a third-party library that contains code for loading all those function addresses etc. I don't have a code example unfortunately, but their site shows how to use it, just click on Usage at glew.sourceforge.net.

Advertisement
Awesome! Thanks!

So I checked GLEW and it looks like the tutorials suggest a use GLUT for window creation and handling.

I'd like to use as much windows code as possible. ( I am a linux sysadmin learning windows programming so I can use the practice :)

Is it possible to use the GLEW extensions with windows code like WndPrc and LRESULT CALLBACK functions?

Any OpenGL method called works on the OpenGL context that is 'current' on the calling thread, same thing with what GLEW calls OpenGL for.

Once wglMakeCurrent has been called the OpenGL context you have created is current on the thread, so everything will work the same as if the window was created with some other method.

Cool! Thanks!

Hi Guys,

It's been a while but I've since been able to ( assumedly ) get glew working.. or maybe not because this code below crashes at runtime...

I am assuming the pointers didn't map correctly even tho the code compiles. Any have any advice?


#include <windows.h>
//#include <gl/gl.h>
#include <GL/glew.h>
//#include <GL/glut.h>

#pragma comment (lib, "opengl32.lib")

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

// Main
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX wc = {};
	wc.cbSize = sizeof(wc);
	wc.lpszClassName = TEXT("MyClass");
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.style = CS_OWNDC;
	RegisterClassEx(&wc);

	// Window
	HWND hWnd = CreateWindowEx(
		0,
		wc.lpszClassName,
		TEXT("OpenGL Window"),
		WS_OVERLAPPEDWINDOW |
		WS_CLIPSIBLINGS |
		WS_CLIPCHILDREN,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL
		);

	// Get DC
	HDC hDC = GetDC(hWnd);

	// Pixel format
	PIXELFORMATDESCRIPTOR pfd = {};
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags =
		PFD_DRAW_TO_WINDOW |
		PFD_SUPPORT_OPENGL |
		PFD_DOUBLEBUFFER |
		PFD_SUPPORT_COMPOSITION;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 32;

	int pf = ChoosePixelFormat(hDC, &pfd);
	SetPixelFormat(hDC, pf, &pfd);

	// OpenGL context
	HGLRC hGLRC = wglCreateContext(hDC);

	wglMakeCurrent(hDC, hGLRC);

	// Get OpenGL version and set it as window title
	SetWindowTextA(hWnd, (char*)glGetString(GL_VERSION));

	// test opengl
	// glCompileShader(GL_VERTEX_SHADER_FILE);
	static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0 };

	// Main loop
	ShowWindow(hWnd, nCmdShow);
	while (true) {
		MSG msg;
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
			if (msg.message == WM_QUIT)
				break;
			else {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else {
			// Draw
			if ((char*)glGetString(GL_VERSION) != NULL) {
				//glClearColor(0.8956f, 0.3451f, 0.2234f, 1.0f); // <--		THIS LINE WORKS FINE 0.2345f, 0.7845f, 0.8934f, 1.0f
				glClearBufferfv(GL_COLOR, 0, red); // <-- THIS LINE CASUES A RUNTIME CRASH
			}
			else {
				glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //0.8956f, 0.3451f, 0.2234f, 1.0f
			}
			glClear(GL_COLOR_BUFFER_BIT);

			SwapBuffers(hDC);
		}
	}

	// Clean up
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(hGLRC);

	UnregisterClass(wc.lpszClassName, hInstance);

	return 0;
}

// Window proc
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_SIZE:
		// Resize GL rendering area to match window size
		glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
		return 0;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

You don't seem to be linking to or initializing GLEW.

Read this page: https://www.opengl.org/wiki/OpenGL_Loading_Library

As well as this one: http://glew.sourceforge.net/basic.html

oh haha :P thanks again. :)

ok.

Here is some updated code. I added in the glewinit() section and found that it does return GLEW_OK but my function to color the buffer and display it either doesnt run or leaves the buffer empty to show a black window.

Further help?


#include <windows.h>
//#include <gl/gl.h>
#include <GL/glew.h>
//#include <GL/glut.h>
#include <iostream>

using namespace std;

#pragma comment (lib, "opengl32.lib")

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

// Main
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	//ExitProcess(100);
	WNDCLASSEX wc = {};
	wc.cbSize = sizeof(wc);
	wc.lpszClassName = TEXT("MyClass");
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.style = CS_OWNDC;
	RegisterClassEx(&wc);

	// Window
	HWND hWnd = CreateWindowEx(
		0,
		wc.lpszClassName,
		TEXT("OpenGL Window"),
		WS_OVERLAPPEDWINDOW |
		WS_CLIPSIBLINGS |
		WS_CLIPCHILDREN,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL
		);

	// Get DC
	HDC hDC = GetDC(hWnd);

	// Pixel format
	PIXELFORMATDESCRIPTOR pfd = {};
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags =
		PFD_DRAW_TO_WINDOW |
		PFD_SUPPORT_OPENGL |
		PFD_DOUBLEBUFFER |
		PFD_SUPPORT_COMPOSITION;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 32;

	int pf = ChoosePixelFormat(hDC, &pfd);
	SetPixelFormat(hDC, pf, &pfd);

	// OpenGL context
	HGLRC hGLRC = wglCreateContext(hDC);

	wglMakeCurrent(hDC, hGLRC);
	
	glewExperimental = GL_TRUE;
	GLenum err = glewInit();
	if (err != GLEW_OK)
	{
		//Problem: glewInit failed, something is seriously wrong.
		cout << "glewInit failed, aborting." << endl;
		ExitProcess(100); //<-- this does not run.
	}

	// Get OpenGL version and set it as window title
	SetWindowTextA(hWnd, (char*)glGetString(GL_VERSION));

	// test opengl
	// glCompileShader(GL_VERTEX_SHADER_FILE);
	static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0 };

	// Main loop
	ShowWindow(hWnd, nCmdShow);
	while (true) {
		MSG msg;
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
			if (msg.message == WM_QUIT)
				break;
			else {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else {
			// Draw
			if ((char*)glGetString(GL_VERSION) != NULL) {
				//glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //0.8956f, 0.3451f, 0.2234f, 1.0f
				glClearBufferfv(GL_COLOR, 0, red);
				ExitProcess(100); //<--- THIS EXITPROCESS RUNS
			}
			else {
				//glClearColor(0.8956f, 0.3451f, 0.2234f, 1.0f); 
				glClearBufferfv(GL_COLOR, 0, red);
				//ExitProcess(100);
			}
			glClear(GL_COLOR_BUFFER_BIT);

			SwapBuffers(hDC);
		}
	}

	// Clean up
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(hGLRC);

	UnregisterClass(wc.lpszClassName, hInstance);

	return 0;
}

// Window proc
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_SIZE:
		// Resize GL rendering area to match window size
		glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
		return 0;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

You might consider a single Form/Window as high as C# application created- and pass its handle to your c++ module to make context of it. Should be smoother and interesting to see the result right in this situation, since old ways of registering windows are not encouraged on windows 7+ and those ways sure have more pitfals than int he past, to be fully functional and accommodated.

This topic is closed to new replies.

Advertisement