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;
}
Related
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).
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 trying to draw a triangle using glDrawArrays function and gl Vertex, Color pointers.
The result is only black empty screen.
static const GLfloat vboData[] =
{ -0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
static const GLfloat colors[]={
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vboData);
glColorPointer(3, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glfwSwapBuffers(window);
glfwPollEvents();
}
Using VBO and VAO also doesn't work.
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
static const GLfloat vboData[] =
{ -0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
GLuint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vboData), vboData, GL_STATIC_DRAW);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
So, what I needed to get my code working is adding shaders to the project.
Here is minimal example.
This is my main.cpp
#include <iostream>
#include <fstream>
#include <algorithm>
#include "Loader.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow *window;
int main(void)
{
//Viewport,window setup using GLFW;
if(!glfwInit()){
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL);
if(!window){
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glewExperimental = true;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
//Loading and compiling shaders;
GLuint shaderID = LoadShader("vertexs.shader", "fragments.shader");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
static const GLfloat vboData[] =
{ -1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
};
GLuint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vboData), vboData, GL_STATIC_DRAW);
glUseProgram(shaderID); //Attaching shaders
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &vbo);
glDeleteProgram(shaderID);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}
Loader.hpp
#ifndef Loader_hpp
#define Loader_hpp
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLuint LoadShader(const char* vertex_file_path, const char* fragment_file_path);
#endif
Loader.cpp
#include "Loader.hpp"
GLuint LoadShader(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();
}
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::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);
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;
}
vertexs.shader (extension actually doesn't matter)
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main()
{
//We're not modifying positions of vertices
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
fragments.shader
#version 330 core
out vec3 color;
void main()
{
color = vec3(1,0,1);
}
I also found these tutorials extremely useful to make this solution, so the code above is partially taken from there.
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.