Skip to content

Instantly share code, notes, and snippets.

@kor01
Last active September 7, 2018 12:03
Show Gist options
  • Save kor01/a3bfadd68d1b41c956ec09313a3786bb to your computer and use it in GitHub Desktop.
Save kor01/a3bfadd68d1b41c956ec09313a3786bb to your computer and use it in GitHub Desktop.
[opengl hello world] openGL stuffs #openGL
/*
update the backend state during rendering idle
*/
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();
}
int main() {
/*stuffs do to prepare things*/
/*update the internal state machine during rendering idle*/
glutIdleFunc(&update_fade_factor);
}
/*
global uniforms idx are extracted through API glGetUnformLocation
the extracted uniforms are later used by render function to perform resource copy
*/
void extract_uniform(){
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");
}
# cmake for opengl projects
cmake_minimum_required(VERSION 3.12)
project(opengl_stuffs)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenGL)
find_package(GLUT)
find_package(GLEW)
add_executable(app main.cpp)
include_directories( ${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} )
target_link_libraries(app ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${GLEW_LIBRARY})
#version 120
/*uniform is global immutable features*/
uniform float fade_factor;
uniform sampler2D textures[2];
/*the value that is task specific*/
varying vec2 texcoord;
void main() {
/*return value of the fragment shader*/
gl_FragColor = mix(
texture2D(textures[0], texcoord),
texture2D(textures[1], texcoord), fade_factor);
}
/*
global resource is one global variable storing:
buffers: vertex buffer and fragment buffer
textures: static resource for texture shading (vertex and fragments)
programes: compiled opengl shader program (the instruction packet to send for rendering device)
attributes: vertex or fragments attributes and global variables in shader program
*/
static struct {
// buffers
GLuint vertex_buffer, element_buffer;
//textures
GLuint textures[2];
/* fields for shader objects ... */
// shader
GLuint vertex_shader, fragment_shader, program;
//uniforms to broadcast for all vertices and fragments
struct {
GLint fade_factor;
GLint textures[2];
} uniforms;
// attributes of vertices
struct {
GLint position;
} attributes;
GLfloat fade_factor; // for assigning
} g_resources;
/* headers */
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
/* GLUT the GL utility toolkit, x-platform interface
/* GLEW the GL extensions wrangler, interface different versions of GL and its extensions
/* the entrance of the graphic*/
int main(int argc, char** argv) {
// init global resource
glutInit(&argc, argv);
// display mode, double buffer for extra pixel information
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
// all cgs are targeted at specific window
glutInitWindowSize(400, 300);
glutCreateWindow("Hello World");
// setup render callback and state update callback
glutDisplayFunc(&render);
glutIdleFunc(&update_fade_factor);
glewInit();
// global resource allocation
if (!make_resources()) {
fprintf(stderr, "Failed to load resources\n");
return 1;
}
// rendering and state update main loop
glutMainLoop();
return 0;
//return 0;
}
/*
set the shader program
refresh uniforms
refresh texture through state machine api
refresh texture into global uniforms
refresh vertex list
refresh vertex attributes
(bind means set the current variable under consideration, like variable scope)
*/
static void render() {
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 */
);
/*one of the clean up api call*/
glDisableVertexAttribArray(g_resources.attributes.position);
glutSwapBuffers();
}
/*
GLenum is a type indicator (fragment shader or vertex shader)
declare a shader -> set the source file -> call compilation -> check compilation state
*/
static GLuint make_shader(GLenum type, const char* filename) {
GLint length;
GLchar* source = (GLchar*)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);
if (!shader_ok) {
fprintf(stderr, "Failed to compile %s:\n", filename);
show_info_log(shader, glGetShaderiv, glGetShaderInfoLog);
glDeleteShader(shader);
return 0;
}
return shader;
}
/*
multiple compiled shader unit have inter dependencies (the above example the texcoord)
linking shaders resolves interdependencies
linked into a single program =
*/
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;
}
// global allocation
/*
allocations through global state machine configuration
glGenTextures declare one variable as a texture
glbindTexture set current texture under configuration (like a context manager)
glTexParameteri configure the current texture interpolation configuration
glTexImage2D set hte image for current
*/
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);
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);
glTexImage2D(
GL_TEXTURE_2D, 0, /* target, level of detail */
GL_RGB8, /* internal format */
width, height, 0, /* width, height, border */
GL_BGR, GL_UNSIGNED_BYTE, /* external format, type */
pixels /* pixels */);
free(pixels);
return texture;
}
#version 120
/*vertex attributes*/
attribute vec2 position;
/*one of the return value (can be used by another shader)*/
/*any return value will be interpolated by rasterizer*/
varying vec2 texcoord;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
texcoord = position * vec2(0.5) + vec2(0.5);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment