texture support
This commit is contained in:
parent
d4a5fea127
commit
b17759b34a
6 changed files with 8087 additions and 14 deletions
5
examples/texture.glsl
Normal file
5
examples/texture.glsl
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||||
|
vec2 uv = fragCoord / iResolution;
|
||||||
|
// mixes two textures
|
||||||
|
fragColor = mix(texture(iChannel0, uv), texture(iChannel1, uv), 0.2);
|
||||||
|
}
|
||||||
|
|
@ -22,8 +22,6 @@
|
||||||
];
|
];
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
libGL
|
libGL
|
||||||
libpng
|
|
||||||
libjpeg
|
|
||||||
];
|
];
|
||||||
makeFlags = [ "PREFIX=$(out)" ];
|
makeFlags = [ "PREFIX=$(out)" ];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
42
glonkers.c
42
glonkers.c
|
|
@ -11,16 +11,28 @@
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
void print_help(FILE *channel, char *bin_path) {
|
void print_help(FILE *channel, char *bin_path) {
|
||||||
fprintf(channel, "Usage: %s [OPTION]... [PATH]\n", bin_path);
|
fprintf(channel, "Usage: %s [OPTION]... [PATH]\n", bin_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What is the argument parser currently reading?
|
||||||
|
enum list_state {
|
||||||
|
list_none,
|
||||||
|
list_ouptut,
|
||||||
|
list_texture,
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
char *shader_path = NULL;
|
char *shader_path = NULL;
|
||||||
int output_type = OUTPUT_WINDOW;
|
int output_type = OUTPUT_WINDOW;
|
||||||
bool currently_reading_output = false;
|
enum list_state list_state = list_none;
|
||||||
char **output_list = NULL;
|
char **output_list = NULL;
|
||||||
int output_count;
|
char **texture_list = NULL;
|
||||||
|
int output_count = 0;
|
||||||
|
int texture_count = 0;
|
||||||
// syntax: --window for a normal window or --layer for a wallpaper
|
// syntax: --window for a normal window or --layer for a wallpaper
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (strcmp("--help", argv[i]) == 0) {
|
if (strcmp("--help", argv[i]) == 0) {
|
||||||
|
|
@ -29,24 +41,36 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
else if (strcmp("--window", argv[i]) == 0) {
|
else if (strcmp("--window", argv[i]) == 0) {
|
||||||
output_type = OUTPUT_WINDOW;
|
output_type = OUTPUT_WINDOW;
|
||||||
currently_reading_output = false;
|
list_state = list_none;
|
||||||
}
|
}
|
||||||
else if (strcmp("--layer", argv[i]) == 0) {
|
else if (strcmp("--layer", argv[i]) == 0) {
|
||||||
output_type = OUTPUT_LAYER;
|
output_type = OUTPUT_LAYER;
|
||||||
currently_reading_output = false;
|
list_state = list_none;
|
||||||
}
|
}
|
||||||
else if (strcmp("--output", argv[i]) == 0) {
|
else if (strcmp("--output", argv[i]) == 0) {
|
||||||
output_count = 0;
|
output_count = 0;
|
||||||
output_list = &argv[i + 1];
|
output_list = &argv[i + 1];
|
||||||
currently_reading_output = true;
|
list_state = list_ouptut;
|
||||||
|
}
|
||||||
|
else if (strcmp("--texture", argv[i]) == 0) {
|
||||||
|
texture_count = 0;
|
||||||
|
texture_list = &argv[i + 1];
|
||||||
|
list_state = list_texture;
|
||||||
}
|
}
|
||||||
else if (strcmp("--", argv[i]) == 0) {
|
else if (strcmp("--", argv[i]) == 0) {
|
||||||
currently_reading_output = false;
|
list_state = list_none;
|
||||||
}
|
}
|
||||||
else if (currently_reading_output) {
|
else if (list_state == list_ouptut) {
|
||||||
output_count++;
|
output_count++;
|
||||||
}
|
}
|
||||||
else if (!currently_reading_output) {
|
else if (list_state == list_texture) {
|
||||||
|
texture_count++;
|
||||||
|
if (texture_count > 4) {
|
||||||
|
fprintf(stderr, "maximum number of textures is 4\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (list_state == list_none) {
|
||||||
// path to fragment shader
|
// path to fragment shader
|
||||||
if (shader_path != NULL) {
|
if (shader_path != NULL) {
|
||||||
fprintf(stderr, "Tried supplying '%s' as a shader file while one has already been selected.\n", argv[i]);
|
fprintf(stderr, "Tried supplying '%s' as a shader file while one has already been selected.\n", argv[i]);
|
||||||
|
|
@ -74,7 +98,7 @@ int main(int argc, char *argv[]) {
|
||||||
int height = event.data.draw.height;
|
int height = event.data.draw.height;
|
||||||
double time = event.data.draw.time / 1000.0;
|
double time = event.data.draw.time / 1000.0;
|
||||||
if (!renderer_initialized) {
|
if (!renderer_initialized) {
|
||||||
renderer = new_renderer();
|
renderer = new_renderer(texture_list, texture_count);
|
||||||
renderer_initialized = true;
|
renderer_initialized = true;
|
||||||
}
|
}
|
||||||
render(&renderer, width, height, time, shader_path, 0);
|
render(&renderer, width, height, time, shader_path, 0);
|
||||||
|
|
|
||||||
60
renderer.c
60
renderer.c
|
|
@ -3,8 +3,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <libpng16/png.h>
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
|
|
||||||
/// returns 0 if failed.
|
/// returns 0 if failed.
|
||||||
|
|
@ -48,6 +48,10 @@ const char *fragment_header_src =
|
||||||
"uniform vec2 iResolution;\n"
|
"uniform vec2 iResolution;\n"
|
||||||
"uniform float iTime;\n"
|
"uniform float iTime;\n"
|
||||||
"uniform int iFrame;\n"
|
"uniform int iFrame;\n"
|
||||||
|
"uniform sampler2D iChannel0;\n"
|
||||||
|
"uniform sampler2D iChannel1;\n"
|
||||||
|
"uniform sampler2D iChannel2;\n"
|
||||||
|
"uniform sampler2D iChannel3;\n"
|
||||||
"void mainImage(out vec4 fragColor, in vec2 fragCoord);\n"
|
"void mainImage(out vec4 fragColor, in vec2 fragCoord);\n"
|
||||||
"void main() {\n"
|
"void main() {\n"
|
||||||
" mainImage(color, gl_FragCoord.xy);\n"
|
" mainImage(color, gl_FragCoord.xy);\n"
|
||||||
|
|
@ -121,7 +125,7 @@ GLuint load_shader(const char *path) {
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer new_renderer() {
|
Renderer new_renderer(char **textures, int texture_count) {
|
||||||
const char *version_str = (const char *)glGetString(GL_VERSION);
|
const char *version_str = (const char *)glGetString(GL_VERSION);
|
||||||
const char *renderer_str = (const char *)glGetString(GL_RENDERER);
|
const char *renderer_str = (const char *)glGetString(GL_RENDERER);
|
||||||
|
|
||||||
|
|
@ -159,6 +163,28 @@ Renderer new_renderer() {
|
||||||
);
|
);
|
||||||
|
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
|
renderer.texture_count = texture_count;
|
||||||
|
|
||||||
|
// textures
|
||||||
|
for (int i = 0; i < texture_count; i++) {
|
||||||
|
glGenTextures(1, &renderer.textures[i]);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, renderer.textures[i]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
int width, height, nr_channels;
|
||||||
|
unsigned char *data = stbi_load(textures[i], &width, &height, &nr_channels, 0);
|
||||||
|
if (data) {
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "failed to load texture %d\n", i);
|
||||||
|
}
|
||||||
|
stbi_image_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
renderer.shader_path = "";
|
renderer.shader_path = "";
|
||||||
renderer.shader = 0;
|
renderer.shader = 0;
|
||||||
renderer.vao = vao;
|
renderer.vao = vao;
|
||||||
|
|
@ -195,6 +221,36 @@ void render(Renderer *state, int w, int h, double time, char *shader_path, int r
|
||||||
// Shader parameters.
|
// Shader parameters.
|
||||||
glUseProgram(state->shader);
|
glUseProgram(state->shader);
|
||||||
|
|
||||||
|
// Bind texture
|
||||||
|
for (int i = 0; i < state->texture_count; i++) {
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->textures[i]);
|
||||||
|
glUniform1i(glGetUniformLocation(state->shader, "iChannel0"), i);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->textures[i]);
|
||||||
|
glUniform1i(glGetUniformLocation(state->shader, "iChannel1"), i);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->textures[i]);
|
||||||
|
glUniform1i(glGetUniformLocation(state->shader, "iChannel2"), i);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->textures[i]);
|
||||||
|
glUniform1i(glGetUniformLocation(state->shader, "iChannel3"), i);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "texture index > 3 not allowed\n");
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int uniform_iResolution = glGetUniformLocation(state->shader, "iResolution");
|
int uniform_iResolution = glGetUniformLocation(state->shader, "iResolution");
|
||||||
glUniform2f(uniform_iResolution, w, h);
|
glUniform2f(uniform_iResolution, w, h);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ typedef struct Renderer {
|
||||||
/// The currently rendered frame.
|
/// The currently rendered frame.
|
||||||
unsigned int frame_nr;
|
unsigned int frame_nr;
|
||||||
struct stat shader_file_modified;
|
struct stat shader_file_modified;
|
||||||
|
unsigned int textures[4];
|
||||||
|
int texture_count;
|
||||||
} Renderer;
|
} Renderer;
|
||||||
|
|
||||||
Renderer new_renderer();
|
Renderer new_renderer(char **textures, int texture_count);
|
||||||
void render(Renderer *renderer, int w, int h, double time, char *shader_path, int reload_shader);
|
void render(Renderer *renderer, int w, int h, double time, char *shader_path, int reload_shader);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
7988
stb_image.h
Normal file
7988
stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue