When I start my program:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
struct ShaderProgramSource
{
std::string VertexSource;
std::string FragmentSource;
};
static ShaderProgramSource parseShader(const std::string& filepath)
{
std::ifstream stream(filepath);
enum class ShaderType
{
NONE = -1, VERTEX = 0, FRAGMENT = 1
};
std::string line;
std::stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != std::string::npos)
{
if (line.find("vertex") != std::string::npos)
type = ShaderType::VERTEX;
else if (line.find("fragment") != std::string::npos)
type = ShaderType::FRAGMENT;
}
else
{
ss[(int)type] << line << '\n';
}
}
return { ss[0].str(), ss[1].str() };
}
typedef unsigned int uint;
static uint compileShader(const std::string& source, uint type)
{
uint id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
//char* message = (char*)alloca(length * sizeof(char));
char* message = new char[length];
glGetShaderInfoLog(id, length, &length, message);
std::cout << "Failed to compile the " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment")
<< " shader !" << std::endl;
std::cout << message << std::endl;
delete[](message);
glDeleteShader(id);
return EXIT_FAILURE;
}
return id;
}
static uint CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
{
uint program = glCreateProgram();
uint vs = compileShader(vertexShader, GL_VERTEX_SHADER);
uint fs = compileShader(fragmentShader, GL_FRAGMENT_SHADER);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello Triangle", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
auto state = glewInit();
if (state != GLEW_OK)
{
std::cerr << "Error initializing GLEW" << std::endl;
return EXIT_FAILURE;
}
std::cout << glGetString(GL_VERSION) << std::endl;
float positions[6] = {
-0.5f, -0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
ShaderProgramSource source = parseShader("res/shaders/basic.shader");
std::cout << "VERTEX" << std::endl;
std::cout << source.VertexSource << std::endl;
std::cout << "FRAGMENT" << std::endl;
std::cout << source.FragmentSource << std::endl;
//uint shader = CreateShader(source.VertexSource, source.VertexSource);
//glUseProgram(shader);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
//glDeleteProgram(shader);
glfwTerminate();
return 0;
}
...everything work well but just a few seconds later, the app crash. it return the exit code -1073741819 and by converting it into hex, I find that's the error code C0000005: buffer overrun. Then I decided to debug that and the debugger said that:
"Exception thrown at 0x00007FFD28144921 (igxelpicd64.dll) in App.exe: 0xC0000005: Access violation writing location 0x0000025170620000."
It seems that you are not using your shader as you have glCompileShader()
and glUseProgram(shader)
commented out and OpenGL does not have default one. Try to uncomment those 2 lines and leave glCompileShader
where it is (before the main loop) but move the glUseShader(shader)
to the rendering loop just before you call 'glDrawArrays()`
Also I don't see that you are creating VertexArrayObject which needs to be created and bound using glBindVertexArray(GLint: VAO)
, instead you use regular buffer as VertexArrayBuffer
so your code for creating VertexArrayBuffer
should look like this
unsigned int VAO, VBO;
//this is missing in your code
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), &positions GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glBindVertexArrays(0)
Now when you have Vertex arrays you can render you triangle using the following
//while loop
glUseProgram(shaderProgram)
glBindVertexArrays(VAO)
glDrawArray(GL_TRIANGLES, 0, 3);
//----------
This shoudl solve your issue assuming your shades are correctly compiled and you pass everything to the VertexArrayBuffer
.