Skip to content

Instantly share code, notes, and snippets.

@clooth
Created September 2, 2012 14:10
Show Gist options
  • Save clooth/3599319 to your computer and use it in GitHub Desktop.
Save clooth/3599319 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <GL/glew.h>
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
#include <math.h>
#include <stdio.h>
#include "util.h"
static struct {
GLuint vertex_buffer, element_buffer;
GLuint textures[2];
GLuint vertex_shader, fragment_shader, program;
struct {
GLint fade_factor;
GLint textures[2];
} uniforms;
struct {
GLint position;
} attributes;
GLfloat fade_factor;
} g_resources;
static GLuint make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size)
{
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(target, buffer);
glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
return buffer;
}
static GLuint make_texture(const char *filename)
{
GLuint texture;
int width, height;
void *pixels = read_tga(filename, &width, &height);
if (!pixels)
return 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// Linear blending for the texture, for smoother scaling
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Allocate the texture
glTexImage2D(
GL_TEXTURE_2D, 0, /* target, level of detail */
GL_RGB8, /* interal format */
width, height, 0, /* width, height, border */
GL_BGR, GL_UNSIGNED_BYTE, /* external format */
pixels /* pixels! */
);
free(pixels);
return texture;
}
static void show_info_log(GLuint object,
PFNGLGETSHADERIVPROC glGet__iv,
PFNGLGETSHADERINFOLOGPROC glGet__InfoLog)
{
GLint log_length;
char *log;
glGet__iv(object, GL_INFO_LOG_LENGTH, &log_length);
log = malloc(log_length);
glGet__InfoLog(object, log_length, NULL, log);
fprintf(stderr, "%s", log);
free(log);
}
static GLuint make_shader(GLenum type, const char *filename)
{
GLint length;
GLchar *source = file_contents(filename, &length);
GLuint shader;
GLint shader_ok;
if (!source)
return 0;
shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar**)&source, &length);
free(source);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
// Failed to compile shader file
if (!shader_ok) {
fprintf(stderr, "Failed to compile %s\n", filename);
show_info_log(shader, glGetShaderiv, glGetShaderInfoLog);
glDeleteShader(shader);
return 0;
}
return shader;
}
static GLuint make_program(GLuint vertex_shader, GLuint fragment_shader)
{
GLint program_ok;
GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
if (!program_ok) {
fprintf(stderr, "Failed to link shader program:\n");
show_info_log(program, glGetProgramiv, glGetProgramInfoLog);
glDeleteProgram(program);
return 0;
}
return program;
}
/*
* Data used to seed our vertex array and element array buffers:
*/
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f
};
static const GLushort g_element_buffer_data[] = { 0, 1, 2, 3 };
static int make_resources(void) {
/* Make buffers */
g_resources.vertex_buffer = make_buffer(
GL_ARRAY_BUFFER,
g_vertex_buffer_data,
sizeof(g_vertex_buffer_data)
);
g_resources.element_buffer = make_buffer(
GL_ELEMENT_ARRAY_BUFFER,
g_element_buffer_data,
sizeof(g_element_buffer_data)
);
/* Make textures */
g_resources.textures[0] = make_texture("hello1.tga");
g_resources.textures[1] = make_texture("hello2.tga");
if (g_resources.textures[0] == 0 || g_resources.textures[1] == 0)
return 0;
/* Make shaders */
g_resources.vertex_shader = make_shader(
GL_VERTEX_SHADER,
"hello-gl.v.glsl"
);
if (g_resources.vertex_shader == 0)
return 0;
g_resources.fragment_shader = make_shader(
GL_FRAGMENT_SHADER,
"hello-gl.f.glsl"
);
if (g_resources.fragment_shader == 0)
return 0;
g_resources.program = make_program(
g_resources.vertex_shader,
g_resources.fragment_shader
);
if (g_resources.program == 0)
return 0;
// Looking up shader variable locations
g_resources.uniforms.fade_factor =
glGetUniformLocation(g_resources.program, "fade_factor");
g_resources.uniforms.textures[0] =
glGetUniformLocation(g_resources.program, "textures[0]");
g_resources.uniforms.textures[1] =
glGetUniformLocation(g_resources.program, "textures[1]");
g_resources.attributes.position =
glGetAttribLocation(g_resources.program, "position");
return 1;
}
static void update_fade_factor(void) {
int milliseconds = glutGet(GLUT_ELAPSED_TIME);
g_resources.fade_factor = sinf((float)milliseconds * 0.001f) * 0.5f + 0.5f;
glutPostRedisplay();
}
static void render(void) {
glUseProgram(g_resources.program);
glUniform1f(g_resources.uniforms.fade_factor, g_resources.fade_factor);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, g_resources.textures[0]);
glUniform1i(g_resources.uniforms.textures[0], 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, g_resources.textures[1]);
glUniform1i(g_resources.uniforms.textures[1], 1);
glBindBuffer(GL_ARRAY_BUFFER, g_resources.vertex_buffer);
glVertexAttribPointer(
g_resources.attributes.position, /* attribute */
2, /* size */
GL_FLOAT, /* type */
GL_FALSE, /* normalized? */
sizeof(GLfloat)*2, /* stride */
(void*)0 /* array buffer offset */
);
glEnableVertexAttribArray(g_resources.attributes.position);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_resources.element_buffer);
glDrawElements(
GL_TRIANGLE_STRIP, /* mode */
4, /* count */
GL_UNSIGNED_SHORT, /* type */
(void*)0 /* element array buffer offset */
);
glDisableVertexAttribArray(g_resources.attributes.position);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(400, 300);
glutCreateWindow("Hello World");
glutDisplayFunc(&render);
glutIdleFunc(&update_fade_factor);
glewInit();
// If we don't have OpenGL 2.0, we can't do anything.
if (!GLEW_VERSION_2_0) {
fprintf(stderr, "OpenGL 2.0 not available\n");
return 1;
}
// Attempt to create resources
if (!make_resources()) {
fprintf(stderr, "Failed to load resources\n");
return 1;
}
glutMainLoop();
return 0;
}
@DavidBuchanan314
Copy link

DavidBuchanan314 commented Oct 11, 2023

Where can I find the corresponding util.h?

ah, found it: https://github.com/jckarter/hello-gl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment