June 15, 2009

Custom 3D Loader and Viewer

10 OCT 2015. NOTE: This is too old - outdated code. (The concept of retrieving/loading data/vertex still can be use)
OpenGL 3D object loader in action!

Made this on somewhere around 2007 - on my other site. Posting the source code here..

// 3D Viewer for Ababil // Created by MZIskandar 2007 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glext.h> #include <time.h> #include "3DData.h" // Windows globals, defines, and prototypes char szAppName[] = "3D Viewer"; HWND ghWnd; HDC ghDC; HGLRC ghRC; #define SWAPBUFFERS SwapBuffers(ghDC) #define WIDTH 640 #define HEIGHT 320 LONG WINAPI MainWndProc (HWND, UINT, WPARAM, LPARAM); BOOL bSetupPixelFormat(HDC); // OpenGL globals, defines, and prototypes float aspect = (float)WIDTH / (float)HEIGHT; float zNear = 1.0f; float zFar = 1024.0f; float TWOPI_OVER_360 = (2*M_PI)/360.0f; GLfloat SpinX = 0.0f; GLfloat SpinY = 0.0f; GLfloat Zoom = -50.0f; GLvoid resize(GLsizei, GLsizei); GLvoid initializeGL(GLsizei, GLsizei); GLvoid drawScene(GLvoid); PFNGLGENBUFFERSPROC glGenBuffers = NULL; PFNGLBINDBUFFERPROC glBindBuffer = NULL; PFNGLBUFFERDATAPROC glBufferData = NULL; PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL; GLuint vertexBuffer = 0; 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 ghWnd = CreateWindow ( szAppName, "3D Viewer for Ababil", WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL ); // Make sure window was created if (!ghWnd) return FALSE; // Show and update main window ShowWindow(ghWnd, nCmdShow); UpdateWindow(ghWnd); // Animation loop while (1) { while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE) { if (GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } else { return TRUE; } } drawScene(); } } // Main window procedure LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static POINT ptLastMousePosit; static POINT ptCurrentMousePosit; static int bLMousing, bRMousing; LONG lRet = 1; RECT rect; switch (uMsg) { case WM_CREATE: { ghDC = GetDC(hWnd); if(!bSetupPixelFormat(ghDC)) PostQuitMessage (0); ghRC = wglCreateContext(ghDC); wglMakeCurrent(ghDC, ghRC); GetClientRect(hWnd, &rect); initializeGL(rect.right, rect.bottom); break; } case WM_PAINT: { drawScene(); static int frames; static clock_t oldTime; static float rate; frames++; if (frames >= 100) { clock_t newTime = clock(); // Optimizing.. // rate = 100.0f / ((newTime - oldTime) / 1000.0); rate = frames / ((newTime - oldTime) * 0.001); oldTime = newTime; char buffer[64]; sprintf(buffer, "3D Viewer for Ababil [mziskandar@yahoo.com] FPS: %3.2f", rate); SetWindowText(hWnd, buffer); frames = 0; } break; } case WM_SIZE: { GetClientRect(hWnd, &rect); resize(rect.right, rect.bottom); break; } case WM_CLOSE: { if (ghRC) wglDeleteContext(ghRC); if (ghDC) ReleaseDC(hWnd, ghDC); ghRC = 0; ghDC = 0; DestroyWindow(hWnd); break; } case WM_DESTROY: { if (ghRC) wglDeleteContext(ghRC); if (ghDC) ReleaseDC(hWnd, ghDC); glDeleteBuffers(1, &vertexBuffer); PostQuitMessage (0); break; } case WM_KEYDOWN: { switch( wParam ) case VK_ESCAPE: PostQuitMessage(0); break; break; } case WM_LBUTTONDOWN: { ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD(lParam); ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD(lParam); bLMousing = 1; break; } case WM_LBUTTONUP: { bLMousing = 0; break; } case WM_RBUTTONDOWN: { ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD(lParam); ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD(lParam); bRMousing = 1; break; } case WM_RBUTTONUP: { bRMousing = 0; break; } case WM_MOUSEMOVE: { ptCurrentMousePosit.x = LOWORD(lParam); ptCurrentMousePosit.y = HIWORD(lParam); if(bLMousing) { SpinX -= (ptCurrentMousePosit.x-ptLastMousePosit.x); SpinY -= (ptCurrentMousePosit.y-ptLastMousePosit.y); } if(bRMousing) { Zoom -= (ptCurrentMousePosit.y-ptLastMousePosit.y); } ptLastMousePosit = ptCurrentMousePosit; break; } default: { lRet = (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); break; } } return lRet; } BOOL bSetupPixelFormat(HDC hdc) { 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 FALSE; } if(SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { MessageBox(NULL,"SetPixelFormat failed", "Error", MB_OK); return FALSE; } return TRUE; } // OpenGL code // ----------- GLvoid resize(GLsizei width, GLsizei height) { glViewport( 0, 0, width, height ); aspect = ((GLfloat) width / (GLfloat) height); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); GLdouble half_height = zNear * tan( 60.0 * 0.5 * TWOPI_OVER_360 ); GLdouble half_width = half_height * aspect; glFrustum( -half_width, half_width, -half_height, half_height, zNear, zFar ); glMatrixMode(GL_MODELVIEW); } GLvoid createObjects() { glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"); glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"); glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Release buffer after usage. // --------------------------- glVertexPointer(3, GL_FLOAT, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); } GLvoid initializeGL(GLsizei width, GLsizei height) { glEnable(GL_DEPTH_TEST); glPolygonOffset(1.0, 1.0); glClearColor(0.0, 0.0, 0.0, 0.0); glDisable(GL_NORMALIZE); glEnable(GL_CULL_FACE); resize(WIDTH, HEIGHT); createObjects(); } GLvoid drawScene(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef( 0.0, 0.0, Zoom ); glRotatef( -SpinY*0.2, 1.0, 0.0, 0.0 ); glRotatef( -SpinX*0.2, 0.0, 1.0, 0.0 ); glEnableClientState(GL_VERTEX_ARRAY); // Hidden line remover // ------------------- glColor3f(0.0,0.0,0.0); glPolygonMode(GL_FRONT, GL_FILL); glEnable(GL_POLYGON_OFFSET_FILL); glDrawArrays(GL_TRIANGLES, 0, 25128); glDisable(GL_POLYGON_OFFSET_FILL); glColor3f(1.0,1.0,1.0); glPolygonMode(GL_FRONT, GL_LINE); glDrawArrays(GL_TRIANGLES, 0, 25128); glDisableClientState(GL_VERTEX_ARRAY); SWAPBUFFERS; }




With pre-baked rendered textures.

The "3DData.h" containing..

const float vertices[]={ -2.4000f,2.5907f,11.0000f,-1.2972f,2.3958f,11.0000f,-1.3320f,2.3501f,9.0000f, ... and so on .. ... and so on .. };



Its and array containing 3D objects vertices from .obj files. The later version with textures.. I lost the codes.. looks like this. Now I'm trying to port to OpenGL 3.

3 comments:

namik_pasha said...

gile2 openGL siot

MZIskandar said...

What the.. argghh.. sorry. The code are broken (sytax highlighting, special characters, etc) since I updated the blogger theme. Does anyone still required this source?

MZIskandar said...

Fixed the syntax highlighter.