Hello…
I use my own C++ library framework over Win32 & OpenGL to produce applications with OpenGL support!
That is little key fragments of my code:
1 - Init OpenGL 3.3 context:
template<typename T> T& MetaWindow<T>::init() {
WNDCLASSEX wcx;
HGLRC tempRenderContext;
RECT windowRect;
PIXELFORMATDESCRIPTOR pixelFormat;
int format, sizex, sizey;
// declare opengl forward context attributes
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = 0;
int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0 };
memset(&wcx, 0, sizeof(wcx));
memset(&pixelFormat, 0, sizeof(pixelFormat));
mode.dmSize = sizeof(mode);
EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &mode);
// register new window class
wcx.cbSize = sizeof(wcx);
wcx.style = classStyle;
wcx.lpfnWndProc = static_cast<WNDPROC> (startMessageRouter);
wcx.hInstance = instance;
wcx.hbrBackground = static_cast<HBRUSH> (GetStockObject(WHITE_BRUSH));
wcx.lpszClassName = className;
wcx.hIcon = LoadIcon(0, IDI_APPLICATION);
wcx.hCursor = LoadCursor(0, IDC_ARROW);
if (!RegisterClassEx(&wcx))
throw Exceptions::BadClassAtom(GetLastError());
// create new window
sizex = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
sizey = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
handle = CreateWindowEx(extendStyle, className, title, style, sizex, sizey,
width, height, static_cast<HWND> (0), static_cast<HMENU> (0),
instance, static_cast<LPVOID> (this));
if (!handle)
throw Exceptions::BadWindowHandle(GetLastError());
context = GetDC(handle);
// choose pixel format
pixelFormat.nSize = sizeof(pixelFormat);
pixelFormat.nVersion = 1;
pixelFormat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pixelFormat.iPixelType = PFD_TYPE_RGBA;
pixelFormat.cColorBits = 32;
pixelFormat.cDepthBits = 16;
format = ChoosePixelFormat(context, &pixelFormat);
if (!format)
throw Exceptions::BadPixelFormat(GetLastError());
if (!SetPixelFormat(context, format, &pixelFormat))
throw Exceptions::BadPixelFormat(GetLastError());
// create temp render context
tempRenderContext = wglCreateContext(context);
if (!tempRenderContext)
throw Exceptions::BadRenderContext(GetLastError());
if (!wglMakeCurrent(context, tempRenderContext))
throw Exceptions::BadRenderContext(GetLastError());
wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC> (wglGetProcAddress("wglCreateContextAttribsARB"));
if (wglCreateContextAttribsARB == 0)
throw Exceptions::BadExtension("wglCreateContextAttribsARB");
// create forward render context
renderContext = wglCreateContextAttribsARB(context, 0, attribs);
if (!renderContext) {
throw Exceptions::BadRenderContext(GetLastError());
wglDeleteContext(tempRenderContext);
}
if (!wglMakeCurrent(context, renderContext)) {
throw Exceptions::BadRenderContext(GetLastError());
wglDeleteContext(tempRenderContext);
}
// print some information to log
fprintf(stderr, "OpenGL render context information:
");
fprintf(stderr, "Renderer : %s
", reinterpret_cast<const char*> (glGetString(GL_RENDERER)));
fprintf(stderr, "Vendor : %s
", reinterpret_cast<const char*> (glGetString(GL_VENDOR)));
fprintf(stderr, "Version : %s
", reinterpret_cast<const char*> (glGetString(GL_VERSION)));
fprintf(stderr, "GLSL version : %s
", reinterpret_cast<const char*> (glGetString(GL_SHADING_LANGUAGE_VERSION)));
// delete temp render context
wglDeleteContext(tempRenderContext);
// initialize OpenGL extensions
Extensions::init();
// show window and bring it to top
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
active = true;
// get window size
GetClientRect(handle, &windowRect);
width = windowRect.right - windowRect.left;
height = windowRect.bottom - windowRect.top;
// set default viewport
glViewport(0, 0, width, height);
return *self;
}
2 - Init function for main window:
typedef MetaWindow<Window> Base;
Window(const char * title) :
Base(title), itMV(MV), lightPosition(0.0f, 0.0f, 5.0f), alpha(0.0f) {
}
Window& init() {
width = height = 1000;
Base::init();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glEnable( GL_DEPTH_TEST);
PM(45.0f, static_cast<float> (width) / height, 0.1f, 100.0f);
TM(0.0f, 0.0f, -4.0f);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
colorTexture.generate()(GL_TEXTURE_2D);
Texture::parameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Texture::parameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Texture::parameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
Texture::parameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Texture::parameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Texture::image2DfromTGA("data/images/galaxy-cluster-ACO-3341.tga");
vertexShader.create(GL_VERTEX_SHADER)("data/shaders/simple-vertex.glsl");
fragmentShader.create(GL_FRAGMENT_SHADER)("data/shaders/simple-fragment.glsl");
program.create().attachShader(vertexShader).attachShader(fragmentShader).link().validate();
positionIndex = program.getAttribLocation("Vertex");
normalIndex = program.getAttribLocation("Normal");
texcoordIndex = program.getAttribLocation("TexCoord");
projectionIndex = program.getUniformLocation("PM");
modelviewIndex = program.getUniformLocation("MV");
itModelviewIndex = program.getUniformLocation("itMV");
lightPositionIndex = program.getUniformLocation("LightPosition");
glEnableVertexAttribArray(positionIndex);
glEnableVertexAttribArray(normalIndex);
glEnableVertexAttribArray(texcoordIndex);
program();
colorTextureIndex = program.getUniformLocation("ColorTexture");
glUniform1i(colorTextureIndex, 0);
glUniform4fv(lightPositionIndex, 1, lightPosition);
glUniformMatrix4fv(projectionIndex, 1, GL_TRUE, PM);
glGenBuffers(4, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeNormals), cubeNormals, GL_STATIC_DRAW);
glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeTexcoords), cubeTexcoords, GL_STATIC_DRAW);
glVertexAttribPointer(texcoordIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[3]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);
colorTexture(GL_TEXTURE_2D);
return *this;
}
3 - WinMain function:
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR cmdline, int cmdshow) {
Window window(“Приветики…”);
try {
return window.init()();
} catch (Exceptions::Exception& e) {
std::cerr << e.what() << std::endl;
return 0;
}
}
4 - fragment shader code:
#version 330
precision highp float;
in vec4 DiffuseSpecular;
in vec2 TexCoords;
uniform sampler2D ColorTexture;
out vec4 Color;
void main() {
Color = texture(ColorTexture, TexCoords) * DiffuseSpecular;
}
5 - vertex shader code:
#version 330
invariant in vec3 Vertex;
in vec3 Normal;
in vec2 TexCoord;
uniform mat4 PM;
uniform mat4 MV;
uniform mat4 itMV;
uniform vec4 LightPosition;
out vec4 DiffuseSpecular;
out vec2 TexCoords;
void main() {
vec4 vertex = MV * vec4(Vertex, 1.0);
vec3 normal = normalize(mat3(itMV) * Normal);
vec3 l = normalize(LightPosition.xyz - vertex.xyz);
vec3 h = normalize(l + vec3(0.0, 0.0, 1.0));
const float specularExp = 128.0;
// calculate diffuse lighting
float NdotL = max(0.0, dot(normal, l));
vec4 diffuse = vec4(NdotL);
// calculate specular lighting
float NdotH = max(0.0, dot(normal, h));
vec4 specular = vec4(0.0);
if (NdotH > 0.0)
specular = vec4(pow(NdotH, specularExp));
DiffuseSpecular = diffuse + specular;
TexCoords = TexCoord;
gl_Position = PM * vertex;
}