20
Hi Jim..
For previous version of OpenGL I'm not using glut and glew - directly "glext.h". I'm a little confused about creating context in OpenGL 3 - That's why I'm using glew right now.
This is another code without glut and glew.. quite messy - experimenting..
I'm trying to understand this: Create gl3 context > vao > vbo > attached shader > object manipulation (eg: rotation, translate, etc)
#include <windows.h>
#include <gl/gl3.h>
#include <gl/wglext.h> //should i remove this?
#include <stdio.h>
char szAppName[] = "3D Viewer";
HWND hWnd;
HDC hDC;
HGLRC hRC;
#define WIDTH 640
#define HEIGHT 320
GLvoid drawScene(GLvoid);
GLvoid createObjects(GLvoid);
LONG WINAPI MainWndProc (HWND, UINT, WPARAM, LPARAM);
const GLchar* vshaderSrc = "in vec3 pos;void main(){gl_Position = vec4(pos, 1);}";
const GLchar* fshaderSrc = "out vec4 color;void main(){color = vec4(1, 0.1, 0, 1);}";
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
PFNGLCREATESHADERPROC glCreateShader = NULL;
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
PFNGLATTACHSHADERPROC glAttachShader = NULL;
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
PFNGLGENBUFFERSPROC glGenBuffers = NULL;
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
PFNGLBUFFERDATAPROC glBufferData = NULL;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
PFNGLDRAWARRAYSPROC glDrawArrays = NULL;
PFNGLCLEARPROC glClear = NULL;
GLuint compileShader(GLenum shaderType, const GLchar* source)
{
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (!status) {
printf("shader compile error");
return 0;
}
return shader;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wndclass;
// Register the frame class
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass)) return FALSE;
// Create the frame
hWnd = CreateWindow ( szAppName,
"3D Viewer for Ababil",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
WIDTH, HEIGHT,
NULL, NULL,
hInstance, NULL );
if (!hWnd){
MessageBox(NULL,"Windows creation failed", "Error",MB_OK);
return FALSE;
}
hDC = GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;
ppfd = &pfd;
ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
ppfd->iPixelType = PFD_TYPE_COLORINDEX;
ppfd->cColorBits = 16;
ppfd->cDepthBits = 16;
ppfd->cAccumBits = 0;
ppfd->cStencilBits = 0;
pixelformat = ChoosePixelFormat(hDC, ppfd);
if((pixelformat = ChoosePixelFormat(hDC, ppfd)) == 0)
{
MessageBox(NULL,"ChoosePixelFormat failed", "Error",MB_OK);
return 0;
}
if(SetPixelFormat(hDC, pixelformat, ppfd) == FALSE)
{
MessageBox(NULL,"SetPixelFormat failed", "Error",MB_OK);
return 0;
}
ShowWindow(hWnd, nCmdShow);
//UpdateWindow(hWnd);
HGLRC tempContext = wglCreateContext(hDC);
wglMakeCurrent(hDC,tempContext);
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//we want a 3.0 context
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
//and it shall be forward compatible so that we can only use up to date functionality
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
}; //zero indicates the end of the array
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; //pointer to the method
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
if (wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported
{
MessageBox(NULL,"Cannot get Proc Adress for CreateContextAttribs", "ERROR",MB_OK);
wglDeleteContext(tempContext);
return 0;
}
if (!(hRC=wglCreateContextAttribsARB(hDC,0, attribs)))
{
wglDeleteContext(tempContext);
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return 0;
}
wglDeleteContext(tempContext);
if (!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return 0;
}
//ShowWindow(hWnd,SW_SHOW); // Show The Window
//SetForegroundWindow(hWnd); // Slightly Higher Priority
//SetFocus(hWnd); // Sets Keyboard Focus To The Window
//createObjects();
glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv");
glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray");
glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
GLuint vshaderID = compileShader(GL_VERTEX_SHADER, vshaderSrc);
GLuint fshaderID = compileShader(GL_FRAGMENT_SHADER, fshaderSrc);
GLuint programID = glCreateProgram();
glAttachShader(programID, vshaderID);
glAttachShader(programID, fshaderID);
glLinkProgram(programID);
GLint status;
glGetProgramiv(programID, GL_LINK_STATUS, &status);
if (!status) {
printf("GL_LINK_STATUS error");
}
// VAO
GLuint vertexArrayID;
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
// VBO
GLuint bufferID;
glGenBuffers(1, &bufferID);
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
float vertexData[] = { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
const GLuint posIndex = glGetAttribLocation(programID, "pos");
// this binds currently binded VBO to VAO
glVertexAttribPointer(posIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posIndex);
glUseProgram(programID);
glDrawArrays = (PFNGLDRAWARRAYSPROC)wglGetProcAddress("glDrawArrays");
glClear = (PFNGLCLEARPROC)wglGetProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
SwapBuffers(hDC);
while (1)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
return 1;
}
}
//drawScene();
}
}
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
break;
}
case WM_PAINT:
{
//drawScene();
break;
}
case WM_CLOSE:
/*if (hRC) wglDeleteContext(hRC);
if (hDC) ReleaseDC(hWnd, hDC);
hRC = 0;
hDC = 0;
DestroyWindow(hWnd);*/
PostQuitMessage(0);
break;
case WM_DESTROY:
/*if (hRC) wglDeleteContext(hRC);
if (hDC) ReleaseDC(hWnd, hDC);*/
return 0;
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
}
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}