From a134def031a452924931a88bf07642e07e330ffa Mon Sep 17 00:00:00 2001 From: Fatbag Date: Sun, 5 Feb 2012 21:02:28 -0600 Subject: [PATCH] Working head renderer, with pixel-perfect results. As for bodies, all appendages are rendered in the same place... --- Libraries/libvitaboy/CMakeLists.txt | 6 +- Libraries/libvitaboy/Renderer.cpp | 485 ++++++++++++++++++++++++++++ Libraries/libvitaboy/libvitaboy.hpp | 40 ++- Libraries/libvitaboy/mesh.cpp | 62 ++++ 4 files changed, 591 insertions(+), 2 deletions(-) create mode 100644 Libraries/libvitaboy/Renderer.cpp create mode 100644 Libraries/libvitaboy/mesh.cpp diff --git a/Libraries/libvitaboy/CMakeLists.txt b/Libraries/libvitaboy/CMakeLists.txt index abd202c..d2d494c 100644 --- a/Libraries/libvitaboy/CMakeLists.txt +++ b/Libraries/libvitaboy/CMakeLists.txt @@ -8,6 +8,7 @@ set(LIBVITABOY_MINOR 1) set(LIBVITABOY_SOURCES anim.cpp libvitaboy.cpp + mesh.cpp ) if(WIN32) set(LIBVITABOY_SOURCES ${LIBVITABOY_SOURCES} resource.rc) @@ -29,4 +30,7 @@ set_target_properties(libvitaboy_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1) add_executable(vbparse vbparse.cpp) -target_link_libraries(vbparse libvitaboy_static) \ No newline at end of file +target_link_libraries(vbparse libvitaboy_static) + +add_executable(Renderer Renderer.cpp) +target_link_libraries(Renderer libvitaboy_shared "${CMAKE_SOURCE_DIR}/Libraries/libvitaboy/libSOIL.a" opengl32 glu32) \ No newline at end of file diff --git a/Libraries/libvitaboy/Renderer.cpp b/Libraries/libvitaboy/Renderer.cpp new file mode 100644 index 0000000..fce2b49 --- /dev/null +++ b/Libraries/libvitaboy/Renderer.cpp @@ -0,0 +1,485 @@ +/* + * This Code Was Created By Jeff Molofee 2000 + * A HUGE Thanks To Fredric Echols For Cleaning Up + * And Optimizing The Base Code, Making It More Flexible! + * If You've Found This Code Useful, Please Let Me Know. + * Visit My Site At nehe.gamedev.net + */ + +#include // Header File For Windows +#include // Header File For The OpenGL32 Library +#include // Header File For The GLu32 Library +#include +#include "SOIL.h" +#include "libvitaboy.hpp" + +HDC hDC=NULL; // Private GDI Device Context +HGLRC hRC=NULL; // Permanent Rendering Context +HWND hWnd=NULL; // Holds Our Window Handle +HINSTANCE hInstance; // Holds The Instance Of The Application + +bool keys[256]; // Array Used For The Keyboard Routine +bool active=TRUE; // Window Active Flag Set To TRUE By Default +bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default + +float zoom = -4; +float xrot = 0; +float yrot = 0; +float zrot = 90; + +GLuint texture[1]; // Storage For One Texture ( NEW ) + +Mesh_t Mesh; + +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc + +int LoadGLTextures() // Load Bitmaps And Convert To Textures +{ + /* load an image file directly as a new OpenGL texture */ + texture[0] = SOIL_load_OGL_texture("texture.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); + if(texture[0] == 0) + return false; + + // Typical Texture Generation Using Data From The Bitmap + glBindTexture(GL_TEXTURE_2D, texture[0]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + return true; // Return Success +} + +void ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window +{ + if (height==0) // Prevent A Divide By Zero By + { + height=1; // Making Height Equal One + } + + glViewport(0,0,width,height); // Reset The Current Viewport + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + + // Calculate The Aspect Ratio Of The Window + gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glLoadIdentity(); // Reset The Modelview Matrix +} + +int InitGL(void) // All Setup For OpenGL Goes Here +{ + if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW ) + { + return FALSE; // If Texture Didn't Load Return FALSE + } + + glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW ) + glShadeModel(GL_SMOOTH); // Enable Smooth Shading + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background + glClearDepth(1.0f); // Depth Buffer Setup + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations + return TRUE; // Initialization Went OK +} + +int DrawGLScene(void) // Here's Where We Do All The Drawing +{ + if(keys[0x41]){ if(zoom <=-1.0f) zoom += 0.05f; } //A + if(keys[0x53]){ if(zoom >=-10.0f) zoom -= 0.05f; } //S + if(keys[VK_UP]){ if((xrot+=1.0f) >=360) xrot-=360; } + if(keys[VK_DOWN]){ if((xrot-=1.0f) <=-360) xrot+=360; } + if(keys[VK_RIGHT]){ if((yrot+=1.0f) >=360) yrot-=360; } + if(keys[VK_LEFT]){ if((yrot-=1.0f) <=-360) yrot+=360; } + if(keys[0x5A]){ if((zrot+=1.0f) >=360) zrot-=360; } //X + if(keys[0x58]){ if((zrot-=1.0f) <=-360) zrot+=360; } //Z + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer + glLoadIdentity(); // Reset The Current Modelview Matrix + + glTranslatef(0.0f,0.0f,zoom); // Move Into The Screen + glRotatef(xrot,1.0f,0.0f,0.0f); + glRotatef(yrot,0.0f,1.0f,0.0f); + glRotatef(zrot,0.0f,0.0f,1.0f); + + glBindTexture(GL_TEXTURE_2D, texture[0]); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, offsetof(Vertex_t, y)-offsetof(Vertex_t, x)-sizeof(float), Mesh.UnclothedVertexData); + glTexCoordPointer(2, GL_FLOAT, offsetof(TextureVertex_t, v)-offsetof(TextureVertex_t, u)-sizeof(float), Mesh.TextureVertexData); + glDrawElements(GL_TRIANGLES, Mesh.FaceCount*3, GL_UNSIGNED_INT, Mesh.FaceData); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + return TRUE; // Keep Going +} + +void KillGLWindow(void) // Properly Kill The Window +{ + if (fullscreen) // Are We In Fullscreen Mode? + { + ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop + ShowCursor(TRUE); // Show Mouse Pointer + } + + if (hRC) // Do We Have A Rendering Context? + { + if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts? + { + MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + } + + if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? + { + MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + } + hRC=NULL; // Set RC To NULL + } + + if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC + { + MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hDC=NULL; // Set DC To NULL + } + + if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window? + { + MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hWnd=NULL; // Set hWnd To NULL + } + + if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class + { + MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hInstance=NULL; // Set hInstance To NULL + } +} + +/* This Code Creates Our OpenGL Window. Parameters Are: * + * title - Title To Appear At The Top Of The Window * + * width - Width Of The GL Window Or Fullscreen Mode * + * height - Height Of The GL Window Or Fullscreen Mode * + * bits - Number Of Bits To Use For Color (8/16/24/32) * + * fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */ + +BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) +{ + GLuint PixelFormat; // Holds The Results After Searching For A Match + WNDCLASS wc; // Windows Class Structure + DWORD dwExStyle; // Window Extended Style + DWORD dwStyle; // Window Style + RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values + WindowRect.left=(long)0; // Set Left Value To 0 + WindowRect.right=(long)width; // Set Right Value To Requested Width + WindowRect.top=(long)0; // Set Top Value To 0 + WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height + + fullscreen=fullscreenflag; // Set The Global Fullscreen Flag + + hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window. + wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages + wc.cbClsExtra = 0; // No Extra Window Data + wc.cbWndExtra = 0; // No Extra Window Data + wc.hInstance = hInstance; // Set The Instance + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon + wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer + wc.hbrBackground = NULL; // No Background Required For GL + wc.lpszMenuName = NULL; // We Don't Want A Menu + wc.lpszClassName = "OpenGL"; // Set The Class Name + + if (!RegisterClass(&wc)) // Attempt To Register The Window Class + { + MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (fullscreen) // Attempt Fullscreen Mode? + { + DEVMODE dmScreenSettings; // Device Mode + memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared + dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure + dmScreenSettings.dmPelsWidth = width; // Selected Screen Width + dmScreenSettings.dmPelsHeight = height; // Selected Screen Height + dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel + dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + + // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. + if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) + { + // If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode. + if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) + { + fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE + } + else + { + // Pop Up A Message Box Letting User Know The Program Is Closing. + MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP); + return FALSE; // Return FALSE + } + } + } + + if (fullscreen) // Are We Still In Fullscreen Mode? + { + dwExStyle=WS_EX_APPWINDOW; // Window Extended Style + dwStyle=WS_POPUP; // Windows Style + ShowCursor(FALSE); // Hide Mouse Pointer + } + else + { + dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style + dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style + } + + AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size + + // Create The Window + if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window + "OpenGL", // Class Name + title, // Window Title + dwStyle | // Defined Window Style + WS_CLIPSIBLINGS | // Required Window Style + WS_CLIPCHILDREN, // Required Window Style + 0, 0, // Window Position + WindowRect.right-WindowRect.left, // Calculate Window Width + WindowRect.bottom-WindowRect.top, // Calculate Window Height + NULL, // No Parent Window + NULL, // No Menu + hInstance, // Instance + NULL))) // Dont Pass Anything To WM_CREATE + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + bits, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 16, // 16Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context? + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format? + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format? + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + ShowWindow(hWnd,SW_SHOW); // Show The Window + SetForegroundWindow(hWnd); // Slightly Higher Priority + SetFocus(hWnd); // Sets Keyboard Focus To The Window + ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen + + if (!InitGL()) // Initialize Our Newly Created GL Window + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + return TRUE; // Success +} + +LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window + UINT uMsg, // Message For This Window + WPARAM wParam, // Additional Message Information + LPARAM lParam) // Additional Message Information +{ + switch (uMsg) // Check For Windows Messages + { + case WM_ACTIVATE: // Watch For Window Activate Message + { + // LoWord Can Be WA_INACTIVE, WA_ACTIVE, WA_CLICKACTIVE, + // The High-Order Word Specifies The Minimized State Of The Window Being Activated Or Deactivated. + // A NonZero Value Indicates The Window Is Minimized. + if ((LOWORD(wParam) != WA_INACTIVE) && !((BOOL)HIWORD(wParam))) + active=TRUE; // Program Is Active + else + active=FALSE; // Program Is No Longer Active + + return 0; // Return To The Message Loop + } + + case WM_SYSCOMMAND: // Intercept System Commands + { + switch (wParam) // Check System Calls + { + case SC_SCREENSAVE: // Screensaver Trying To Start? + case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? + return 0; // Prevent From Happening + } + break; // Exit + } + + case WM_CLOSE: // Did We Receive A Close Message? + { + PostQuitMessage(0); // Send A Quit Message + return 0; // Jump Back + } + + case WM_KEYDOWN: // Is A Key Being Held Down? + { + keys[wParam] = TRUE; // If So, Mark It As TRUE + return 0; // Jump Back + } + + case WM_KEYUP: // Has A Key Been Released? + { + keys[wParam] = FALSE; // If So, Mark It As FALSE + return 0; // Jump Back + } + + case WM_SIZE: // Resize The OpenGL Window + { + ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height + return 0; // Jump Back + } + } + + // Pass All Unhandled Messages To DefWindowProc + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +int WINAPI WinMain( HINSTANCE hInstance, // Instance + HINSTANCE hPrevInstance, // Previous Instance + LPSTR lpCmdLine, // Command Line Parameters + int nCmdShow) // Window Show State +{ + MSG msg; // Windows Message Structure + BOOL done=FALSE; // Bool Variable To Exit Loop + + // Ask The User Which Screen Mode They Prefer + if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) + { + fullscreen=FALSE; // Windowed Mode + } + + HANDLE hFile; + unsigned FileSize; + uint8_t *InData; + DWORD bytestransferred; + + hFile = CreateFile("mesh.mesh", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if(hFile == INVALID_HANDLE_VALUE){ + if(GetLastError() == ERROR_FILE_NOT_FOUND){ + MessageBox(NULL, "The specified mesh does not exist.", "Error", MB_OK); + return -1; + } + MessageBox(NULL, "The mesh could not be opened for reading.", "Error", MB_OK); + return -1; + } + FileSize = GetFileSize(hFile, NULL); + InData = (uint8_t*) malloc(FileSize); + if(InData == NULL){ + MessageBox(NULL, "Memory for the mesh could not be allocated.", "Error", MB_OK); + return -1; + } + if(!ReadFile(hFile, InData, FileSize, &bytestransferred, NULL) || bytestransferred != FileSize){ + MessageBox(NULL, "The mesh could not be read.", "Error", MB_OK); + return -1; + } + CloseHandle(hFile); + + VBFile.set(InData, FileSize); + ReadMesh(Mesh); + + // Create Our OpenGL Window + if (!CreateGLWindow("libvitaboy - Renderer",640,480,16,fullscreen)) + { + return 0; // Quit If Window Was Not Created + } + + while(!done) // Loop That Runs While done=FALSE + { + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? + { + if (msg.message==WM_QUIT) // Have We Received A Quit Message? + { + done=TRUE; // If So done=TRUE + } + else // If Not, Deal With Window Messages + { + TranslateMessage(&msg); // Translate The Message + DispatchMessage(&msg); // Dispatch The Message + } + } + else // If There Are No Messages + { + // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() + if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received? + { + done=TRUE; // ESC or DrawGLScene Signalled A Quit + } + else // Not Time To Quit, Update Screen + { + SwapBuffers(hDC); // Swap Buffers (Double Buffering) + } + + if (keys[VK_F1]) // Is F1 Being Pressed? + { + keys[VK_F1]=FALSE; // If So Make Key FALSE + KillGLWindow(); // Kill Our Current Window + fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode + // Recreate Our OpenGL Window + if (!CreateGLWindow("NeHe's Solid Object Tutorial",640,480,16,fullscreen)) + { + return 0; // Quit If Window Was Not Created + } + } + } + } + + // Shutdown + KillGLWindow(); // Kill The Window + return (msg.wParam); // Exit The Program +} diff --git a/Libraries/libvitaboy/libvitaboy.hpp b/Libraries/libvitaboy/libvitaboy.hpp index bb467bd..c2cb670 100644 --- a/Libraries/libvitaboy/libvitaboy.hpp +++ b/Libraries/libvitaboy/libvitaboy.hpp @@ -76,6 +76,10 @@ class VBFile_t { extern VBFile_t VBFile; +/**** +** Animation (*.anim) +*/ + struct Translation_t { float x, y, z; }; @@ -153,4 +157,38 @@ void ReadMotion(Animation_t& Animation, Motion_t& Motion); void ReadPropsList(PropsList_t& PropsList); void ReadPropsLists(Motion_t& Motion); void ReadTimePropsList(TimePropsList_t& TimePropsList); -void ReadTimePropsLists(Motion_t& Motion); \ No newline at end of file +void ReadTimePropsLists(Motion_t& Motion); + + +/**** +** Mesh (*.mesh) +*/ + +struct TextureVertex_t { + float u, v; +}; + +struct Vertex_t { + float x, y, z; +}; + +struct Face_t { + unsigned VertexA, VertexB, VertexC; +}; + +struct Mesh_t { + uint32_t Version; + uint32_t BoneCount; + char ** BoneNames; + uint32_t FaceCount; + Face_t * FaceData; + uint32_t BindingCount; + uint32_t TextureVertexCount; + TextureVertex_t * TextureVertexData; + uint32_t BlendDataCount; + uint32_t VertexCount; + Vertex_t * UnclothedVertexData; + Vertex_t * ClothedVertexData; +}; + +void ReadMesh(Mesh_t& Mesh); \ No newline at end of file diff --git a/Libraries/libvitaboy/mesh.cpp b/Libraries/libvitaboy/mesh.cpp new file mode 100644 index 0000000..b6b6920 --- /dev/null +++ b/Libraries/libvitaboy/mesh.cpp @@ -0,0 +1,62 @@ +#include "libvitaboy.hpp" + +void ReadMesh(Mesh_t& Mesh){ + Mesh.Version = VBFile.readint32(); + printf("========== Mesh ==========\n"); + printf("Version: %u\n", Mesh.Version); + + Mesh.BoneCount = VBFile.readint32(); + printf("BoneCount: %u\n", Mesh.BoneCount); + Mesh.BoneNames = (char**) malloc(Mesh.BoneCount * sizeof(char*)); + for(unsigned i=0; i