Skip to content

Instantly share code, notes, and snippets.

@leviska
Created May 3, 2020 23:49
Show Gist options
  • Save leviska/e2c2ebb15eeb0b7a076a7daa0398ba6d to your computer and use it in GitHub Desktop.
Save leviska/e2c2ebb15eeb0b7a076a7daa0398ba6d to your computer and use it in GitHub Desktop.
opengl bug
#version 330 core
out vec4 FragColor;
in vec4 vertexColor;
void main()
{
FragColor = vertexColor;
}
#include "window.h"
int main(int argc, char* args[])
{
Window window;
if (window.IsGood())
window.Process();
return 0;
}
#include "shader.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <cassert>
#include <glad/glad.h>
Shader::Shader(const std::string& vertexFile, const std::string& fragmentFile) : Shader() {
Load(vertexFile, fragmentFile);
}
Shader::~Shader() {
glDeleteProgram(id);
}
void Shader::Init() {
id = glCreateProgram();
}
bool Shader::Load(const std::string& vertexFile, const std::string& fragmentFile) {
uint32_t vertex = LoadShader(vertexFile, Type::Vertex);
if (vertex == 0)
return false;
uint32_t fragment = LoadShader(fragmentFile, Type::Fragment);
if (fragment == 0) {
DeleteShader(vertex);
return false;
}
bool result = Link(vertex, fragment);
DeleteShader(vertex);
DeleteShader(fragment);
return result;
}
void Shader::Select() const {
glUseProgram(id);
}
void Shader::Set(const std::string& name, bool value) const {
glUniform1i(glGetUniformLocation(id, name.c_str()), (int32_t)value);
}
void Shader::Set(const std::string& name, int32_t value) const {
glUniform1i(glGetUniformLocation(id, name.c_str()), value);
}
void Shader::Set(const std::string& name, float value) const {
glUniform1f(glGetUniformLocation(id, name.c_str()), value);
}
uint32_t Shader::GetId() const {
return id;
}
bool Shader::Link(uint32_t vertex, uint32_t fragment) {
glAttachShader(id, vertex);
glAttachShader(id, fragment);
int success;
std::string errorLog;
errorLog.reserve(512);
glLinkProgram(id);
glGetProgramiv(id, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(id, errorLog.capacity(), nullptr, &errorLog[0]);
std::cerr << "Failed to link shaders\n" << errorLog << std::endl;
return false;
}
glDeleteShader(vertex);
glDeleteShader(fragment);
return true;
}
uint32_t Shader::LoadShader(const std::string& fileName, Shader::Type type) {
std::string code = ReadShader(fileName);
if (code.empty())
return 0;
uint32_t shader = CompileShader(code, type);
if (shader == 0)
return 0;
return shader;
}
void Shader::DeleteShader(uint32_t shader) {
glDeleteShader(shader);
}
std::string Shader::ReadShader(const std::string& fileName) {
std::stringstream buffer;
std::ifstream file(fileName);
if (!file.good()) {
std::cerr << "Can't open " << fileName << " shader file" << std::endl;
return std::string();
}
buffer << file.rdbuf();
file.close();
return buffer.str();
}
uint32_t Shader::CompileShader(const std::string& code, Shader::Type type) {
assert(type != Type::None);
uint32_t shader;
int success;
std::string errorLog;
errorLog.reserve(512);
const char* cstrCode = code.c_str();
shader = glCreateShader((type == Type::Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER));
glShaderSource(shader, 1, &cstrCode, nullptr);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(shader, errorLog.capacity(), nullptr, &errorLog[0]);
std::cerr << "Failed to compile shader\n" << errorLog << std::endl;
return 0;
};
return shader;
}
#pragma once
#include <string>
#include <cstdint>
class Shader {
uint32_t id = 0;
public:
Shader() = default;
Shader(const std::string& vertexFile, const std::string& fragmentFile);
~Shader();
enum class Type {
None,
Vertex,
Fragment
};
void Init();
bool Load(const std::string& vertexFile, const std::string& fragmentFile);
void Select() const;
void Set(const std::string& name, bool value) const;
void Set(const std::string& name, int32_t value) const;
void Set(const std::string& name, float value) const;
uint32_t GetId() const;
bool Link(uint32_t vertex, uint32_t fragment);
static uint32_t LoadShader(const std::string& fileName, Shader::Type type);
static void DeleteShader(uint32_t shader);
private:
static std::string ReadShader(const std::string& fileName);
static uint32_t CompileShader(const std::string& code, Shader::Type type);
};
#version 330 core
layout (location = 0) in vec3 pos;
out vec4 vertexColor;
uniform float shift = 0;
void main()
{
gl_Position = vec4(pos.x, pos.y - shift, pos.z, 1.0);
vertexColor = vec4(0, 1, 0, 1.0);
}
#include "window.h"
#include <cassert>
#include <iostream>
#include <glad/glad.h>
#include <windows.h>
const float vertices[] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
const unsigned int indices[] = { // note that we start from 0!
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
Window::Window()
{
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
return;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!window) {
std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
return;
}
glcontext = SDL_GL_CreateContext(window);
if (!glcontext) {
std::cerr << "Unable to create GL context: " << SDL_GetError() << std::endl;
return;
}
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
std::cerr << "Failed to initialize GLAD" << std::endl;
return;
}
// OpenGL
glViewport(0, 0, 800, 600);
// Shaders
shader.Init();
if (!shader.Load("vertex.glsl", "fragment.glsl")) {
std::cerr << "Failed to load shaders" << std::endl;
return;
}
// Triangle
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
good = true;
open = true;
}
Window::~Window()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
if (glcontext)
SDL_GL_DeleteContext(glcontext);
if (window)
SDL_DestroyWindow(window);
SDL_Quit();
}
void Window::Process()
{
assert(good);
SDL_Event event;
while (open) {
while (SDL_PollEvent(&event) != 0) {
//User requests quit
if (event.type == SDL_QUIT) {
open = false;
}
if (event.type == SDL_WINDOWEVENT) {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
glViewport(0, 0, event.window.data1, event.window.data2);
}
}
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
shader.Select();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
shader.Set("shift", 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
shader.Set("shift", 0.5f);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glFlush();
SDL_GL_SwapWindow(window);
}
}
#pragma once
#include "shader.h"
#include <SDL.h>
class Window
{
public:
Window();
~Window();
bool IsGood() { return good; }
void Process();
private:
bool good = false;
bool open = false;
SDL_Window* window = nullptr;
SDL_GLContext glcontext = nullptr;
Shader shader;
unsigned int VBO = 0;
unsigned int VAO = 0;
unsigned int EBO = 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment