Skip to content

Instantly share code, notes, and snippets.

@LordAro
Last active August 29, 2015 14:19
Show Gist options
  • Save LordAro/63146578ed3185bc28c3 to your computer and use it in GitHub Desktop.
Save LordAro/63146578ed3185bc28c3 to your computer and use it in GitHub Desktop.
#version 120
// The texture data
uniform sampler2D texture;
// Interpolated texture coordinates recieved from vertex shader
varying vec2 tex_position;
void main(void) {
// Sets the fragment colour to the corresponding texel
gl_FragColor = texture2D(texture, tex_position);
}
#version 120
// Modelview*projection matrix
uniform mat4 mvp_matrix;
// Position of this vertex
attribute vec4 vertex_position;
// Coordinates assigned to this vertex
attribute vec2 tex_coords;
// Interpolated texture coordinates sent to fragment shader
varying vec2 tex_position;
void main(void) {
// Transform the vertex coordinates
gl_Position = gl_ModelViewProjectionMatrix * vertex_position;
// Pass the fix points for texture coordinates set at this vertex
tex_position = tex_coords;
}
#include <cassert>
#include <stdexcept>
#include <string>
#include "shader.h"
Shader::Shader(GLenum type, const char *source) : type(type)
{
this->id = glCreateShader(type);
// Load & compile
glShaderSource(this->id, 1, &source, nullptr);
glCompileShader(this->id);
// Get compile result
GLint status;
glGetShaderiv(this->id, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
GLint loglen;
glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &loglen);
char *infolog = new char[loglen];
glGetShaderInfoLog(this->id, loglen, nullptr, infolog);
std::string err = "Failed to compile ";
err += Shader::TypeToString(this->type);
err += " shader:\n";
err += infolog;
delete infolog;
throw std::runtime_error(err);
}
}
Shader::~Shader()
{
glDeleteShader(this->id);
}
/* static */ const char *Shader::TypeToString(GLenum type)
{
switch (type) {
case GL_VERTEX_SHADER:
return "vertex";
case GL_FRAGMENT_SHADER:
return "fragment";
case GL_GEOMETRY_SHADER:
return "geometry";
default:
throw std::runtime_error("Unknown shader type");
}
}
ShaderProgram::ShaderProgram(Shader *vert, Shader *frag)
{
this->id = glCreateProgram();
glAttachShader(this->id, vert->id);
glAttachShader(this->id, frag->id);
glLinkProgram(this->id);
GLint status;
glGetProgramiv(this->id, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
// TODO: More debug info
throw std::runtime_error("Program failed to link");
}
glValidateProgram(this->id);
glGetProgramiv(this->id, GL_VALIDATE_STATUS, &status);
if (status != GL_TRUE) {
// TODO: More debug info
throw std::runtime_error("Program failed to validate");
}
this->pos_id = glGetAttribLocation(this->id, "vertex_position");
this->mvpm_id = glGetUniformLocation(this->id, "mvp_matrix");
assert(this->pos_id != -1 || this->mvpm_id != -1);
glDetachShader(this->id, vert->id);
glDetachShader(this->id, frag->id);
this->tex_coord = glGetAttribLocation(this->id, "tex_coords");
this->texture = glGetUniformLocation(this->id, "texture");
assert(this->tex_coord != -1 || this->texture != -1);
this->Use();
glUniform1i(this->texture, 0);
this->StopUsing();
}
ShaderProgram::~ShaderProgram()
{
glDeleteProgram(this->id);
}
void ShaderProgram::Use()
{
glUseProgram(this->id);
}
void ShaderProgram::StopUsing()
{
glUseProgram(0);
}
#include <stdexcept>
#include <SDL2/SDL_image.h>
#include "texture.h"
#include "video.h"
Texture::Texture(const std::string &filepath)
{
glGenTextures(1, &this->texid);
if (this->texid == 0) {
const char *glerr = (const char *)gluErrorString(glGetError());
std::string err = "Error creating texture: ";
err += glerr;
throw std::runtime_error(err);
}
glBindTexture(GL_TEXTURE_2D, this->texid);
// Set texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
SDL_Surface *surface = IMG_Load(filepath.c_str());
GLint int_format;
GLenum format;
switch (surface->format->BytesPerPixel) {
case 3:
int_format = GL_RGB8;
format = GL_RGB;
break;
case 4:
int_format = GL_RGBA8;
format = GL_RGBA;
break;
default:
throw std::runtime_error("unknown texture bit depth for" + filepath);
}
this->width = surface->w;
this->height = surface->h;
glTexImage2D(GL_TEXTURE_2D, 0, int_format, this->width, this->height, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
SDL_FreeSurface(surface);
glGenBuffers(1, &this->vbo);
}
Texture::~Texture()
{
glDeleteTextures(1, &this->texid);
glDeleteBuffers(1, &this->vbo);
}
void Texture::OnDraw(int x, int y) const
{
glColor4f(1, 1, 1, 1); // Should be black?
auto shader = _vid.GetShader(0);
shader->Use();
int *pos_id = &shader->pos_id;
int *texcoord_id = &shader->tex_coord;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->texid);
float left = x;
float right = x + this->width;
float top = y;
float bottom = y + this->height;
float vertices[] = {
left, top, 0, 0,
right, top, 1, 0,
left, bottom, 0, 1,
right, top, 1, 0,
left, bottom, 0, 1,
right, bottom, 1, 1,
};
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(*pos_id);
glEnableVertexAttribArray(*texcoord_id);
glVertexAttribPointer(*texcoord_id, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(0));
glVertexAttribPointer(*pos_id, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(2*sizeof(float)));
/* glBegin(GL_TRIANGLES);
{
glTexCoord2f(0, 0); glVertex3f(x, y, 0);
glTexCoord2f(1, 0); glVertex3f(x + this->width, y, 0);
glTexCoord2f(0, 1); glVertex3f(x, y + this->height, 0);
glTexCoord2f(1, 0); glVertex3f(x + this->width, y, 0);
glTexCoord2f(0, 1); glVertex3f(x, y + this->height, 0);
glTexCoord2f(1, 1); glVertex3f(x + this->width, y + this->height, 0);
}
glEnd();*/
glDrawArrays(GL_TRIANGLES, 0, 6); // 2 triangles
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(*pos_id);
glDisableVertexAttribArray(*texcoord_id);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment