I'm having a problem with glCreateShaders. It always returns 0. I'm using Glew with SDL and whenever I run the program, it says:
0(1) : error C0000: syntax error, unexpected '}' at token "}"
Shader Shaders/colorShading.vert failed to compile!
main.cpp:
#include <iostream>
#include "MainGame.h"
int main(int argc, char** argv)
{
MainGame maingame;
maingame.run();
return 0;
}
MainGame.h:
//Core -> initializing glew, sdl etc...
//Just ignore the sprite class
#pragma once
#include <SDL/SDL.h>
#include <GL/glew.h>
#include <iostream>
#include <string>
#include "Errors.h"
#include "GLSLProgram.h"
enum class GameState {PLAY, EXIT};
#include "Sprite.h"
class MainGame
{
public:
MainGame(void);
~MainGame(void);
void run();
private:
void initSystems();
void initShaders();
void gameLoop();
void processInput();
void drawGame();
SDL_Window* _window;
int _screenWidth;
int _screenHeight;
GameState _gameState;
Sprite _sprite;
GLSLProgram _colorProgram;
};
MainGame.cpp:
#include "MainGame.h"
MainGame::MainGame(void)
{
_window = nullptr;
_screenWidth = 1024;
_screenHeight = 700;
_gameState = GameState::PLAY;
}
MainGame::~MainGame(void)
{
}
void MainGame::run()
{
initSystems();
_sprite.init(-1.0f, -1.0f, 1.0f, 1.0f);
gameLoop();
}
void MainGame::initSystems()
{
//Initialize SDL
SDL_Init(SDL_INIT_EVERYTHING);
_window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, _screenWidth, _screenHeight, SDL_WINDOW_OPENGL);
if (_window == nullptr)
{
fatalError("SDL Window could not be created!");
}
SDL_GLContext glContext = SDL_GL_CreateContext(_window);
if (glContext == nullptr)
fatalError("SDL_GL context could not be created!");
GLenum error = glewInit();
if (error != GLEW_OK)
fatalError("Could not initialize glew!");
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
initShaders();
}
void MainGame::initShaders()
{
_colorProgram.compileShaders("Shaders/colorShading.vert", "Shaders/colorShading.frag");
_colorProgram.addAttribute("vertexPosition");
_colorProgram.linkShaders();
}
void MainGame::gameLoop()
{
while (_gameState != GameState::EXIT)
{
processInput();
drawGame();
}
}
void MainGame::processInput()
{
SDL_Event evnt;
while (SDL_PollEvent(&evnt))
{
switch (evnt.type)
{
case SDL_QUIT:
_gameState = GameState::EXIT;
break;
case SDL_MOUSEMOTION:
std::cout << "New Coords: " << evnt.motion.x << " " << evnt.motion.y << std::endl;
break;
}
}
}
void MainGame::drawGame()
{
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_colorProgram.use();
_sprite.draw();
_colorProgram.unUse();
SDL_GL_SwapWindow(_window);
}
GLSLProgram.h:
//Used for
#pragma once
#include <string>
#include <GL/glew.h>
//#include <SDL/SDL.h>
#include "Errors.h"
class GLSLProgram
{
public:
GLSLProgram();
~GLSLProgram();
void compileShaders(const std::string& vertextShaderFilePath, const std::string& fragmentShaderFilePath);
void linkShaders();
void addAttribute(const std::string&);
void use();
void unUse();
private:
int _numAttributes;
void _compileShader(const std::string&, GLuint);
GLuint _programID;
GLuint _vertexShaderID;
GLuint _fragmentShaderID;
};
GLSLProgram.cpp:
//Used for compiling shaders
#include "GLSLProgram.h"
#include <fstream>
#include <vector>
GLSLProgram::GLSLProgram() : _numAttributes(0), _programID(0), _vertexShaderID(0), _fragmentShaderID(0)
{
}
GLSLProgram::~GLSLProgram()
{
}
void GLSLProgram::compileShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath)
{
_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if (_vertexShaderID == 0)
{
fatalError("Vertex shader failed to be created!");
SDL_Quit();
}
_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (_fragmentShaderID == 0)
{
fatalError("Fragment shader failed to be created!");
SDL_Quit();
}
_compileShader(vertexShaderFilePath, _vertexShaderID);
_compileShader(fragmentShaderFilePath, _fragmentShaderID);
}
void GLSLProgram::addAttribute(const std::string& attributeName)
{
glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str());
}
void GLSLProgram::use()
{
glUseProgram(_programID);
for (int x = 0; x < _numAttributes; x++)
{
glEnableVertexAttribArray(x);
}
}
void GLSLProgram::unUse()
{
glUseProgram(0);
for (int x = 0; x < _numAttributes; x++)
{
glDisableVertexAttribArray(x);
}
}
void GLSLProgram::linkShaders()
{
//Vertex and fragment shaders are successfully compiled.
//Now time to link them together into a program.
//Get a program object.
_programID = glCreateProgram();
//Attach our shaders to our program
glAttachShader(_programID, _vertexShaderID);
glAttachShader(_programID, _fragmentShaderID);
//Link our program
glLinkProgram(_programID);
//Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(_programID, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
std::vector<char> infoLog(maxLength);
glGetProgramInfoLog(_programID, maxLength, &maxLength, &infoLog[0]);
//We don't need the program anymore.
glDeleteProgram(_programID);
//Don't leak shaders either.
glDeleteShader(_vertexShaderID);
glDeleteShader(_fragmentShaderID);
printf("%s\n", &(infoLog[0]));
fatalError("Shaders failed to link!");
}
//Always detach shaders after a successful link.
glDetachShader(_programID, _vertexShaderID);
glDetachShader(_programID, _fragmentShaderID);
glDeleteProgram(_programID);
glDeleteShader(_vertexShaderID);
glDeleteShader(_fragmentShaderID);
}
void GLSLProgram::_compileShader(const std::string &filePath, GLuint id)
{
std::ifstream vertexFile(filePath);
if (vertexFile.fail())
{
perror(filePath.c_str());
fatalError("Failed to open " + filePath);
}
std::string fileContents;
std::string line;
while (std::getline(vertexFile, line));
{
fileContents += line + "\n";
}
vertexFile.close();
const char *contentsPtr = fileContents.c_str();
glShaderSource(id, 1, &contentsPtr, nullptr);
glCompileShader(id);
GLint isCompiled = 0;
glGetShaderiv(id, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
std::vector<char> errorLog(maxLength);
glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
//Provide the infolog in whatever manor you deem best.
//Exit with failure.
glDeleteShader(id); //Don't leak the shader.
printf("%s\n", &(errorLog[0]));
fatalError("Shader" + filePath + "failed to compile!");
}
}
vertex shader:
#version 130
//The vertex shader operates on each vertex
//input data from the VBO. Each vertex is 2 floats
in vec2 vertexPosition;
void main()
{
//Set the x,y position on the screen
gl_Position.xy = vertexPosition;
//the z position is zero since we are in 2D
gl_Position.z = 0.0;
//Indicate that the coordinates are normalized
gl_Position.w = 1.0;
}
and fragment shader:
#version 130
//The fragment shader operates on each pixel in a given polygon
//This is the 3 component float vector that gets outputted to the screen
//for each pixel.
out vec3 color;
void main() {
//Just hardcode the color to red
color = vec3(1.0, 0.0, 1.0);
}
I don't have any idea why it is happening. :(
PS: I'm beginner with glew so please don't answer with some advance stuff:D
Edit 1:
02/11/2014 (11/02/2014 for Americans)
I downloaded the source code from the tutorial I was using and it is working. So there's something with my code. I will edit the post when I find the problem.
Remove semicolon in file GLSLProgram.cpp at line:
while (std::getline(vertexFile, line));
You go through the file and then just add to the empty string fileContents the last line of your shader code, that is '}'.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I try to launch next code, but it gives error with code 1285 on line glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr) (Application.cpp).
If I replace preceding line of code with glDrawArrays(GL_TRIANGLES, 0, 3) it draws a triangle, so shader, vertex buffer, vertex array binding works fine. The problem should be in IndexBuffer, but I can't find it.
Renderer.h
#pragma once
#include <GL/glew.h>
#define ASSERT(x) if (!(x)) __debugbreak();
#define GLCall(x) GLClearError();\
x;\
ASSERT(GLLogCall(#x, __FILE__, __LINE__))
void GLClearError();
bool GLLogCall(const char* function, const char* file, int line);
Renderer.cpp
#include "Renderer.h"
#include <iostream>
void GLClearError()
{
while (glGetError() != GL_NO_ERROR);
}
bool GLLogCall(const char* function, const char* file, int line)
{
while (GLenum error = glGetError())
{
std::cout << "[OpenGL Error] (" << error << "): " << function <<
" " << file << ": " << line << std::endl;
return false;
}
return true;
}
VertexBuffer.h
#pragma once
class VertexBuffer
{
private:
unsigned int m_RendererID;
public:
VertexBuffer(const void* data, unsigned int size);
~VertexBuffer();
void Bind() const;
void Unbind() const;
};
VertexBuffer.cpp
#include "VertexBuffer.h"
#include "Renderer.h"
VertexBuffer::VertexBuffer(const void* data, unsigned int size)
{
GLCall(glGenBuffers(1, &m_RendererID));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID));
GLCall(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
}
VertexBuffer::~VertexBuffer()
{
GLCall(glDeleteBuffers(1, &m_RendererID));
}
void VertexBuffer::Bind() const
{
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID));
}
void VertexBuffer::Unbind() const
{
GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
IndexBuffer.h
#pragma once
class IndexBuffer
{
private:
unsigned int m_RendererID;
unsigned int m_Count;
public:
IndexBuffer(const unsigned int* data, unsigned int count);
~IndexBuffer();
void Bind() const;
void Unbind() const;
inline unsigned int GetCount() const { return m_Count; }
};
IndexBuffer.cpp
#include "IndexBuffer.h"
#include "Renderer.h"
IndexBuffer::IndexBuffer(const unsigned int* data, unsigned int count)
: m_Count(count)
{
ASSERT(sizeof(unsigned int) == sizeof(GLuint));
GLCall(glGenBuffers(1, &m_RendererID));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID));
GLCall(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW);
}
IndexBuffer::~IndexBuffer()
{
GLCall(glDeleteBuffers(1, &m_RendererID));
}
void IndexBuffer::Bind() const
{
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID));
}
void IndexBuffer::Unbind() const
{
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
Application.cpp
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Renderer.h"
#include "VertexBuffer.h"
#include "IndexBuffer.h"
struct ShaderProgramSource
{
std::string VertexSource;
std::string FragmentSource;
};
static ShaderProgramSource ParseShader(const std::string& filepath)
{
std::fstream 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() };
}
static unsigned int CompileShader(unsigned int type, const std::string& source)
{
GLCall(unsigned int id = glCreateShader(type));
const char* src = source.c_str();
GLCall(glShaderSource(id, 1, &src, nullptr));
GLCall(glCompileShader(id));
int result;
GLCall(glGetShaderiv(id, GL_COMPILE_STATUS, &result));
if (result == GL_FALSE)
{
int length;
GLCall(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length));
char* message = (char*)alloca(length * sizeof(char));
GLCall(glGetShaderInfoLog(id, length, &length, message));
std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader!" << std::endl;
std::cout << message << std::endl;
GLCall(glDeleteShader(id));
return 0;
}
return id;
}
static unsigned int CreateProgram(const std::string& vertexShader, const std::string& fragmentShader)
{
GLCall(unsigned int program = glCreateProgram());
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
GLCall(glAttachShader(program, vs));
GLCall(glAttachShader(program, fs));
GLCall(glLinkProgram(program));
GLCall(glValidateProgram(program));
GLCall(glDeleteShader(vs));
GLCall(glDeleteShader(fs));
return program;
}
int main()
{
GLFWwindow* window;
if (!glfwInit())
{
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(640, 400, "Hello world", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
if (glewInit() != GLEW_OK)
{
std::cout << "Error while GLEW init!" << std::endl;
}
std::cout << glGetString(GL_VERSION) << std::endl;
{
float positions[] = {
-0.5f, -0.5f, // 0
0.5f, -0.5f, // 1
0.5f, 0.5f, // 2
-0.5f, 0.5f // 3
};
unsigned int indices[] = {
0, 1, 2,
2, 3, 0
};
unsigned int vao;
GLCall(glGenVertexArrays(1, &vao));
GLCall(glBindVertexArray(vao));
VertexBuffer vb(positions, 4 * 2 * sizeof(float));
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
IndexBuffer ib(indices, 6);
ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");
unsigned int program = CreateProgram(source.VertexSource, source.FragmentSource);
GLCall(glUseProgram(program));
GLCall(int location = glGetUniformLocation(program, "u_Color"));
ASSERT(location != -1);
GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f));
GLCall(glBindVertexArray(0));
GLCall(glUseProgram(0));
vb.Unbind();
ib.Unbind();
float r = 0;
float increment = 0.05f;
while (!glfwWindowShouldClose(window))
{
GLCall(glClear(GL_COLOR_BUFFER_BIT));
glClearColor(1, 0, 0, 1);
GLCall(glUseProgram(program));
GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
GLCall(glBindVertexArray(vao));
ib.Bind();
// glDrawArrays(GL_TRIANGLES, 0, 3);
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr));
if (r > 1.0f)
{
increment = -0.05f;
}
else if (r < 0.0f)
{
increment = 0.05f;
}
r += increment;
glfwSwapBuffers(window);
glfwPollEvents();
}
GLCall(glDeleteProgram(program));
}
glfwTerminate();
return 0;
}
Basic.shader
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main()
{
color = u_Color;
}
This does not look right. Missing a glBufferData?
GLCall(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW);
I'm trying to write shaders using GLSL but whenever I try to compile this code an exception gets thrown in visual studio and I have no idea how to handle it or what exactly is causing the problem here so I'd appreciate some help. The exception says:
First-chance exception at 0x00220645 in Open GL.exe: 0xC0000005: Access violation reading location 0x00D54000.
I don't really know how to go about that. When I check my output I see that everything happens as it's supposed to with the exception of two lines:
'Open GL.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ig7icd32.dll'. Cannot find or open the PDB file.
'Open GL.exe' (Win32): Loaded 'C:\Windows\SysWOW64\igdusc32.dll'. Cannot find or open the PDB file.
Here's my code:
Main.cpp
#include <iostream>
#include "Display.h"
#include "Shader.h"
int main(int argc, char *argv[])
{
Display display(800, 600, "test");
Shader shader("basicshader");
while (!display.isClosed())
{
display.Clear(1.0f, 0.0f, 0.0f, 1.0f);
shader.Bind();
display.Update();
}
return 0;
}
Display.cpp
#pragma once
#include "Display.h"
Display::Display(int width, int height, const char *title)
{
if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
m_window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
m_context = SDL_GL_CreateContext(m_window);
GLenum status = glewInit();
if (status != GLEW_OK){
std::cerr << "this is where the problem is" << std::endl;
}
m_isClosed = false;
}
}
Display::~Display()
{
std::cerr << "destructor ran" << std::endl;
SDL_GL_DeleteContext(m_context);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
void Display::Update()
{
SDL_Event event;
SDL_GL_SwapWindow(m_window);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
m_isClosed = true;
}
}
}
void Display::Clear(float r, float g, float b, float a)
{
glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT);
}
bool Display::isClosed(){
return m_isClosed;
}
Display.h
#pragma once
#include <SDL.h>
#include <glew.h>
#include <iostream>
class Display
{
public:
void Update();
void Clear(float r, float g, float b, float a);
bool isClosed();
Display(int width, int height, const char *title);
virtual ~Display();
private:
bool m_isClosed;
SDL_Window* m_window;
SDL_GLContext m_context;
};
Shader.cpp
#pragma once
#include "Shader.h"
std::string Shader::LoadShader(const std::string& filename)
{
std::ifstream file;
std::string output;
std::string line;
file.open(filename.c_str());
if (file.is_open())
{
while (file)
{
std::getline(file, line);
output.append(line + "\n");
}
file.close();
return output;
}
}
GLuint Shader::CreateShader(const std::string& text, GLenum shadertype)
{
GLuint shader = glCreateShader(shadertype);
const GLchar* shadersourcestrings[1];
GLint shadersourcelengths[1];
shadersourcestrings[0] = text.c_str();
shadersourcelengths[0] = text.length();
glShaderSource(shader, 1, shadersourcestrings, shadersourcelengths);
glCompileShader(shader);
return shader;
}
void Shader::Bind()
{
glUseProgram(m_program);
}
Shader::Shader(const std::string& filename)
{
m_program = glCreateProgram();
m_shaders[0] = CreateShader(LoadShader(filename + ".shade_v"), GL_VERTEX_SHADER);
m_shaders[1] = CreateShader(LoadShader(filename + ".shade_f"), GL_FRAGMENT_SHADER);
for (unsigned int i = 0; NUMOFSHADERS; i++)
{
glAttachShader(m_program, m_shaders[i]); <~(breaks here)
};
glBindAttribLocation(m_program, 0, "position");
glLinkProgram(m_program);
}
Shader::~Shader()
{
for (unsigned int i = 0; NUMOFSHADERS; i++)
{
glDetachShader(m_program, m_shaders[i]);
glDeleteShader(m_shaders[i]);
}
glDeleteProgram(m_program);
}
Shader.h
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <glew.h>
class Shader
{
public:
const static unsigned int NUMOFSHADERS = 2;
GLuint m_program;
GLuint m_shaders[NUMOFSHADERS];
void Bind();
static std::string LoadShader(const std::string& filename);
static GLuint CreateShader(const std::string& text, GLenum shadertype);
Shader(const std::string& filename);
virtual ~Shader();
};
basicshader.shade_v
#version 120
void main()
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
basicshader.shade_f
#version 120
attribute vec3 position;
void main()
{
gl_position = vec4(postion, 1.0);
}
One problem is if LoadShader can't open the file it will return garbage, since it falls off the end without returning anything (which results in Undefined Behavior). This could result in the problem you're seeing.
If you compile with the warnings maxed out (/W4) you'll get a warning about that ("not all control paths return a value", or something like that).
for the last two days I've been watching following (really great and informative) tutorial series: http://www.youtube.com/playlist?list=PLEETnX-uPtBXT9T-hD0Bj31DSnwio-ywh
Last night I finished the part about meshes and now a red triangle is supposed to appear on my window, but it just doesn't. I don't know if it is a problem with my mesh or with my shader class (for both of them I don't get any errors). I use GLEW 1.10.0 for loading OpenGL, GLM 0.9.5.4 for OpenGL math stuff and SDL 2.0.3 for window stuff. Everything running on Windows 8.1 in Visual Studio 2013 Ultimate with the latest Nvidia graphics drivers.
Edit: I forgot to mention that the screen doesn't stay black, so the display.Clear method works. I hope thats any help.
Here are my shader and mesh files:
Shader.h:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <glew\glew.h>
using namespace std;
class Shader
{
public:
Shader(const string& fileName);
virtual ~Shader();
void Bind();
private:
string LoadShader(const string& fileName);
void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const string& errorMessage);
GLuint CreateShader(const string& text, GLenum shaderType);
static const unsigned int NUM_SHADERS = 2;
GLuint m_program;
GLuint m_shaders[NUM_SHADERS];
};
Shader.cpp
#include "Shader.h"
Shader::Shader(const string& fileName)
{
m_program = glCreateProgram();
m_shaders[0] = CreateShader(LoadShader(fileName + ".vert"), GL_VERTEX_SHADER);
m_shaders[1] = CreateShader(LoadShader(fileName + ".frag"), GL_FRAGMENT_SHADER);
for (unsigned int i = 0; i < NUM_SHADERS; i++)
glAttachShader(m_program, m_shaders[i]);
glLinkProgram(m_program);
CheckShaderError(m_program, GL_LINK_STATUS, true, "Error: Program linking failed");
glValidateProgram(m_program);
CheckShaderError(m_program, GL_VALIDATE_STATUS, true, "Error: Program is invalid");
}
Shader::~Shader()
{
for (unsigned int i = 0; i < NUM_SHADERS; i++)
{
glDetachShader(m_program, m_shaders[i]);
glDeleteShader(m_shaders[i]);
}
glDeleteProgram(m_program);
}
string Shader::LoadShader(const string& fileName)
{
ifstream file;
file.open(fileName.c_str());
string line;
string output;
if (file.is_open())
{
while (file.good())
{
getline(file, line);
output += (line + "\n");
}
}
else
{
cerr << "Unable to load shader: " << fileName << endl;
}
return output;
}
GLuint Shader::CreateShader(const string& text, GLenum shaderType)
{
GLuint shader = glCreateShader(shaderType);
if (shader == 0)
cerr << "Error: Shader creation failed!";
const GLchar* shaderSourceStrings[1] = { text.c_str() };
GLint shaderSourceStringLengths[1] = { text.length() };
glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLengths);
glCompileShader(shader);
CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error: Shader compilation failed");
return shader;
}
void Shader::Bind()
{
glUseProgram(m_program);
}
void Shader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const string& errorMessage)
{
GLint success = 0;
GLchar error[1024] = { 0 };
if (isProgram)
glGetProgramiv(shader, flag, &success);
else
glGetShaderiv(shader, flag, &success);
if (success == GL_FALSE)
{
if (isProgram)
glGetProgramInfoLog(shader, sizeof(error), NULL, error);
else
glGetShaderInfoLog(shader, sizeof(error), NULL, error);
cerr << errorMessage << ": '" << error << "'" << endl;
}
}
BasicShader.vert:
#version 420 core
attribute vec3 position;
void main()
{
gl_Position = vec4(position, 1.0);
}
BasicShader.frag:
#version 420 core
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Mesh.h:
#pragma once
#include <glew\glew.h>
#include "Vertex.h"
class Mesh
{
public:
Mesh(Vertex* vertecies, unsigned int numVertecies);
virtual ~Mesh();
void Draw();
private:
enum
{
POSITION_VB,
NUM_BUFFERS
};
GLuint m_vertexArrayObject;
GLuint m_vertexArrayBuffers[NUM_BUFFERS];
unsigned int m_drawCount;
};
Mesh.cpp:
#include "Mesh.h"
Mesh::Mesh(Vertex* vertecies, unsigned int numVertecies)
{
m_drawCount = numVertecies;
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(m_vertexArrayObject);
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexArrayBuffers[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertecies[0]) * numVertecies, vertecies, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}
Mesh::~Mesh()
{
glDeleteBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glDeleteVertexArrays(1, &m_vertexArrayObject);
}
void Mesh::Draw()
{
glBindVertexArray(m_vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, m_drawCount);
glBindVertexArray(0);
}
Vertex.h:
#pragma once
#include <glm\glm.hpp>
using namespace glm;
class Vertex
{
public:
Vertex(const vec3& pos);
virtual ~Vertex();
private:
vec3 m_pos;
};
Vertex.cpp:
#include "Vertex.h"
Vertex::Vertex(const vec3& pos)
{
m_pos = pos;
}
Vertex::~Vertex()
{
}
main.cpp:
#include "Display.h"
#include "Shader.h"
#include "Mesh.h"
using namespace std;
int main(int argc, char** argv)
{
Display display(800, 600, "Hello World");
Vertex vertecies[] =
{
Vertex(vec3(-0.5, -0.5, 0)),
Vertex(vec3(0, 0.5, 0)),
Vertex(vec3(0.5, -0.5, 0))
};
Mesh mesh(vertecies, sizeof(vertecies) / sizeof(vertecies[0]));
Shader shader(".\\res\\BasicShader");
while (!display.IsClosed())
{
display.Clear(0.0f, 0.15f, 0.3f, 1.0f);
shader.Bind();
mesh.Draw();
display.Update();
}
return 0;
}
I'd be very grateful for any help...
Try changing your vertex program to:
#version 420 core
layout(location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0);
}
and your fragment program to:
#version 420 core
out vec4 frag;
void main()
{
frag = vec4(1.0, 0.0, 0.0, 1.0);
}
OpenGl seems to be ignoring my shaders, not scalling, or changing the color.
Screenshot
I dont get any errors, throught the errorhandler either.
I have been at it for hours, what am i doing wrong?
im using freeglut and glew(dont know it that matters).
Im doing this with:
OpenGl 4.3
Radeon HD 6800
Windows 8.1 Enterprise
Vertex Shader:
#version 120
attribute vec3 position;
void main()
{
gl_Position = vec4(position*2.0,1.0);
}
Fragment Shader:
#version 120
void main()
{
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
Shader.cpp
#include "Shader.h"
#include <fstream>
#include "ErrorHandler.h"
namespace{
std::string VERTEX_SHADER_EXTENSION = ".vs";
std::string FRAGMENT_SHADER_EXTENSION = ".fs";
}
Shader::Shader(const std::string& fileName)
{
m_program = glCreateProgram();
m_shaders[0] = CreateShader(LoadShader(fileName + VERTEX_SHADER_EXTENSION), GL_VERTEX_SHADER);
m_shaders[1] = CreateShader(LoadShader(fileName + FRAGMENT_SHADER_EXTENSION), GL_FRAGMENT_SHADER);
for (unsigned int i = 0; i < NUM_SHADERS; i++)
{
glAttachShader(m_program, m_shaders[i]);
}
glBindAttribLocation(m_program, 0, "position");
glLinkProgram(m_program);
CheckShaderError(m_program, GL_LINK_STATUS, true, "Program linking failed: ");
glValidateProgram(m_program);
CheckShaderError(m_program, GL_VALIDATE_STATUS, true, "Program is invalid: ");
}
void Shader::Bind()
{
glUseProgram(m_program);
}
Shader::~Shader()
{
for (unsigned int i = 0; i < NUM_SHADERS; i++)
{
glDetachShader(m_program, m_shaders[i]);
glDeleteShader(m_shaders[i]);
}
glDeleteProgram(m_program);
}
GLuint Shader::CreateShader(const std::string& text, GLenum shaderType)
{
GLuint shader = glCreateShader(shaderType);
if (shader == 0)
{
ErrorHandler::LogError("Error: Shader creation failed!");
}
const GLchar* shaderSourceStrings[1];
GLint shaderSourceStringLength[1];
shaderSourceStringLength[0] = text.length();
shaderSourceStrings[0] = text.c_str();
glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLength);
glCompileShader(shader);
CheckShaderError(shader, GL_COMPILE_STATUS, false, "Shader compilation failed: ");
return shader;
}
std::string Shader::LoadShader(const std::string& fileName)
{
std::ifstream file;
file.open((fileName).c_str());
std::string output;
std::string line;
if (file.is_open())
{
while(file.good())
{
getline(file, line);
output.append(line + "\n");
}
}
else
{
ErrorHandler::LogError("Unable to load shader: " + fileName);
}
return output;
}
void Shader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
{
GLint success = 0;
GLchar error[1024] = { 0 };
if (isProgram)
glGetProgramiv(shader, flag, &success);
else
glGetShaderiv(shader, flag, &success);
if (success == GL_FALSE)
{
if (isProgram)
glGetProgramInfoLog(shader, sizeof(error), NULL, error);
else
glGetShaderInfoLog(shader, sizeof(error), NULL, error);
ErrorHandler::LogError(errorMessage + ": " + error + "'");
}
}
Game Loop:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Shaders[0].Bind();
Meshes[0].Draw();
glutSwapBuffers();
Mesh.cpp:
#include "Mesh.h"
Mesh::Mesh(Vertex* vertices, unsigned int numVertices)
{
m_drawCount = numVertices;
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(*m_vertexArrayBuffers);
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER,m_vertexArrayBuffers[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}
Mesh::~Mesh()
{
glDeleteVertexArrays(1, &m_vertexArrayObject);
}
void Mesh::Draw()
{
glBindVertexArray(m_vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, m_drawCount);
glBindVertexArray(0);
}
main and init function:
int init(int argc, char** argv)
{
//init glut
glutInit(&argc, argv);
Display display(800, 600, "OpenGL Playground");
//init glew
GLenum err = glewInit();
if (GLEW_OK != err){
ErrorHandler::LogError(std::string(reinterpret_cast<const char*>(glewGetErrorString(err))));
return 1;
}
//bind functions
glutDisplayFunc(draw);//Drawloop
return 0;
}
int main(int argc, char** argv)
{
int i = init(argc, argv);
Vertex verts[3];
verts[0] = Vertex(Vector3f(-0.5f, -0.5f, 0.0f));
verts[1] = Vertex(Vector3f(0.0f, 0.5f, 0.0f));
verts[2] = Vertex(Vector3f(0.5f, -0.5f, 0.0f));
Meshes.push_back(Mesh(verts, (sizeof(verts)/sizeof(verts[0]))));
Shaders.push_back(Shader("./res/basicShader"));
if (i == 0)
{
glutMainLoop();
}
else
{
cin.ignore(1);
return 1;
}
return 0;
}
Display.cpp:
#include "Display.h"
#include <GL\glut.h>
#include <GL\freeglut.h>
#include <iostream>
#include "ErrorHandler.h"
Display::Display(int width, int height, const std::string& title)
{
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 100);
glutCreateWindow(title.c_str());
glClearColor(0.0f, 0.2f, 0.2f, 1.0f);
}
Display::~Display()
{
}
This code in your Mesh constructor does not look right:
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(*m_vertexArrayBuffers);
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
You probably meant to pass m_vertexArrayObject as the argument to glBindVertexArray().
This program builds with no problem, and the executable starts up, but no triangle shows up. I am following a GLSL tutorial where a Shader class is made to handle GLSL files.
Shader.h
#ifndef SHADER_H_
#define SHADER_H_
#include <GL/glew.h>
#include <GL/glfw.h>
#include <string>
class Shader {
public:
Shader();
Shader(const char *vsFile, const char *fsFile);
~Shader();
void init(const char *vsFile, const char *fsFile);
void bind();
void unbind();
unsigned int id();
private:
unsigned int shader_id;
unsigned int shader_vp;
unsigned int shader_fp;
};
#endif // SHADER_H_
Shader.cpp
#include "Shader.h"
#include <cstring>
#include <iostream>
#include <ftream>
#include <cstdlib>
using namespace std;
static char* textFileRead(const char *fileName) {
char* text;
if (fileName != NULL) {
FILE *file = fopen(fileName, "rt");
if (file != NULL) {
fseek(file, 0, SEEK_END);
int count = ftell(file);
rewind(file);
if (count > 0) {
text = (char*)malloc(sizeof(char) * (count + 1));
count = fread(text, sizeof(char), count, file);
text[count] = '\0';
}
fclose(file);
}
}
return text;
}
Shader::Shader() {}
Shader::Shader(const char *vsFile, const char *fsFile)
{
init(vsFile, fsFile);
}
void Shader::init(const char *vsFile, const char *fsFile)
{
shader_vp = glCreateShader(GL_VERTEX_SHADER);
shader_fp = glCreateShader(GL_FRAGMENT_SHADER);
const char *vsText = textFileRead(vsFile);
const char *fsText = textFileRead(fsFile);
if (vsText == NULL || fsText == NULL)
{
cerr << "Either vertex shader or fragment shader file is not found" << endl;
return;
}
glShaderSource(shader_vp, 1, &vsText, 0);
glShaderSource(shader_fp, 1, &fsText, 0);
glCompileShader(shader_vp);
glCompileShader(shader_fp);
shader_id = glCreateProgram();
glAttachShader(shader_id, shader_fp);
glAttachShader(shader_id, shader_vp);
glLinkProgram(shader_id);
}
Shader::~Shader()
{
glDetachShader(shader_id, shader_fp);
glDetachShader(shader_id, shader_vp);
glDeleteShader(shader_fp);
glDeleteShader(shader_vp);
glDeleteShader(shader_id);
}
unsigned int Shader::id()
{
return shader_id;
}
void Shader::bind()
{
glUseProgram(shader_id);
}
void Shader::unbind()
{
glUseProgram(0);
}
Main.cpp
#include "Shader.h"
#include <cstdlib>
#include <iostream>
using namespace std;
Shader shader;
void init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
shader.init("shader.vert", "shader.frag");
}
void resize(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
int main()
{
int running = GL_TRUE;
// init GLFW
if (!glfwInit())
exit(EXIT_FAILURE);
if (!glfwOpenWindow(300, 300, 0, 0, 0, 0, 0, 0, GLFW_WINDOW))
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetWindowTitle("ohhai.");
glfwSetWindowSizeCallback(resize);
/* CHECK GLEW */
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
cout << "Error: " << glewGetErrorString(err) << endl;
}
cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl;
if (!GLEW_ARB_vertex_buffer_object)
{
cerr << "VBO not supported\n";
exit(1);
}
init();
while (running)
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glShadeModel(GL_SMOOTH);
shader.bind();
glBegin(GL_TRIANGLES);
//glColor3f(0.2f, 0.5f, 0.54f);
glVertex2f(0.0f, 0.5f);
//glColor3f(0.75f, 0.8f, 0.1f);
glVertex2f(-.5f, -.5f);
//glColor3f(0.0f, 0.9f, 0.2f);
glVertex2f(0.5f, -0.5f);
glEnd();
shader.unbind();
glfwSwapBuffers();
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
}
glfwTerminate();
exit(EXIT_SUCCESS);
}
shader.vert
void main()
{
// set the posistion of the current matrix
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
shader.frag
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Again, when this compiles under g++, it goes through fine, but no triangle was shown.
I haven't found the part where you setup the camera (modelview matrix) with gluLookAt or glTranslate/glRotate/glScale. So you use the default, corresponding to a camera at the origin and looking into -z, thus your triangle (which lies in the z=0 plane) is behind the near plane.