Strange OpenGL runtime exceptions

Hello! I was working on a class that would abstract the OpenGL subsystem from the rest of the program using a set of functions, however I keep getting several runtime exceptions which I am unable to decode. I could really use someone else's eyes on this since I am unable to find the error myself.

OGLAbstr.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#ifndef _OGLABSTR_H_
#define _OGLABSTR_H_

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glew32.lib")

#include <GL/glew.h>
#include <GL/wglew.h>
#include <string.h>
#include <iostream>
#include <Windows.h>
#include "LogMgr.h"
#include "resource.h"
#include <vector>
#include "Shaders.h"

namespace EEngine
{
class OGLAbstr
{
public:
	OGLAbstr(HINSTANCE hInst, LogMgr* mLog);
	~OGLAbstr();

	bool initGL(int AA=0);
	bool initGLEW();

	bool openGameWindow(WNDCLASSEX wc, std::string title, int x=0, int y=0);
	bool openEditorWindow(WNDCLASSEX wc);

	bool addPrimitive(const float vPos[]);
	bool testDraw();

	void renderFrame();
	void renderPrimitive();

	HWND Window;
	HWND RenderWindow;

	EEngine::Shaders* shader;

private:
	HDC hDC;
	HMENU Menu;
	HINSTANCE hInstance;
	WNDCLASSEX fakeClass;
	HGLRC hRC;
	std::string className;
	LogMgr* log;
	GLuint VBO;

	bool canRender;
	bool test_draw;
	GLuint testDrawVAO;
	//std::vector<GLuint> vertexBufferList;
};
}

#endif 


OGLAbstr.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

void OGLAbstr::renderFrame()
{
	glClear(GL_COLOR_BUFFER_BIT);

	renderPrimitive();
	//Rendering code
	SwapBuffers(hDC);
}


bool OGLAbstr::addPrimitive(const float vPos[])
{
	/*GLuint VertexBuffer;
	glGenBuffers(1, &VertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vPos), vPos, GL_STATIC_DRAW);
//	glBindBuffer(GL_ARRAY_BUFFER, 0);

	canRender = true;
	*/return true;
}

void OGLAbstr::renderPrimitive()
{
	/*if(canRender)
	{
		glUseProgram(shaderProgram);
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
			
		glDrawArrays(GL_TRIANGLES, 0, 3);

		glDisableVertexAttribArray(0);
	}*/

	if(test_draw)
	{
		glDrawArrays(GL_TRIANGLES, 0, 3);
	}
}

bool OGLAbstr::testDraw()
{
	const float data[] =
	{
		0.0f, 0.0f, 0.0f,
		0.5f, 0.5f, 0.0f,
		0.0f, 0.5f, 0.0f
	};

	glGenVertexArrays(1,&testDrawVAO);//<----------------------- Exception
	glBindVertexArray(testDrawVAO);

	GLuint vBuf;
	glGenBuffers(1, &vBuf);
	glBindBuffer(GL_ARRAY_BUFFER, vBuf);
	glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);

	GLuint shProg;
	shProg = shader->loadBasicShaders();
	glUseProgram(shProg);

	GLuint vPosition = glGetAttribLocation( shProg, "vPosition" );
	glEnableVertexAttribArray( vPosition );
	glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);
	
	test_draw = true;
	return true;
}


The exception itself:
First-chance exception at 0x010fe839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x010fe839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x010fe839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x010fe839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x5669199e in EEngine - Editor.exe: 0xC0000005: Access violation writing location 0xcdcdce45.
Unhandled exception at 0x778615de in EEngine - Editor.exe: 0xC0000005: Access violation writing location 0xcdcdce45.


Thanks in advance!
Check where you are calling testDraw(). It looks like you're using an uninitialized pointer.
I am calling testDraw() in my application, however all the pointers associated to the function call is in the header file, as you can see.

1
2
3
4
5
void Editor::testDraw()
{
	
	subsystems.gl->testDraw();
}


is where i call it, which in turn gets called by this:
1
2
3
4
5
6
bool Game::init()
{
	if(!core->initEngine()) return false;
	editor->testDraw();
	return true;
}


core->initEngine() initializes everything needed in the program,

here is the log file:
##NORMAL## : Log has been created
##NORMAL## : Initializing subsystems...
##WND## : Registered dummy class
##NORMAL## : Done!
##GL## : Initialized GLEW
##WND## : Created Editor window
##GL## : Created DC

Last edited on
Ok there seems to be a problem when i create the variable testDrawVAO inside my class header, i moved it to the function instead and i no longer get the same exception, now i get this:
First-chance exception at 0x00cde839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00cde839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00cde839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00cde839 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00ce0d61 in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0xcdcdcdd5.
Unhandled exception at 0x773e15de in EEngine - Editor.exe: 0xC0000005: Access violation reading location 0xcdcdcdd5.


