Compare commits

...

6 Commits

14 changed files with 8632 additions and 11 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "cglm/cglm"]
path = cglm/cglm
url = https://github.com/recp/cglm.git

View File

@@ -1,17 +1,20 @@
cmake_minimum_required(VERSION 3.5)
project(shimatta-opengl LANGUAGES C)
add_subdirectory(cglm)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
pkg_check_modules(EPOXY REQUIRED epoxy)
add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
aux_source_directory("src" SRC_DIR)
aux_source_directory("stb" STB_DIR)
add_library(${PROJECT_NAME} SHARED ${SRC_DIR})
add_library(${PROJECT_NAME} SHARED ${SRC_DIR} ${STB_DIR})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(${PROJECT_NAME} PRIVATE ${EPOXY_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${GLIB_LDFLAGS} ${EPOXY_LDFLAGS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${GLIB_LDFLAGS} ${EPOXY_LDFLAGS} cglm)
target_link_directories(${PROJECT_NAME} PUBLIC ${GLIB_LINK_DIRS} ${EPOXY_LINK_DIRS})
target_include_directories(${PROJECT_NAME} PUBLIC ${GLIB_INCLUDE_DIRS})

13
cglm/CMakeLists.txt Normal file
View File

@@ -0,0 +1,13 @@
project(cglm)
cmake_minimum_required(VERSION 2.8)
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS} ${OPENCL_INCLUDE_DIRS})
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
add_definitions(${GLIB2_CFLAGS_OTHER})
aux_source_directory("cglm/src" SOURCES)
add_library(${PROJECT_NAME} STATIC ${SOURCES})
add_compile_options(-Wall -std=gnu99 -O3 -Wstrict-aliasing=2 -fstrict-aliasing -pedantic)
target_include_directories(${PROJECT_NAME} PUBLIC "cglm/include")
target_link_libraries(${PROJECT_NAME} m)

1
cglm/cglm Submodule

Submodule cglm/cglm added at 79c44fdbfa

View File

@@ -0,0 +1,33 @@
/*
* This file is part of Shimatta OpenGL.
*
* Shimatta OpenGL is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Shimatta OpenGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GtkGraphView. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _SHIMATTA_OPENGL_COLORED_TRIANGLE_H_
#define _SHIMATTA_OPENGL_COLORED_TRIANGLE_H_
#include <shimatta-opengl-graphics.h>
#include <shimatta-opengl-program.h>
G_BEGIN_DECLS
#define SHIMATTA_TYPE_OPENGL_COLORED_TRIANGLE (shimatta_opengl_colored_triangle_get_type())
G_DECLARE_FINAL_TYPE(ShimattaOpenglColoredTriangle, shimatta_opengl_colored_triangle, SHIMATTA, OPENGL_COLORED_TRIANGLE, ShimattaOpenglGraphics);
ShimattaOpenglGraphics *shimatta_opengl_colored_triangle_new(ShimattaOpenglProgram *prog, const vec3 color, const vec3* vertecies);
G_END_DECLS
#endif /* _SHIMATTA_OPENGL_COLORED_TRIANGLE_H_ */

View File

@@ -0,0 +1,46 @@
/*
* This file is part of Shimatta OpenGL.
*
* Shimatta OpenGL is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Shimatta OpenGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GtkGraphView. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _SHIMATTA_OPENGL_GRAPHICS_H_
#define _SHIMATTA_OPENGL_GRAPHICS_H_
#include <glib.h>
#include <glib-object.h>
#include <cglm/cglm.h>
G_BEGIN_DECLS
#define SHIMATTA_TYPE_OPENGL_GRAPHICS (shimatta_opengl_graphics_get_type())
G_DECLARE_DERIVABLE_TYPE(ShimattaOpenglGraphics, shimatta_opengl_graphics, SHIMATTA, OPENGL_GRAPHICS, GObject);
struct _ShimattaOpenglGraphicsClass {
GObjectClass super_class;
int (*realize)(ShimattaOpenglGraphics *graphics);
void (*draw)(ShimattaOpenglGraphics *graphics);
void (*draw_with_model_matrix)(ShimattaOpenglGraphics *graphics, mat4 model_matrix, mat4 normal_matrix);
};
int shimatta_opengl_graphics_realize(ShimattaOpenglGraphics *graphics);
void shimatta_opengl_graphics_draw(ShimattaOpenglGraphics *graphics);
void shimatta_opengl_graphics_draw_with_model_matrix(ShimattaOpenglGraphics *graphics, mat4 model_matrix, mat4 normal_matrix);
G_END_DECLS
#endif /* _SHIMATTA_OPENGL_GRAPHICS_H_ */

View File

@@ -1,7 +1,7 @@
/*
* This file is part of Shimatta OpenGL.
*
* Foobar is free software: you can redistribute it and/or modify
* Shimatta OpenGL is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
@@ -14,8 +14,12 @@
* along with GtkGraphView. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _SHIMATTA_OPENGL_PROGRAM_H_
#define _SHIMATTA_OPENGL_PROGRAM_H_
#include <glib.h>
#include <glib-object.h>
#include <cglm/cglm.h>
G_BEGIN_DECLS
@@ -72,4 +76,38 @@ int shimatta_opengl_program_use(ShimattaOpenglProgram *program);
*/
gboolean shimatta_opengl_program_is_compiled(ShimattaOpenglProgram *program);
/**
* @brief Get the location of a uniform of a given shader program
* @param program Shader program
* @param uniform_name Name of the uniform parameter
* @return Location. -1 if error.
*/
int shimatta_opengl_program_get_uniform_location(ShimattaOpenglProgram *program, const char *uniform_name);
/**
* @brief Get the location of an Attribute of a given shader program
* @param program Shader program
* @param attrib_name Name of the attribute
* @return Location of attribute. -1 if error.
*/
int shimatta_opengl_program_get_attrib_location(ShimattaOpenglProgram *program, const char *attrib_name);
void shimatta_opengl_program_set_uniform_float(ShimattaOpenglProgram *program, const char *uniform, float value);
void shimatta_opengl_program_set_uniform_int(ShimattaOpenglProgram *program, const char *uniform, int value);
void shimatta_opengl_program_set_uniform_vec2(ShimattaOpenglProgram *program, const char *uniform, vec2 value);
void shimatta_opengl_program_set_uniform_vec3(ShimattaOpenglProgram *program, const char *uniform, vec3 value);
void shimatta_opengl_program_set_uniform_vec4(ShimattaOpenglProgram *program, const char *uniform, vec4 value);
void shimatta_opengl_program_set_uniform_mat2(ShimattaOpenglProgram *program, const char *uniform, mat2 value);
void shimatta_opengl_program_set_uniform_mat3(ShimattaOpenglProgram *program, const char *uniform, mat3 value);
void shimatta_opengl_program_set_uniform_mat4(ShimattaOpenglProgram *program, const char *uniform, mat4 value);
G_END_DECLS
#endif /* _SHIMATTA_OPENGL_PROGRAM_H_ */

View File

@@ -0,0 +1,53 @@
#ifndef _SHIMATTA_OPENGL_TEXTURE_H_
#define _SHIMATTA_OPENGL_TEXTURE_H_
#include <glib.h>
#include <glib-object.h>
#include <epoxy/gl.h>
G_BEGIN_DECLS
#define SHIMATTA_TYPE_OPENGL_TEXTURE (shimatta_opengl_texture_get_type())
G_DECLARE_DERIVABLE_TYPE(ShimattaOpenglTexture, shimatta_opengl_texture, SHIMATTA, OPENGL_TEXTURE, GObject);
struct _ShimattaOpenglTextureClass {
GObjectClass super;
void (*use)(ShimattaOpenglTexture *texture);
int (*use_in_slot)(ShimattaOpenglTexture *texture, unsigned int slot);
};
void shimatta_opengl_texture_use(ShimattaOpenglTexture *texture);
int shimatta_opengl_texture_use_in_slot(ShimattaOpenglTexture *texture, unsigned int slot);
ShimattaOpenglTexture *shimatta_opengl_texture_new(void);
int shimatta_opengl_texture_set_data(ShimattaOpenglTexture *texture, unsigned int width, unsigned int height,
GLenum format, void *buffer);
int shimatta_opengl_texture_set_data_from_image(ShimattaOpenglTexture *texture, const char *path);
void shimatta_opengl_texture_set_wrap_s(ShimattaOpenglTexture *self, int wrap_s);
void shimatta_opengl_texture_set_wrap_t(ShimattaOpenglTexture *self, int wrap_t);
void shimatta_opengl_texture_set_min_filter(ShimattaOpenglTexture *self, int min_filter);
void shimatta_opengl_texture_set_mag_filter(ShimattaOpenglTexture *self, int mag_filter);
void shimatta_opengl_texture_set_gen_mipmap(ShimattaOpenglTexture *self, gboolean gen_mipmap);
int shimatta_opengl_texture_get_wrap_s(ShimattaOpenglTexture *self);
int shimatta_opengl_texture_get_wrap_t(ShimattaOpenglTexture *self);
int shimatta_opengl_texture_get_mag_filter(ShimattaOpenglTexture *self);
int shimatta_opengl_texture_get_min_filter(ShimattaOpenglTexture *self);
gboolean shimatta_opengl_texture_get_gen_mipmap(ShimattaOpenglTexture *self);
G_END_DECLS
#endif /* _SHIMATTA_OPENGL_TEXTURE_H_ */

7656
include/stb/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
/*
* This file is part of Shimatta OpenGL.
*
* Shimatta OpenGL is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Shimatta OpenGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GtkGraphView. If not, see <https://www.gnu.org/licenses/>.
*/
#include <shimatta-opengl-colored-triangle.h>
#include <shimatta-opengl-program.h>
#include <epoxy/gl.h>
struct _ShimattaOpenglColoredTriangle {
ShimattaOpenglGraphics super;
};
typedef struct {
vec3 color;
vec3 vertecies[3];
GLuint vao;
GLuint vbo;
ShimattaOpenglProgram *prog;
} ShimattaOpenglColoredTrianglePrivate;
G_DEFINE_TYPE_WITH_PRIVATE(ShimattaOpenglColoredTriangle, shimatta_opengl_colored_triangle, SHIMATTA_TYPE_OPENGL_GRAPHICS);
static int realize(ShimattaOpenglGraphics *self)
{
ShimattaOpenglColoredTrianglePrivate *priv;
priv = shimatta_opengl_colored_triangle_get_instance_private(SHIMATTA_OPENGL_COLORED_TRIANGLE(self));
glGenVertexArrays(1, &priv->vao);
glBindVertexArray(priv->vao);
glGenBuffers(1, &priv->vbo);
glBindBuffer(GL_ARRAY_BUFFER, priv->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*3, priv->vertecies, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
return 0;
}
static void draw(ShimattaOpenglGraphics *self)
{
ShimattaOpenglColoredTrianglePrivate *priv;
priv = shimatta_opengl_colored_triangle_get_instance_private(SHIMATTA_OPENGL_COLORED_TRIANGLE(self));
shimatta_opengl_program_use(priv->prog);
shimatta_opengl_program_set_uniform_vec3(priv->prog, "color", priv->color);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindVertexArray(priv->vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
static void draw_with_model_matrix(ShimattaOpenglGraphics *self, mat4 m, mat4 n)
{
(void)m;
(void)n;
draw(self);
}
static void shimatta_opengl_colored_triangle_dispose(GObject *obj)
{
ShimattaOpenglColoredTriangle *self;
ShimattaOpenglColoredTrianglePrivate *priv;
self = SHIMATTA_OPENGL_COLORED_TRIANGLE(obj);
priv = shimatta_opengl_colored_triangle_get_instance_private(self);
if (priv->vao) {
glDeleteVertexArrays(1, &priv->vao);
priv->vao = 0;
}
if (priv->vbo) {
glDeleteBuffers(1, &priv->vbo);
priv->vbo = 0;
}
g_clear_object(&priv->prog);
G_OBJECT_CLASS(shimatta_opengl_colored_triangle_parent_class)->dispose(obj);
}
void shimatta_opengl_colored_triangle_class_init(ShimattaOpenglColoredTriangleClass *klass)
{
ShimattaOpenglGraphicsClass *gclass;
GObjectClass *oclass;
gclass = SHIMATTA_OPENGL_GRAPHICS_CLASS(klass);
oclass = G_OBJECT_CLASS(klass);
gclass->draw = draw;
gclass->realize = realize;
gclass->draw_with_model_matrix = draw_with_model_matrix;
oclass->dispose = shimatta_opengl_colored_triangle_dispose;
}
void shimatta_opengl_colored_triangle_init(ShimattaOpenglColoredTriangle *self)
{
ShimattaOpenglColoredTrianglePrivate *priv;
priv = shimatta_opengl_colored_triangle_get_instance_private(self);
priv->color[0] = 0.0f;
priv->color[1] = 0.0f;
priv->color[2] = 0.0f;
}
ShimattaOpenglGraphics *shimatta_opengl_colored_triangle_new(ShimattaOpenglProgram *prog, const vec3 color, const vec3* vertecies)
{
ShimattaOpenglGraphics *ret;
ShimattaOpenglColoredTrianglePrivate *priv;
ret = g_object_new(SHIMATTA_TYPE_OPENGL_COLORED_TRIANGLE, NULL);
priv = shimatta_opengl_colored_triangle_get_instance_private(SHIMATTA_OPENGL_COLORED_TRIANGLE(ret));
priv->prog = prog;
g_object_ref(prog);
priv->vertecies[0][0] = vertecies[0][0];
priv->vertecies[0][1] = vertecies[0][1];
priv->vertecies[0][2] = vertecies[0][2];
priv->vertecies[1][0] = vertecies[1][0];
priv->vertecies[1][1] = vertecies[1][1];
priv->vertecies[1][2] = vertecies[1][2];
priv->vertecies[2][0] = vertecies[2][0];
priv->vertecies[2][1] = vertecies[2][1];
priv->vertecies[2][2] = vertecies[2][2];
priv->color[0] = color[0];
priv->color[1] = color[1];
priv->color[2] = color[2];
return ret;
}

View File

@@ -0,0 +1,101 @@
/*
* This file is part of Shimatta OpenGL.
*
* Shimatta OpenGL is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Shimatta OpenGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GtkGraphView. If not, see <https://www.gnu.org/licenses/>.
*/
#include <shimatta-opengl-graphics.h>
typedef struct {
gpointer dummy[12];
} ShimattaOpenglGraphicsPrivate;
G_DEFINE_TYPE_WITH_PRIVATE(ShimattaOpenglGraphics, shimatta_opengl_graphics, G_TYPE_OBJECT);
static void shimatta_opengl_graphics_dispose(GObject *self)
{
G_OBJECT_CLASS(shimatta_opengl_graphics_parent_class)->dispose(self);
}
static void draw_dummy(ShimattaOpenglGraphics *graphics)
{
(void)graphics;
g_warning("Object does not implement draw function");
}
static void draw_dummy_with_matrix(ShimattaOpenglGraphics *graphics, mat4 model_matrix, mat4 normal_matrix)
{
(void)graphics;
(void)model_matrix;
(void)normal_matrix;
g_warning("Object does not implement draw_with_model_matrix function");
}
static int realize_dummy(ShimattaOpenglGraphics *graphics)
{
(void)graphics;
g_warning("Object does not implement relize function");
return -1;
}
static void shimatta_opengl_graphics_class_init(ShimattaOpenglGraphicsClass *klass)
{
(void)klass;
GObjectClass *oclass;
oclass = G_OBJECT_CLASS(klass);
oclass->dispose = shimatta_opengl_graphics_dispose;
klass->draw = draw_dummy;
klass->draw_with_model_matrix = draw_dummy_with_matrix;
klass->realize = realize_dummy;
return;
}
static void shimatta_opengl_graphics_init(ShimattaOpenglGraphics *self)
{
(void)self;
return;
}
int shimatta_opengl_graphics_realize(ShimattaOpenglGraphics *graphics)
{
ShimattaOpenglGraphicsClass *klass;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_GRAPHICS(graphics), -1001);
klass = SHIMATTA_OPENGL_GRAPHICS_GET_CLASS(graphics);
return klass->realize(graphics);
}
void shimatta_opengl_graphics_draw(ShimattaOpenglGraphics *graphics)
{
ShimattaOpenglGraphicsClass *klass;
g_return_if_fail(SHIMATTA_IS_OPENGL_GRAPHICS(graphics));
klass = SHIMATTA_OPENGL_GRAPHICS_GET_CLASS(graphics);
klass->draw(graphics);
}
void shimatta_opengl_graphics_draw_with_model_matrix(ShimattaOpenglGraphics *graphics, mat4 model_matrix, mat4 normal_matrix)
{
ShimattaOpenglGraphicsClass *klass;
g_return_if_fail(SHIMATTA_IS_OPENGL_GRAPHICS(graphics));
klass = SHIMATTA_OPENGL_GRAPHICS_GET_CLASS(graphics);
klass->draw_with_model_matrix(graphics, model_matrix, normal_matrix);
}

View File

@@ -1,7 +1,7 @@
/*
* This file is part of Shimatta OpenGL.
*
* Foobar is free software: you can redistribute it and/or modify
* Shimatta OpenGL is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
@@ -16,6 +16,8 @@
#include <shimatta-opengl-program.h>
#include <epoxy/gl.h>
#include <stdio.h>
#include <stdlib.h>
struct _ShimattaOpenglProgram {
GObject super;
@@ -62,6 +64,8 @@ static void shimatta_opengl_program_dispose(GObject *self)
if (priv->geometry_file)
g_free(priv->geometry_file);
G_OBJECT_CLASS(shimatta_opengl_program_parent_class)->dispose(self);
}
static void shimatta_opengl_program_class_init(ShimattaOpenglProgramClass *klass)
@@ -149,12 +153,44 @@ gboolean shimatta_opengl_program_is_compiled(ShimattaOpenglProgram *program)
return priv->compiled;
}
static char *load_shader_from_source_file(const char *src_file)
/**
* @brief This function loads the entire content of a file into a zero-terminated string
* @param src_file Path to the source file
* @return Newly created buffer containing file content. NULL in case of an error.
* @note The returend buffer has to be deleted by the caller using g_free()
*/
static gchar *load_shader_from_source_file(const char *src_file)
{
FILE *fil;
long int end_position;
gchar *file_content;
if (!src_file)
return NULL;
fil = fopen(src_file, "rb");
if (!fil) {
g_warning("Shader source file not found: %s", src_file);
return NULL;
}
/* Get length of file */
fseek(fil, 0, SEEK_END);
end_position = ftell(fil);
fseek(fil, 0, SEEK_SET);
/* Allocate memory for file content */
file_content = (gchar *)g_malloc(end_position + 1);
fread(file_content, 1, end_position, fil);
fclose(fil);
/* Append null terminator */
file_content[end_position] = '\0';
return file_content;
}
static int compile_shader(const char *src, char *error_text, size_t error_text_size, gboolean use_error,
static int compile_shader(const gchar *src, char *error_text, size_t error_text_size, gboolean use_error,
GLuint shader_type, GLuint *shader_id_out)
{
GLuint shader_id;
@@ -186,7 +222,7 @@ int shimatta_opengl_program_compile(ShimattaOpenglProgram *program, char *error_
{
gboolean use_error = FALSE;
ShimattaOpenglProgramPrivate *priv;
char *shader_source_code;
gchar *shader_source_code;
int ret_val = 0;
int status;
GLint success;
@@ -195,8 +231,10 @@ int shimatta_opengl_program_compile(ShimattaOpenglProgram *program, char *error_
g_return_val_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program), -1001);
if (error_text && error_text_size > 0)
if (error_text && error_text_size > 0) {
use_error = TRUE;
error_text[0] = 0;
}
priv = shimatta_opengl_program_get_instance_private(program);
@@ -224,7 +262,7 @@ int shimatta_opengl_program_compile(ShimattaOpenglProgram *program, char *error_
status = compile_shader(shader_source_code, error_text, error_text_size, use_error, GL_VERTEX_SHADER,
&vertex_shader);
free(shader_source_code);
g_free(shader_source_code);
if (status) {
ret_val = -2;
@@ -251,7 +289,7 @@ int shimatta_opengl_program_compile(ShimattaOpenglProgram *program, char *error_
status = compile_shader(shader_source_code, error_text, error_text_size, use_error, GL_FRAGMENT_SHADER,
&fragment_shader);
free(shader_source_code);
g_free(shader_source_code);
if (status) {
ret_val = -2;
@@ -278,7 +316,7 @@ int shimatta_opengl_program_compile(ShimattaOpenglProgram *program, char *error_
status = compile_shader(shader_source_code, error_text, error_text_size, use_error, GL_GEOMETRY_SHADER,
&geometry_shader);
free(shader_source_code);
g_free(shader_source_code);
if (status) {
ret_val = -2;
@@ -309,3 +347,139 @@ return_value:
return ret_val;
}
int shimatta_opengl_program_get_uniform_location(ShimattaOpenglProgram *program, const char *uniform_name)
{
int ret;
ShimattaOpenglProgramPrivate *priv;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program), -1001);
if (!uniform_name)
return -1002;
if (!shimatta_opengl_program_is_compiled(program)) {
g_warning("Trying to get Uniform location of %s for not loaded shader program", uniform_name);
return -1;
}
priv = shimatta_opengl_program_get_instance_private(program);
ret = glGetUniformLocation(priv->shader_id, (const GLchar *)uniform_name);
return ret;
}
int shimatta_opengl_program_get_attrib_location(ShimattaOpenglProgram *program, const char *attrib_name)
{
int ret;
ShimattaOpenglProgramPrivate *priv;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program), -1001);
if (!attrib_name)
return -1002;
if (!shimatta_opengl_program_is_compiled(program)) {
g_warning("Trying to get Attribute location of %s for not loaded shader program", attrib_name);
return -1;
}
priv = shimatta_opengl_program_get_instance_private(program);
ret = glGetAttribLocation(priv->shader_id, (const GLchar *)attrib_name);
return ret;
}
void shimatta_opengl_program_set_uniform_float(ShimattaOpenglProgram *program, const char *uniform, float value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniform1f(loc, value);
}
void shimatta_opengl_program_set_uniform_int(ShimattaOpenglProgram *program, const char *uniform, int value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniform1i(loc, value);
}
void shimatta_opengl_program_set_uniform_vec2(ShimattaOpenglProgram *program, const char *uniform, vec2 value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniform2fv(loc, 1, value);
}
void shimatta_opengl_program_set_uniform_vec3(ShimattaOpenglProgram *program, const char *uniform, vec3 value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniform3fv(loc, 1, value);
}
void shimatta_opengl_program_set_uniform_vec4(ShimattaOpenglProgram *program, const char *uniform, vec4 value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniform4fv(loc, 1, value);
}
void shimatta_opengl_program_set_uniform_mat2(ShimattaOpenglProgram *program, const char *uniform, mat2 value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniformMatrix2fv(loc, 1, GL_FALSE, &value[0][0]);
}
void shimatta_opengl_program_set_uniform_mat3(ShimattaOpenglProgram *program, const char *uniform, mat3 value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniformMatrix3fv(loc, 1, GL_FALSE, &value[0][0]);
}
void shimatta_opengl_program_set_uniform_mat4(ShimattaOpenglProgram *program, const char *uniform, mat4 value)
{
int loc;
g_return_if_fail(SHIMATTA_IS_OPENGL_PROGRAM(program));
g_return_if_fail(uniform != NULL);
loc = shimatta_opengl_program_get_uniform_location(program, uniform);
if (loc >= 0)
glUniformMatrix4fv(loc, 1, GL_FALSE, &value[0][0]);
}

View File

@@ -0,0 +1,351 @@
#include <shimatta-opengl-texture.h>
#include <stb/stb_image.h>
#include <epoxy/gl.h>
typedef struct {
gboolean generate_mipmap;
GLuint texture_id;
} ShimattaOpenglTexturePrivate;
enum shimatta_opengl_texture_properties {
PROP_TEXTURE_WRAP_S = 1,
PROP_TEXTURE_WRAP_T,
PROP_TEXTURE_MIN_FILTER,
PROP_TEXTURE_MAG_FILTER,
PROP_TEXTURE_GEN_MIPMAP,
N_PROPS_TEXTURE
};
G_DEFINE_TYPE_WITH_PRIVATE(ShimattaOpenglTexture, shimatta_opengl_texture, G_TYPE_OBJECT);
static int shimatta_opengl_texure_use_default_impl(ShimattaOpenglTexture *texture, unsigned int slot, gboolean use_slot)
{
ShimattaOpenglTexturePrivate *priv;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(texture), -1001);
priv = shimatta_opengl_texture_get_instance_private(texture);
if (use_slot) {
if (slot > 31)
return -1002;
else
glActiveTexture(GL_TEXTURE0+slot);
}
glBindTexture(GL_TEXTURE_2D, priv->texture_id);
return 0;
}
static int use_in_slot_default(ShimattaOpenglTexture *texture, unsigned int slot)
{
return shimatta_opengl_texure_use_default_impl(texture, slot, TRUE);
}
static void use_default(ShimattaOpenglTexture *texture)
{
(void)shimatta_opengl_texure_use_default_impl(texture, 0U, FALSE);
}
static void shimatta_opengl_texture_dispose(ShimattaOpenglTexture *self)
{
ShimattaOpenglTexturePrivate *priv;
priv = shimatta_opengl_texture_get_instance_private(self);
if (priv->texture_id) {
glDeleteTextures(1, &priv->texture_id);
priv->texture_id = 0;
}
G_OBJECT_CLASS(shimatta_opengl_texture_parent_class)->dispose(G_OBJECT(self));
}
static void shimatta_opengl_texture_get_property(GObject *obj, guint id, GValue *val, GParamSpec *spec)
{
ShimattaOpenglTexture *self;
self = SHIMATTA_OPENGL_TEXTURE(obj);
switch (id) {
case PROP_TEXTURE_WRAP_S:
g_value_set_int(val, shimatta_opengl_texture_get_wrap_s(self));
break;
case PROP_TEXTURE_WRAP_T:
g_value_set_int(val, shimatta_opengl_texture_get_wrap_t(self));
break;
case PROP_TEXTURE_GEN_MIPMAP:
g_value_set_boolean(val, shimatta_opengl_texture_get_gen_mipmap(self));
break;
case PROP_TEXTURE_MAG_FILTER:
g_value_set_int(val, shimatta_opengl_texture_get_mag_filter(self));
break;
case PROP_TEXTURE_MIN_FILTER:
g_value_set_int(val, shimatta_opengl_texture_get_min_filter(self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec);
break;
}
}
static void shimatta_opengl_texture_set_property(GObject *obj, guint id, const GValue *value, GParamSpec *spec)
{
ShimattaOpenglTexture *self;
self = SHIMATTA_OPENGL_TEXTURE(obj);
switch (id) {
case PROP_TEXTURE_WRAP_S:
shimatta_opengl_texture_set_wrap_s(self, g_value_get_int(value));
break;
case PROP_TEXTURE_WRAP_T:
shimatta_opengl_texture_set_wrap_t(self, g_value_get_int(value));
break;
case PROP_TEXTURE_GEN_MIPMAP:
shimatta_opengl_texture_set_gen_mipmap(self, g_value_get_boolean(value));
break;
case PROP_TEXTURE_MAG_FILTER:
shimatta_opengl_texture_set_mag_filter(self, g_value_get_int(value));
break;
case PROP_TEXTURE_MIN_FILTER:
shimatta_opengl_texture_set_min_filter(self, g_value_get_int(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec);
break;
}
}
static GParamSpec *shimatta_opengl_texture_props[N_PROPS_TEXTURE] = {NULL, };
static void shimatta_opengl_texture_class_init(ShimattaOpenglTextureClass *klass)
{
GObjectClass *gclass;
gclass = G_OBJECT_CLASS(klass);
klass->use = use_default;
klass->use_in_slot = use_in_slot_default;
gclass->dispose = (void (*)(GObject *))shimatta_opengl_texture_dispose;
gclass->set_property = shimatta_opengl_texture_set_property;
gclass->get_property = shimatta_opengl_texture_get_property;
shimatta_opengl_texture_props[PROP_TEXTURE_WRAP_S] =
g_param_spec_int("wrap-s", "WRAP_S", "Wrapping in S",
0, INT_MAX, GL_REPEAT, G_PARAM_READWRITE);
shimatta_opengl_texture_props[PROP_TEXTURE_WRAP_T] =
g_param_spec_int("wrap-t", "WRAP_T", "Wrapping in T",
0, INT_MAX, GL_REPEAT, G_PARAM_READWRITE);
shimatta_opengl_texture_props[PROP_TEXTURE_MIN_FILTER] =
g_param_spec_int("min-filter", "MIN_FILTER", "Min filtering",
0, INT_MAX, GL_LINEAR, G_PARAM_READWRITE);
shimatta_opengl_texture_props[PROP_TEXTURE_MAG_FILTER] =
g_param_spec_int("max-filter", "MAG_FILTER", "Mag filtering",
0, INT_MAX, GL_LINEAR, G_PARAM_READWRITE);
shimatta_opengl_texture_props[PROP_TEXTURE_GEN_MIPMAP] =
g_param_spec_boolean("generate-mipmap", "gen-mipmap", "Generate Mipmap for texture",
TRUE, G_PARAM_READWRITE);
g_object_class_install_properties(gclass, N_PROPS_TEXTURE, shimatta_opengl_texture_props);
}
static void shimatta_opengl_texture_init(ShimattaOpenglTexture *self)
{
ShimattaOpenglTexturePrivate *priv;
priv = shimatta_opengl_texture_get_instance_private(self);
priv->texture_id = 0;
glGenTextures(1, &priv->texture_id);
glBindTexture(GL_TEXTURE_2D, priv->texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void shimatta_opengl_texture_use(ShimattaOpenglTexture *texture)
{
ShimattaOpenglTextureClass *klass;
g_return_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(texture));
klass = SHIMATTA_OPENGL_TEXTURE_GET_CLASS(texture);
klass->use(texture);
}
int shimatta_opengl_texture_use_in_slot(ShimattaOpenglTexture *texture, unsigned int slot)
{
ShimattaOpenglTextureClass *klass;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(texture), -1001);
klass = SHIMATTA_OPENGL_TEXTURE_GET_CLASS(texture);
return klass->use_in_slot(texture, slot);
}
ShimattaOpenglTexture *shimatta_opengl_texture_new()
{
return g_object_new(SHIMATTA_TYPE_OPENGL_TEXTURE, NULL);
}
int shimatta_opengl_texture_set_data(ShimattaOpenglTexture *texture, unsigned int width, unsigned int height,
GLenum format, void *buffer)
{
ShimattaOpenglTexturePrivate *priv;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(texture), -1001);
g_return_val_if_fail(!!buffer, -1005);
priv = shimatta_opengl_texture_get_instance_private(texture);
shimatta_opengl_texture_use(texture);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, buffer);
if (priv->generate_mipmap)
glGenerateMipmap(GL_TEXTURE_2D);
return 0;
}
int shimatta_opengl_texture_set_data_from_image(ShimattaOpenglTexture *texture, const char *path)
{
int ret = -1;
unsigned char *data;
int width, height;
int nr_channels;
GLenum format;
data = stbi_load(path, &width, &height, &nr_channels, 0);
if (!data)
goto go_out;
switch (nr_channels) {
case 1:
format = GL_RED;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
shimatta_opengl_texture_set_data(texture, width, height, format, data);
ret = 0;
stbi_image_free(data);
go_out:
return ret;
}
void shimatta_opengl_texture_set_wrap_s(ShimattaOpenglTexture *self, int wrap_s)
{
g_return_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self));
shimatta_opengl_texture_use(self);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s);
g_object_notify_by_pspec(G_OBJECT(self), shimatta_opengl_texture_props[PROP_TEXTURE_WRAP_S]);
}
void shimatta_opengl_texture_set_wrap_t(ShimattaOpenglTexture *self, int wrap_t)
{
g_return_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self));
shimatta_opengl_texture_use(self);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t);
g_object_notify_by_pspec(G_OBJECT(self), shimatta_opengl_texture_props[PROP_TEXTURE_WRAP_T]);
}
void shimatta_opengl_texture_set_min_filter(ShimattaOpenglTexture *self, int min_filter)
{
g_return_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self));
shimatta_opengl_texture_use(self);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
g_object_notify_by_pspec(G_OBJECT(self), shimatta_opengl_texture_props[PROP_TEXTURE_MIN_FILTER]);
}
void shimatta_opengl_texture_set_mag_filter(ShimattaOpenglTexture *self, int mag_filter)
{
g_return_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self));
shimatta_opengl_texture_use(self);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
g_object_notify_by_pspec(G_OBJECT(self), shimatta_opengl_texture_props[PROP_TEXTURE_MAG_FILTER]);
}
void shimatta_opengl_texture_set_gen_mipmap(ShimattaOpenglTexture *self, gboolean gen_mipmap)
{
ShimattaOpenglTexturePrivate *priv;
priv = shimatta_opengl_texture_get_instance_private(self);
g_return_if_fail(!!priv);
priv->generate_mipmap = gen_mipmap;
}
int shimatta_opengl_texture_get_wrap_s(ShimattaOpenglTexture *self)
{
GLint val;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self), -1);
shimatta_opengl_texture_use(self);
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &val);
return val;
}
int shimatta_opengl_texture_get_wrap_t(ShimattaOpenglTexture *self)
{
GLint val;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self), -1);
shimatta_opengl_texture_use(self);
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &val);
return val;
}
int shimatta_opengl_texture_get_mag_filter(ShimattaOpenglTexture *self)
{
GLint val;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self), -1);
shimatta_opengl_texture_use(self);
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &val);
return val;
}
int shimatta_opengl_texture_get_min_filter(ShimattaOpenglTexture *self)
{
GLint val;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self), -1);
shimatta_opengl_texture_use(self);
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &val);
return val;
}
gboolean shimatta_opengl_texture_get_gen_mipmap(ShimattaOpenglTexture *self)
{
ShimattaOpenglTexturePrivate *priv;
g_return_val_if_fail(SHIMATTA_IS_OPENGL_TEXTURE(self), -1);
priv = shimatta_opengl_texture_get_instance_private(self);
return priv->generate_mipmap;
}

2
stb/stb-implementation.c Normal file
View File

@@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>