When I tried to run this I got a "Segmentation fault (core dumped) error and nothing ran:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include </home/rohan/Documents/opengl/common/loadShader.hpp>
using namespace glm;
int main() {
glewExperimental = true;
if ( !glfwInit() )
{
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLFWwindow* window;
window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
if (window == NULL)
{
fprintf(stderr, "Failed to open GLFW window.If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental=true;
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.glsl", "SimpleFragmentShader.glsl" );
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
// unknown, size, type, normalized?, stride, array buffer offset
0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// Use our shader
glUseProgram(programID);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
}
vertex shader
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main()
{
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
fragment shader:
#version 330 core
out vec3 color;
void main()
{
color = vec3(1,0,0);
}
shader-loader:
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open()){
std::stringstream sstr;
sstr << VertexShaderStream.rdbuf();
VertexShaderCode = sstr.str();
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
getchar();
return 0;
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::stringstream sstr;
sstr << FragmentShaderStream.rdbuf();
FragmentShaderCode = sstr.str();
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
The code is supposed to make a red triangle appear.
To call an OpenGL instruction, you need a valid and current OpenGL context and the OpenGL loader (in your case glew) must be in initialized. Therefore you cannot do the vertex specification before glewInit. Move all OpenGL commands after that:
// [...]
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// The earliest point for calling an OpenGL (gl*) instruction is here
// [...]
Note, glewExperimental = True is not further necessary (see Initializing GLEW).
Related
I am trying to draw a triangle with GLFW and Glad. But the screen won't display anything (I can only clear the screen).
I am able to Open a Window, and clear the screen to a dark blue color (or any other color)
But I cannot draw a triangle on the Screen, and I do not know why.
I thought maybe my GPU didn't have a default shader.
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string.h>
#include <vector>
void Log(const char* str) {
std::cout << str << std::endl;
}
void error_callback(int error, const char* description)
{
std::cout << "Error Code ["<< stderr << "] Error: \n" << description << std::endl;
}
class Shader {
public:
Shader(const std::string& vertexSrc, const std::string& fragSrc) {
// Create an empty vertex shader handle
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const GLchar* source = vertexSrc.c_str();
glShaderSource(vertexShader, 1, &source, 0);
glCompileShader(vertexShader);
GLint isCompiled = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> infoLog(maxLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);
glDeleteShader(vertexShader);
return;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
source = fragSrc.c_str();
glShaderSource(fragmentShader, 1, &source, 0);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> infoLog(maxLength);
glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
return;
}
m_RendererID = glCreateProgram();
glAttachShader(m_RendererID, vertexShader);
glAttachShader(m_RendererID, fragmentShader);
glLinkProgram(m_RendererID);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(m_RendererID, GL_LINK_STATUS, (int*)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(m_RendererID, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(m_RendererID, maxLength, &maxLength, &infoLog[0]);
glDeleteProgram(m_RendererID);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return;
}
Log("Shader compiled Successfully at:");
std::cout << m_RendererID << std::endl;
glDetachShader(m_RendererID, vertexShader);
glDetachShader(m_RendererID, fragmentShader);
}
~Shader() {
glDeleteProgram(m_RendererID);
}
void Bind() const {
glUseProgram(m_RendererID);
}
void Unbind() const {
glUseProgram(0);
}
private:
uint32_t m_RendererID = 0;
};
int main() {
Log("Initializing...");
glfwSetErrorCallback(error_callback);
if (!glfwInit())
{
// Initialization failed
Log("Initialization Failed");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
GLFWwindow* window = glfwCreateWindow(1080, 720, "GLFW_GLAD TEST", NULL, NULL);
if (!window)
{
glfwTerminate();
Log("Window or OpenGL Context Failed");
}
glfwMakeContextCurrent(window);
gladLoadGL();
glfwSwapInterval(1);
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
//APP CODE
unsigned int m_VertexArray;
unsigned int m_VertexBuffer;
unsigned int m_IndexBuffer;
float vertices[9] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// Vertex Array
glGenVertexArrays(1, &m_VertexArray);
glBindVertexArray(m_VertexArray);
// Vertex Buffer
glGenBuffers(1, &m_VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glDisableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
// Index Buffer
glGenBuffers(1, &m_IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
unsigned int indices[3] = {
0, 1, 2,
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
std::string vertexSrc = R"(
#version 330
layout(location = 0) in vec3 a_Pos;
void main()
{
gl_Position = vec4(a_Pos, 1);
}
)";
std::string fragmentSrc = R"(
#version 330
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(0.8f, 0.5f, 0.2f, 1.0f);
}
)";
Shader* shader = new Shader(vertexSrc, fragmentSrc);
shader->Bind();
while (!glfwWindowShouldClose(window))
{
glViewport(0, 0, width, height);
glClearColor(0.1f, .1f, .14f, 1);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(m_VertexArray);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
This here definitively is wrong.
glDisableVertexAttribArray(0);
You meant glEnableVertexAttribArray here, so that the attibute pointer you are setting up is actually used. For disabled attribute arrays, all shader invocations will get a constant value.
Also your shaders use #version 330 and actually require GLSL 330 syntax, however:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
you request only a GL 2.0 context and GL 2.0 only mandates support for GLSL 1.10. If this is going to work will be completely up to your driver, you might get some >= 3.3 compatibility profile, but you can't count on it.
You should create a 3.3 context explicitly, and also explicitly request a core profile.
I'm added in my simple OpenGL project very simple GLSL shaders, and it not working.
#include <python3.6m/Python.h>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <vector>
#include <fstream>
#include <sstream>
using namespace glm;
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){
// Создаем шейдеры
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Загружаем код Вершинного Шейдера из файла
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if (VertexShaderStream.is_open()) {
std::stringstream sstr;
sstr << VertexShaderStream.rdbuf();
VertexShaderCode = sstr.str();
VertexShaderStream.close();
}
// Загружаем код Фрагментного шейдера из файла
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if (FragmentShaderStream.is_open()){
std::stringstream sstr;
sstr << FragmentShaderStream.rdbuf();
FragmentShaderCode = sstr.str();
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Компилируем Вершинный шейдер
printf("Компиляция шейдера: %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Выполняем проверку Вершинного шейдера
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
}
// Компилируем Фрагментный шейдер
printf("Компиляция шейдера: %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Проверяем Фрагментный шейдер
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
}
// Создаем шейдерную программу и привязываем шейдеры к ней
fprintf(stdout, "Создаем шейдерную программу и привязываем шейдеры к ней\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Проверяем шейдерную программу
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
int main(int argc, char *argv[]) {
// Инициализируем GLFW
if (!glfwInit()) {
fprintf( stderr, "Ошибка при инициализации GLFW\n" );
return -1;
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_SAMPLES, 4); // Включаем сглаживание
glEnable(GL_MULTISAMPLE);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Мы хотим использовать OpenGL 3.3
// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Мы не хотим старый OpenGL
// Открыть окно и создать в нем контекст OpenGL
GLFWwindow* window; // (В сопроводительном исходном коде эта переменная является глобальной)
window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
if (window == NULL) {
fprintf( stderr, "Невозможно открыть окно GLFW. Если у вас Intel GPU, то он не поддерживает версию 3.3. Попробуйте версию уроков для OpenGL 2.1.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Инициализируем GLEW
glewExperimental=true; // Флаг необходим в Core-режиме OpenGL
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Невозможно инициализировать GLEW\n");
return -1;
}
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Массив 3 векторов, которые являются вершинами треугольника
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.5f, 1.0f, 0.0f,
};
// Это будет идентификатором нашего буфера вершин
GLuint vertexbuffer;
// Создадим 1 буфер и поместим в переменную vertexbuffer его идентификатор
glGenBuffers(1, &vertexbuffer);
// Сделаем только что созданный буфер текущим
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Передадим информацию о вершинах в OpenGL
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
// Включим режим отслеживания нажатия клавиш, для проверки ниже
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Создать и откомпилировать нашу шейдерную программу
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
do {
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Устанавливаем наш шейдер текущим
// glUseProgram(programID);
// Рисуем треугольник...
// Указываем, что первым буфером атрибутов будут вершины
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // Атрибут 0. Подробнее об этом будет рассказано в части, посвященной шейдерам.
3, // Размер
GL_FLOAT, // Тип
GL_FALSE, // Указывает, что значения не нормализованы
0, // Шаг
(void*) nullptr // Смещение массива в буфере
);
// Вывести треугольник!
glDrawArrays(GL_TRIANGLES, 0, 3); // Начиная с вершины 0, всего 3 вершины -> один треугольник
glDisableVertexAttribArray(0);
// Сбрасываем буферы
glfwSwapBuffers(window);
glfwPollEvents();
} // Проверяем нажатие клавиши Escape или закрытие окна
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
}
I see black window (if I write
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
else i see errors:
Compiling shader: SimpleVertexShader.vertexshader
0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, and 3.00 ES
*Compiling shader: SimpleFragmentShader.fragmentshader *
Creating shader programm and linking...
error: linking with uncompiled/unspecialized shader
)
Vertex shader:
#version 300 es
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
Fragment shader:
#version 300 es
precision mediump float;
layout(location = 0) out vec3 color;
void main() {
color = vec3(1,0,0);
}
GLuint programID = ...
You mihght actually sucessfully create and link your program object, but you never activate it. You have to add glUseProgram(programID) somewhere before your draw call.
I'm trying to learn SDL2, modern OpenGL, etc...
Below is the code I've adapted from tutorial for use with SDL2.
I have managed to get everything else to work, but for some reason the shader part crashes the program...
...I'm unable to get any console output to work (any tips on that?).
I'm using Eclipse.
Also if you find any other fixable spots on the code, please feel free to
point them out.
Program compiles without any errors or warnings.
#include <windows.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <SDL2/SDL.h>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
const int WINDOW_W = 1280;
const int WINDOW_H = 720;
const int WINDOW_X = 200;
const int WINDOW_Y = 200;
// FUNCTIONS
/* Shader loader:
* Handles loading GLSL vertex and fragment shaders
*/
GLuint ShaderLoad(const char * vertex_file_path, const char * fragment_file_path)
{
// Vertex shader ID
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
//Read the vertex shader files
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if (VertexShaderStream.is_open())
{
std::string Line = "";
while (getline(VertexShaderStream, Line))
{
VertexShaderCode += "\n" + Line;
}
VertexShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile vertex shader
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check vertex shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
// Fragment shader ID
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Link the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage(InfoLogLength);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
//GLuint programID = ShaderLoad("vshader.glsl", "fshader.glsl");
// Main
int main(int argc, char **argv)
{
//Variables
SDL_Window * SDLWindow = NULL;
SDL_GLContext GLContext;
SDL_Event event;
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
SDL_Init(SDL_INIT_EVERYTHING);
SDLWindow = SDL_CreateWindow("ELSA",
WINDOW_X, WINDOW_Y,
WINDOW_W, WINDOW_H,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
GLContext = SDL_GL_CreateContext(SDLWindow);
SDL_GL_MakeCurrent(SDLWindow, GLContext);
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetSwapInterval(1);
// OPENGL INIT
glewExperimental = GL_TRUE;
glewInit();
GLuint vertexbuffer;
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER,
sizeof(g_vertex_buffer_data),
g_vertex_buffer_data, GL_STATIC_DRAW);
while(true)
{
while (SDL_PollEvent(&event)) // Get all events per frame
{
if (event.type == SDL_QUIT)
{
return false;
}
if (event.type == SDL_WINDOWEVENT_RESIZED)
{
glViewport(0, 0,
SDL_GetWindowSurface(SDLWindow)->w,
SDL_GetWindowSurface(SDLWindow)->h);
}
}
//OpenGL code
glClearColor(0.15, 0.15, 0.30, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use shader
//glUseProgram(programID);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(SDLWindow);
glDisableVertexAttribArray(0);
}
SDL_GL_DeleteContext(GLContext);
SDL_DestroyWindow(SDLWindow);
SDL_Quit();
return 0;
}
The Problem:
I tried to write a class to draw me clickable rectangles the problem is that since I started using the new OpenGL version (4.0) in the program it doesn't render and gives me the runtime error error while reading on position 0x00000000.
I'll include the code of the class as well as the main loop in the bottom.
GUI::GUI(std::string name, int top, int left,int heigh, int width, bool isvisible, void(_cdecl * func)())
{
Name=name;
Top=top;
Left=left;
Heigh=heigh;
Width=width;
BackColor = struct_RGB();
glClearColor(0.0f, 0.0f, 0.4f, 1.0f);
BackDrawFunc=func;
Visibility=isvisible;
GuiObj = std::vector<GUIOBJ *>();
vertices = std::vector<float>();
vertices.clear();
for(unsigned int i=0; i<GuiObj.size(); i++)
{
GuiObj[i]->addVertices();
};
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &VBO);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
program = LoadShaders("res/VertexShader.glsl", "res/FragmentShader.glsl");
}
void GUI::Draw()
{
glClear(GL_COLOR_BUFFER_BIT);
// Use our shader
glUseProgram(program);
// 1rst attribute buffer : vertices
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
vertices.size(), // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, vertices.size()); // 3 indices starting at 0 -> 1 triangle
printf("drawing\n");
glDisableVertexAttribArray(0);
}
void main()
{
init();
//Main Loop
while(!glfwWindowShouldClose(Window))
{
if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(Window, GL_TRUE);
Test->Draw();
glfwSwapBuffers(Window);
glfwPollEvents();
}
//Termination
glfwTerminate();
}
EDIT:
I copied all the code in the same file the error is solved but it still doesn't render
#include "extincludes.h"
#include <vector>
#include <fstream>
#include <sstream>
GLFWwindow* Window;
typedef unsigned int GLuint;
GLuint VertexArrayID;
GLuint VBO;
GLuint program;
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream = std::ifstream(vertex_file_path, std::ios::in);
if (!VertexShaderStream.is_open()) VertexShaderStream.open(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open())
{
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
} else
printf("Couldn't open VertexShader");
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
} else
printf("Couldn't open FragmentShader");
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Link the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage( glm::max(InfoLogLength, int(1)) );
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
void main()
{
//GLFW
printf("started init of GLFW \n");
if (!glfwInit())
printf("startup of GLFW errored \n");
printf("started GLFW \n");
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //excluding old openGL functionality
Window = glfwCreateWindow(640, 768, "Simple example", NULL, NULL);
printf("attempt to create window \n");
if (!Window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(Window);
printf("Init of GLFW done \n");
//GLEW
printf("start init of GLEW \n");
glewExperimental = true; // Needed for core profile
printf("using experimental version of GLEW\n");
if (glewInit() != GLEW_OK) {
printf("Failed to initialize GLEW\n");
}
printf("done with GLEW\n");
if (glfwGetCurrentContext()!=Window)
printf("context error");
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
program = LoadShaders("res/VertexShader.glsl", "res/FragmentShader.glsl");
std::vector<float> vertices = std::vector<float>();
vertices.clear();
//triangle 1
vertices.push_back(1);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(3);
//triangle 2
vertices.push_back(1);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(3);
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &VBO);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
//Main Loop
while(!glfwWindowShouldClose(Window))
{
if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(Window, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT);
// Use our shader
glUseProgram(program);
// 1rst attribute buffer : vertices
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VertexArrayID);
// Draw the triangle !
printf("everything setup we can draw \n");
glDrawArrays(GL_TRIANGLES, 0, vertices.size()); // 3 indices starting at 0 -> 1 triangle
printf("drawing\n");
glfwSwapBuffers(Window);
glfwPollEvents();
}
//Termination
glDisableVertexAttribArray(0);
glfwDestroyWindow(Window);
glfwTerminate();
}
I figured the error of the crash out it was just that you need three dimensions instead of one. This led to the error that the draw function was reading out of range....
I have just started to learn OpenGL, and am following this tutorial. I am having difficulty compiling the GLSL files that the tutorial uses.
Originally when I tried compiling them the compiler said that mesa did not support GLSL version 330 so I changed #version 330 core to #version 130. Now when I run it it gives me the following error:
3.0 Mesa 10.0.20Compiling shader : SimpleVertexShader.vertexshader
0:3(1): error: syntax error, unexpected NEW_IDENTIFIER
Compiling shader : SimpleFragmentShader.fragmentshader
Linking program
error: linking with uncompiled shader
I have searched on google and cannot find anyone with this problem. Anyway, here are all of the files in question:
SimpleVertexShader.vertexshader:
#version 130
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
SimpleFragmentShader.fragmentshader:
#version 130
out vec3 color;
void main() {
color = vec3(1,0,0);
}
loadShader.cpp:
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open())
{
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Link the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage( max(InfoLogLength, int(1)) );
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
main.cpp:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
//#define GLFW_DLL // maybe some glu problems - look up
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path);
int main()
{
GLFWwindow * window;
if (!glfwInit()) {
std::cout << "Failed to initiate GLFW\n";
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4); //4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //version 3
//open a window and create context
window=glfwCreateWindow(1024,768,"Lerning", glfwGetPrimaryMonitor(), NULL);
if (!window) {
std::cout << "Failed to open window\n";
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
std::cout << glGetString(GL_VERSION);
// initialize GLEW
glewExperimental=GL_TRUE; //needed
GLenum err = glewInit();
std::cout << err;
if (err != GLEW_OK) {
std::cout << "Failed to initialize\n" << glewGetErrorString(err);
return -1;
}
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data),
g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint programID = LoadShaders("SimpleVertexShader.vertexshader",
"SimpleFragmentShader.fragmentshader");
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
layout(location = 0) is not valid in GLSL 1.30. Layout qualifiers were introduced in GLSL 1.40. You will need to manually bind that vertex attribute location in your C++ code prior to linking your shaders.
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Create the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
// Setup Vertex Attributes [NEW]
glBindAttribLocation (ProgramID, 0, "vertexPosition_modelspace");
// Link the program
glLinkProgram(ProgramID);
Chances are this attribute is going to be automatically assigned 0 by the GLSL implementation anyway once you remove the layout (location = 0), but you should go ahead and bind the location to do things the right way.