Fixed SimpleTexturedOpenGL sample.

Several places in the sample's code were calling Unicode versions of Win32 functions with "multibyte" strings. A few changes were required to fix it.

I added a class "UTFConverter", which handles calls to unicode/multibyte string conversions. This should help minimize the impacts on code change in case C++'s codecvt_utf8 ever changes.

In addition, seveal memory leaks have been found, but these fixes will come in another PR because it goes beyond the scope of this PR.

DevIL.lib was removed in CMakeFiles.txt, as it is unused in the sample.

Here is a list of the changes:

- Fixed MB string calls to Unicode functions.
- Added class UTFConverter to handle string conversions.
- Removed reference to DevIL.lib.
- Fixed compile warnings.
pull/3015/head
Marc-Antoine Lortie 2020-02-15 18:02:12 -05:00
parent a0000e5be4
commit d9042e4609
2 changed files with 54 additions and 22 deletions

View File

@ -35,7 +35,7 @@ ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
TARGET_LINK_LIBRARIES( assimp_simpletexturedogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} DevIL.lib ) TARGET_LINK_LIBRARIES( assimp_simpletexturedogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} )
SET_TARGET_PROPERTIES( assimp_simpletexturedogl PROPERTIES SET_TARGET_PROPERTIES( assimp_simpletexturedogl PROPERTIES
OUTPUT_NAME assimp_simpletexturedogl OUTPUT_NAME assimp_simpletexturedogl

View File

@ -21,6 +21,8 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "contrib/stb_image/stb_image.h" #include "contrib/stb_image/stb_image.h"
#include <locale>
#include <codecvt>
#include <fstream> #include <fstream>
//to map image filenames to textureIds //to map image filenames to textureIds
@ -75,6 +77,36 @@ GLuint* textureIds; // pointer to texture Array
// Create an instance of the Importer class // Create an instance of the Importer class
Assimp::Importer importer; Assimp::Importer importer;
// Used to convert between multibyte and unicode strings.
class UTFConverter {
using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
public:
UTFConverter(const char* s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::string& s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::wstring& s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
inline const std::string& str() const {
return s_;
}
inline const wchar_t* c_wstr() const {
return ws_.c_str();
}
private:
static UTFConverterImpl impl_;
std::string s_;
std::wstring ws_;
};
typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
void createAILogger() void createAILogger()
{ {
// Change this line to normal if you not want to analyse the import process // Change this line to normal if you not want to analyse the import process
@ -120,7 +152,7 @@ bool Import3DFromFile( const std::string& pFile)
} }
else else
{ {
MessageBox(NULL, ("Couldn't open file: " + pFile).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION); MessageBox(NULL, UTFConverter("Couldn't open file: " + pFile).c_wstr() , TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
logInfo( importer.GetErrorString()); logInfo( importer.GetErrorString());
return false; return false;
} }
@ -205,7 +237,7 @@ int LoadGLTextures(const aiScene* scene)
} }
} }
int numTextures = textureIdMap.size(); const size_t numTextures = textureIdMap.size();
/* array with DevIL image IDs */ /* array with DevIL image IDs */
@ -217,13 +249,13 @@ int LoadGLTextures(const aiScene* scene)
/* create and fill array with GL texture ids */ /* create and fill array with GL texture ids */
textureIds = new GLuint[numTextures]; textureIds = new GLuint[numTextures];
glGenTextures(numTextures, textureIds); /* Texture name generation */ glGenTextures(static_cast<GLsizei>(numTextures), textureIds); /* Texture name generation */
/* get iterator */ /* get iterator */
std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin(); std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin();
std::string basepath = getBasePath(modelpath); std::string basepath = getBasePath(modelpath);
for (int i=0; i<numTextures; i++) for (size_t i=0; i<numTextures; i++)
{ {
//save IL image ID //save IL image ID
@ -268,7 +300,7 @@ int LoadGLTextures(const aiScene* scene)
else else
{ {
/* Error occurred */ /* Error occurred */
MessageBox(NULL, ("Couldn't load Image: " + fileloc).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION); MessageBox(NULL, UTFConverter("Couldn't load Image: " + fileloc).c_wstr(), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
} }
} }
// Because we have already copied image data into texture data we can release memory used by image. // Because we have already copied image data into texture data we can release memory used by image.
@ -534,31 +566,31 @@ void KillGLWindow() // Properly Kill The Window
{ {
if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts? 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); MessageBox(NULL, TEXT("Release Of DC And RC Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
} }
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{ {
MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); MessageBox(NULL, TEXT("Release Rendering Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
} }
hRC = NULL; hRC = NULL;
} }
if (hDC && !ReleaseDC(hWnd, hDC)) // Are We able to Release The DC? if (hDC && !ReleaseDC(hWnd, hDC)) // Are We able to Release The DC?
{ {
MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); MessageBox(NULL, TEXT("Release Device Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
hDC=NULL; hDC=NULL;
} }
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window
{ {
MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); MessageBox(NULL, TEXT("Could Not Release hWnd."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
hWnd = NULL; hWnd = NULL;
} }
if (!UnregisterClass("OpenGL", hInstance)) // Are We Able To Unregister Class if (!UnregisterClass(TEXT("OpenGL"), hInstance)) // Are We Able To Unregister Class
{ {
MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); MessageBox(NULL, TEXT("Could Not Unregister Class."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
hInstance = NULL; hInstance = NULL;
} }
} }
@ -566,7 +598,7 @@ void KillGLWindow() // Properly Kill The Window
GLboolean abortGLInit(const char* abortMessage) GLboolean abortGLInit(const char* abortMessage)
{ {
KillGLWindow(); // Reset Display KillGLWindow(); // Reset Display
MessageBox(NULL, abortMessage, "ERROR", MB_OK|MB_ICONEXCLAMATION); MessageBox(NULL, UTFConverter(abortMessage).c_wstr(), TEXT("ERROR"), MB_OK|MB_ICONEXCLAMATION);
return FALSE; // quit and return False return FALSE; // quit and return False
} }
@ -594,11 +626,11 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the default arrow wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the default arrow
wc.hbrBackground= NULL; // No Background required for OpenGL wc.hbrBackground= NULL; // No Background required for OpenGL
wc.lpszMenuName = NULL; // No Menu wc.lpszMenuName = NULL; // No Menu
wc.lpszClassName= "OpenGL"; // Class Name wc.lpszClassName= TEXT("OpenGL"); // Class Name
if (!RegisterClass(&wc)) if (!RegisterClass(&wc))
{ {
MessageBox(NULL, "Failed to register the window class", "ERROR", MB_OK | MB_ICONEXCLAMATION); MessageBox(NULL, TEXT("Failed to register the window class"), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return FALSE; //exit and return false return FALSE; //exit and return false
} }
@ -616,14 +648,14 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{ {
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window. // If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
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) if (MessageBox(NULL,TEXT("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),TEXT("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{ {
fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE) fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE)
} }
else else
{ {
//Popup Messagebox: Closing //Popup Messagebox: Closing
MessageBox(NULL, "Program will close now.", "ERROR", MB_OK|MB_ICONSTOP); MessageBox(NULL, TEXT("Program will close now."), TEXT("ERROR"), MB_OK|MB_ICONSTOP);
return FALSE; //exit, return false return FALSE; //exit, return false
} }
} }
@ -644,8 +676,8 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requestes Size AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requestes Size
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name TEXT("OpenGL"), // Class Name
title, // Window Title UTFConverter(title).c_wstr(), // Window Title
WS_CLIPSIBLINGS | // Required Window Style WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN | // Required Window Style WS_CLIPCHILDREN | // Required Window Style
dwStyle, // Selected WIndow Style dwStyle, // Selected WIndow Style
@ -807,14 +839,14 @@ int WINAPI WinMain( HINSTANCE hInstance, // The instance
if (argv != NULL && argc > 1) if (argv != NULL && argc > 1)
{ {
std::wstring modelpathW(argv[1]); std::wstring modelpathW(argv[1]);
modelpath = std::string(modelpathW.begin(), modelpathW.end()); modelpath = UTFConverter(modelpathW).str();
} }
if (!Import3DFromFile(modelpath)) return 0; if (!Import3DFromFile(modelpath)) return 0;
logInfo("=============== Post Import ===================="); logInfo("=============== Post Import ====================");
if (MessageBox(NULL, "Would You Like To Run In Fullscreen Mode?", "Start Fullscreen?", MB_YESNO|MB_ICONEXCLAMATION)==IDNO) if (MessageBox(NULL, TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start Fullscreen?"), MB_YESNO|MB_ICONEXCLAMATION)==IDNO)
{ {
fullscreen=FALSE; fullscreen=FALSE;
} }
@ -881,5 +913,5 @@ int WINAPI WinMain( HINSTANCE hInstance, // The instance
destroyAILogger(); destroyAILogger();
KillGLWindow(); KillGLWindow();
return (msg.wParam); return static_cast<int>(msg.wParam);
} }