glShaderSource access violation when using Win32 to read files

0

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.

c++
winapi
opengl
file-io
asked on Stack Overflow Nov 24, 2019 by Poseydon42

1 Answer

2

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>());
answered on Stack Overflow Nov 24, 2019 by Rabbid76 • edited Nov 24, 2019 by Rabbid76

User contributions licensed under CC BY-SA 3.0