So, I'm trying to setup basic OpenGL scene using only Win32 API and OpenGL, but I've big problems with loading shaders and glShaderSource function. I'm reading my file like this:
//HEADER
class FileReader
{
public:
FileReader(const LPCSTR FileName);
const void* GetFileData();
~FileReader();
private:
HANDLE FileHandle;
void* FileDataMemory;
};
//ACTUAL CODE
FileReader::FileReader(const LPCSTR FileName)
{
FileHandle = CreateFileA(FileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (FileHandle == INVALID_HANDLE_VALUE)
{
OutputDebugStringA("Failed to open file ");
OutputDebugStringA(FileName);
OutputDebugStringA(" for reading, application could not be loaded\n");
ExitProcess(-2);
}
unsigned int FileSize = GetFileSize(FileHandle, 0);
DWORD BytesRead;
FileDataMemory = VirtualAlloc(0, FileSize, MEM_COMMIT, PAGE_READWRITE);
ReadFile(FileHandle, FileDataMemory, FileSize, &BytesRead, 0);
if (BytesRead < FileSize)
{
OutputDebugStringA("File was not read completely\n");
}
}
const void* FileReader::GetFileData()
{
return FileDataMemory;
}
FileReader::~FileReader()
{
CloseHandle(FileHandle);
}
And I use this class to load vertex shader from disc like this:
VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, static_cast<const GLchar* const*>(VertexShaderFile->GetFileData()), 0);
But my app gives me an access violation reading address 0xFFFFFFFF on line with glShaderSource. And I'm just so confused, because when I try to see this block of memory in debug mode, it looks properly and has correct data insisde it, so I just don't know what to do.
The shader source code string, which is read form the file is not 0 terminated.
Reserve FileSize+1
bytes of memory and ensure that the last byte of the buffer is 0. e.g.:
FileDataMemory = VirtualAlloc(0, FileSize+1, MEM_COMMIT, PAGE_READWRITE);
ZeroMemory(FileDataMemory, FileSize+1);
ReadFile(FileHandle, FileDataMemory, FileSize, &BytesRead, 0);
Further, the 3rd parameter to glShaderSource
is an array of strings (const GLchar **
):
const GLchar *source = static_cast<const GLchar*>(VertexShaderFile->GetFileData());
glShaderSource(VertexShader, 1, &source, 0);
What you actually do in your code is to cast VertexShaderFile->GetFileData()
. What you would have to do ist to cast &VertexShaderFile->GetFileData()
Furthermore, I recommend to use STL to read the shader source file. e.g:
std::ifstream sourceFile(FileName, std::fstream::in);
std::string sourceCode = std::string(
std::istreambuf_iterator<char>(sourceFile),
std::istreambuf_iterator<char>());
User contributions licensed under CC BY-SA 3.0