Here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GLuint testDrawVAO;

	glGenVertexArrays(1, &testDrawVAO);
	glBindVertexArray(testDrawVAO);

	GLuint vBuf;
	glGenBuffers(1, &vBuf);
	glBindBuffer(GL_ARRAY_BUFFER, vBuf);
	glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 
//----------------------The line above-----------------------

	GLuint shProg;
	shProg = shader->loadBasicShaders();
	glUseProgram(shProg);
Last edited on
subsystems.gl->testDraw();

Where is sybstems.gl set to an address? My suspicion is that the this pointer is invalid when OGLAbstr::testDraw() is called. 0xcdcdcdcd is the bit bit pattern VS uses to mark uninitialized pointers in debug mode.

[ Edit: Useful info @ http://www.nobugs.org/developer/win32/debug_crt_heap.html ]
Last edited on
Here is the full class of subsystems. aka middleLayer

Header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef _MIDDLE_LAYER_H_
#define _MIDDLE_LAYER_H_

#include "OGLAbstr.h"
#include "hMsg.h"
#include "ScriptAbstr.h"
#include "FileMgr.h"
#include "LogMgr.h"
#include "Shaders.h"

namespace EEngine
{
class MiddleLayer
{
public:
	MiddleLayer();
	~MiddleLayer();

	OGLAbstr* gl;
	hMsg* callback;
	ScriptAbstr* script;
	FileMgr* fileMgr;
	LogMgr* log;

	void startUp(HINSTANCE hInstance, LogMgr* mLog);

private:

};
}

#endif 


.cpp file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "MiddleLayer.h"
using namespace EEngine;

MiddleLayer::MiddleLayer()
{
}

MiddleLayer::~MiddleLayer()
{
}

void MiddleLayer::startUp(HINSTANCE hInstance, LogMgr* mLog)
{
	log = mLog;
	log->logMessage(log->NORMAL, "Initializing subsystems...");
	gl = new OGLAbstr(hInstance, mLog);
	callback = new hMsg();
	script = new ScriptAbstr(mLog);
	fileMgr = new FileMgr(mLog);
	log->logMessage(log->NORMAL, "Done!");
}


Now Core calls MiddleLayer::startUp() and initializes OpenGL with calls to the gl subsystem in MiddleLayer:
1
2
3
4
5
6
Core::Core(LogMgr* mLog, HINSTANCE hInst)
{
	hInstance = hInst;
	log = mLog;	
	subsystems.startUp(hInst, mLog);
	subsystems.callback->getGL(subsystems.gl);


and
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool Core::initEngine()
{
	if(!subsystems.gl->initGLEW()) return false;
#ifdef _EDITOR
	subsystems.gl->openEditorWindow(wc);
#endif
#ifdef _GAME
	if(!subsystems.gl->openGameWindow(wc, title.c_str())) return false;
#endif
	if(!subsystems.gl->initGL())  return false;

	subsystems.callback->resizeView();
	return true;
}


The main class that i use for the application creates an Engine object, which in it's constructor creates Core and Editor objects. I later use those objects to call core->initEngine() and edtior->testDraw()
callback = new hMsg(); ¿is there a good reason to use dynamic allocation?

¿Is subsystems global?
That's how i designed it, and no, subsystems is not global. I made the constructors of each class/subsystem grab a prointer to a logMgr class, do some initializing and stuff, and that was the way i saw it work. Can i do the same thing using only hMsg callback and still make it public in the class?
Use the constructor and initialization lists.

> subsystems is not global.
¿How is that an editor and a core can access it?
Does not the object call the constructer when declared like this: hMsg callback?

And the Editor and Core class creates an object to subsystems.

When you wrote a class you only say how it is composed.
1
2
3
class foo{
   bar something; //just saying that a `foo' has a `bar'
};
When you want to instantiate an object of that class, the members will be created
1
2
3
foo::foo(int value): 
   something(value, "hello_world") //constructing the `bar' member
{}


> And the Editor and Core class creates an object to subsystems.
¿So they are different objects?
Yes, the Objetcs are provate to each class. I think i know where you are going here, i had the assumption that an object simply was a reference to the class.
Because that could explain some of the other errors i have been having
But i can't control when the constructor is called if i use this: hMsg callback correct? Because i want to call the constructor at specific times in the engine.
The constructor is called when the object is constructed.
¿do you want to `reconstruct' it several times?
No, i want to control the construction. I.e i want to control when the constructor is called
I solved it by sharing the subsystems object with Editor from Core
Topic archived. No new replies allowed.