start adding GL shaders, program, texture loading
This commit is contained in:
parent
d4a4cfc9df
commit
afd3cb56f1
99
GLProgram.cc
Normal file
99
GLProgram.cc
Normal file
@ -0,0 +1,99 @@
|
||||
#include "GLProgram.h"
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
GLProgram::GLProgram()
|
||||
{
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
GLProgram::~GLProgram()
|
||||
{
|
||||
if (m_id > 0)
|
||||
{
|
||||
glDeleteProgram(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLProgram::create(const char *v_source, const char *f_source, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, f_source);
|
||||
bool rv = createv(v_source, f_source, va);
|
||||
va_end(va);
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool GLProgram::create(const uint8_t *v_source, const uint8_t *f_source, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, f_source);
|
||||
bool rv = createv((const char *) v_source, (const char *) f_source, va);
|
||||
va_end(va);
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool GLProgram::createv(const char *v_source, const char *f_source, va_list va)
|
||||
{
|
||||
if (v_source == NULL || f_source == NULL)
|
||||
return false;
|
||||
if (!m_v_shader.create(GL_VERTEX_SHADER, v_source))
|
||||
{
|
||||
cerr << "Failed vertex shader source:" << endl << v_source << endl;
|
||||
return false;
|
||||
}
|
||||
if (!m_f_shader.create(GL_FRAGMENT_SHADER, f_source))
|
||||
{
|
||||
cerr << "Failed fragment shader source:" << endl << f_source << endl;
|
||||
return false;
|
||||
}
|
||||
m_id = glCreateProgram();
|
||||
if (m_id <= 0)
|
||||
{
|
||||
cerr << "Error allocating GL program object" << endl;
|
||||
return false;
|
||||
}
|
||||
glAttachShader(m_id, m_v_shader.get_id());
|
||||
glAttachShader(m_id, m_f_shader.get_id());
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const char *attribute_name = va_arg(va, const char *);
|
||||
if (attribute_name == NULL)
|
||||
break;
|
||||
GLuint attribute_index = va_arg(va, uint32_t);
|
||||
glBindAttribLocation(m_id, attribute_index, attribute_name);
|
||||
}
|
||||
|
||||
glLinkProgram(m_id);
|
||||
|
||||
GLint link_status;
|
||||
glGetProgramiv(m_id, GL_LINK_STATUS, &link_status);
|
||||
if (link_status != GL_TRUE)
|
||||
{
|
||||
GLint log_length;
|
||||
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if (log_length > 0)
|
||||
{
|
||||
char *log = new char[log_length];
|
||||
glGetProgramInfoLog(m_id, log_length, &log_length, log);
|
||||
cerr << "Program log:" << endl << log << endl;
|
||||
delete[] log;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const char *uniform_name = va_arg(va, const char *);
|
||||
if (uniform_name == NULL)
|
||||
break;
|
||||
GLint loc = glGetUniformLocation(m_id, uniform_name);
|
||||
m_uniform_locations.push_back(loc);
|
||||
m_uniform_location_names[uniform_name] = loc;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
30
GLProgram.h
Normal file
30
GLProgram.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef GLPROGRAM_H
|
||||
#define GLPROGRAM_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "GLShader.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GLProgram
|
||||
{
|
||||
public:
|
||||
GLProgram();
|
||||
~GLProgram();
|
||||
bool create(const char *v_source, const char *f_source, ...);
|
||||
bool create(const uint8_t *v_source, const uint8_t *f_source, ...);
|
||||
bool createv(const char *v_source, const char *f_source, va_list va);
|
||||
GLuint get_id() { return m_id; }
|
||||
void use() { glUseProgram(m_id); }
|
||||
GLint uniform(int i) { return m_uniform_locations[i]; }
|
||||
GLint uniform(const std::string & s) { return m_uniform_location_names[s]; }
|
||||
protected:
|
||||
GLuint m_id;
|
||||
GLShader m_v_shader;
|
||||
GLShader m_f_shader;
|
||||
std::vector<GLint> m_uniform_locations;
|
||||
std::map<std::string, GLint> m_uniform_location_names;
|
||||
};
|
||||
|
||||
#endif
|
59
GLShader.cc
Normal file
59
GLShader.cc
Normal file
@ -0,0 +1,59 @@
|
||||
#include "GLShader.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
GLShader::GLShader()
|
||||
{
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
GLShader::~GLShader()
|
||||
{
|
||||
if (m_id > 0)
|
||||
{
|
||||
glDeleteShader(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLShader::create(GLenum shaderType, const char *source)
|
||||
{
|
||||
GLint status;
|
||||
|
||||
m_id = glCreateShader(shaderType);
|
||||
if (m_id > 0)
|
||||
{
|
||||
glShaderSource(m_id, 1, &source, NULL);
|
||||
|
||||
glCompileShader(m_id);
|
||||
|
||||
glGetShaderiv(m_id, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_TRUE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
GLint log_length;
|
||||
cerr << "Error compiling ";
|
||||
switch (shaderType)
|
||||
{
|
||||
case GL_VERTEX_SHADER:
|
||||
cerr << "vertex";
|
||||
break;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
cerr << "fragment";
|
||||
break;
|
||||
}
|
||||
cerr << " shader" << endl;
|
||||
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if (log_length > 0)
|
||||
{
|
||||
char * log = new char[log_length];
|
||||
glGetShaderInfoLog(m_id, log_length, &log_length, log);
|
||||
cerr << "Shader Log:" << endl << log << endl;
|
||||
delete[] log;
|
||||
}
|
||||
glDeleteShader(m_id);
|
||||
}
|
||||
return false;
|
||||
}
|
18
GLShader.h
Normal file
18
GLShader.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef GLSHADER_H
|
||||
#define GLSHADER_H
|
||||
|
||||
#include "gl3w.h"
|
||||
|
||||
class GLShader
|
||||
{
|
||||
public:
|
||||
GLShader();
|
||||
~GLShader();
|
||||
bool create(GLenum shaderType, const char *source);
|
||||
GLuint get_id() { return m_id; }
|
||||
bool valid() { return m_id > 0; }
|
||||
protected:
|
||||
GLuint m_id;
|
||||
};
|
||||
|
||||
#endif
|
2
Makefile
2
Makefile
@ -7,7 +7,7 @@ CFLAGS := $(shell freetype-config --cflags) $(shell sdl2-config --cflags)
|
||||
CXXFLAGS := $(CFLAGS)
|
||||
LDFLAGS := -l$(GL_LIB) -ldl -lfreetype $(shell sdl2-config --libs) $(shell freetype-config --libs)
|
||||
|
||||
freetype2gl3: gl3w.o freetype2gl3.o
|
||||
freetype2gl3: gl3w.o freetype2gl3.o GLShader.o GLProgram.o
|
||||
$(CXX) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
.PHONY: clean
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <iostream>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "GLProgram.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -11,15 +12,76 @@ using namespace std;
|
||||
|
||||
static FT_Library ft;
|
||||
static FT_Face face;
|
||||
static GLProgram program;
|
||||
static GLint uniform_tex;
|
||||
|
||||
const char vertex_shader[] =
|
||||
"#version 120\n"
|
||||
"\n"
|
||||
"attribute vec4 coord;\n"
|
||||
"\n"
|
||||
"varying vec2 tex_coord_i;\n"
|
||||
"\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(coord.xy, 0, 1);\n"
|
||||
" tex_coord_i = coord.zw;\n"
|
||||
"}\n";
|
||||
|
||||
const char fragment_shader[] =
|
||||
"varying vec2 tex_coord_i;\n"
|
||||
"\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform vec4 color;\n"
|
||||
"\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_FragColor = vec4(1, 1, 1, texture2D(tex, tex_coord_i).a) * color;\n"
|
||||
"}\n";
|
||||
|
||||
void init(void)
|
||||
{
|
||||
glClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
program.create(vertex_shader, fragment_shader,
|
||||
"coord", 0, NULL,
|
||||
"tex", NULL);
|
||||
uniform_tex = program.uniform("tex");
|
||||
program.use();
|
||||
}
|
||||
|
||||
void display(SDL_Window * window)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
if (FT_Load_Char(face, 'h', FT_LOAD_RENDER) != 0)
|
||||
{
|
||||
cerr << "Failed to load character" << endl;
|
||||
}
|
||||
#if 0
|
||||
GLuint texture_id;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_ALPHA,
|
||||
face->glyph->bitmap.width,
|
||||
face->glyph->bitmap.rows,
|
||||
0,
|
||||
GL_ALPHA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
face->glyph->bitmap.buffer);
|
||||
GLuint vbo;
|
||||
glGenBuffers(1, &vbo);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glUniform1i(uniform_tex, 0);
|
||||
#endif
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user