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.
gile2 openGL siot
ReplyDeleteWhat the.. argghh.. sorry. The code are broken (sytax highlighting, special characters, etc) since I updated the blogger theme. Does anyone still required this source?
ReplyDeleteFixed the syntax highlighter.
ReplyDelete