space box

This commit is contained in:
Frank DeMarco 2018-11-26 03:45:33 -05:00
parent 7e6dc58374
commit 57ddb3dca0
4 changed files with 200 additions and 215 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ Main.app/
main
glm/
sdl2-gfx/
screen.png

379
main.cpp
View File

@ -1,5 +1,7 @@
#include <stdio.h>
#include <math.h>
#include <vector>
#include <array>
#include <SDL.h>
#include <SDL_image.h>
@ -40,12 +42,67 @@ char* file_to_buf(const char *path)
return buf;
}
GLuint load_shader(const char* path, GLenum type)
{
char *source = file_to_buf(path);
GLuint shader = glCreateShader(type);
int is_compiled, max_length;
glShaderSource(shader, 1, (const GLchar**) &source, 0);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);
if(is_compiled == 0)
{
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length);
char *log = (char *) malloc(max_length);
glGetShaderInfoLog(shader, max_length, &max_length, log);
fprintf(stderr, "%s -- shader compilation failed %s\n", path, log);
free(log);
return -1;
}
return shader;
}
int link_shader(GLuint program)
{
glLinkProgram(program);
int is_linked, max_length;
glGetProgramiv(program, GL_LINK_STATUS, (int *) &is_linked);
if(is_linked == 0)
{
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
char *log = (char *) malloc(max_length);
glGetProgramInfoLog(program, max_length, &max_length, log);
fprintf(stderr, "shader program %i linking failed %s\n", program, log);
free(log);
return -1;
}
return 0;
}
void capture_screen(SDL_Window *window)
{
int w, h;
SDL_GetWindowSize(window, &w, &h);
unsigned char *pixels = (unsigned char *) malloc(24 * w * h);
printf("allocated %i bytes\n", 24 * w * h);
glReadPixels(0, 0, w, h, GL_BGR, GL_UNSIGNED_BYTE, pixels);
printf("read data into pixels memory\n");
SDL_Surface *surface = zoomSurface(
SDL_CreateRGBSurfaceFrom(pixels, w, h, 24, 3 * w,
0xff0000, 0x00ff00, 0x0000ff, 0), 1, -1, SMOOTHING_OFF);
printf("created RGB surface from pixels memory\n");
IMG_SavePNG(surface, "screen.png");
printf("saved png to screen.png\n");
SDL_FreeSurface(surface);
free(pixels);
}
int main(int argc, char *argv[])
{
SDL_version version;
SDL_GetVersion(&version);
printf("SDL %d.%d.%d\n", version.major, version.minor, version.patch);
fprintf(stderr, "Error test\n");
fprintf(stderr, "stderr test message\n");
SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
@ -89,66 +146,92 @@ int main(int argc, char *argv[])
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
printf("OpenGL %s\n", glGetString(GL_VERSION));
SDL_Event event;
int done = 0, x = 0;
int done = 0;
float r = 0.0;
int i;
// Create handles for our Vertex Array Object and two Vertex Buffer Objects
GLuint vao, vbo;
int IsCompiled_VS, IsCompiled_FS;
int IsLinked;
int maxLength;
char *vertexInfoLog;
char *fragmentInfoLog;
char *shaderProgramInfoLog;
// We're going to create a simple diamond made from lines
GLfloat diamond[4][2] = {
{ 0.0, 1.0 },
{ 1.0, 0.0 },
{ 0.0, -1.0 },
{ -1.0, 0.0 } };
// GLfloat diamond[4][2] = {
// { 0.0, 1.0 },
// { 1.0, 0.0 },
// { 0.0, -1.0 },
// { -1.0, 0.0 } };
const GLfloat diamond_colors[4][3] = {
{ 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 },
{ 1.0, 1.0, 1.0 } };
// const GLfloat diamond_colors[4][3] = {
// { 1.0, 0.0, 0.0 },
// { 0.0, 1.0, 0.0 },
// { 0.0, 0.0, 1.0 },
// { 1.0, 1.0, 1.0 } };
GLfloat cube[36][3] = {
{1, 1, 1}, {-1, 1, 1}, {-1,-1, 1}, // v0-v1-v2 (front)
{-1,-1, 1}, {1,-1, 1}, {1, 1, 1}, // v2-v3-v0
{1, 1, 1}, {1,-1, 1}, {1,-1,-1}, // v0-v3-v4 (right)
{1,-1,-1}, {1, 1,-1}, {1, 1, 1}, // v4-v5-v0
{1, 1, 1}, {1, 1,-1}, {-1, 1,-1}, // v0-v5-v6 (top)
{-1, 1,-1}, {-1, 1, 1}, {1, 1, 1}, // v6-v1-v0
{-1, 1, 1}, {-1, 1,-1}, {-1,-1,-1}, // v1-v6-v7 (left)
{-1,-1,-1}, {-1,-1, 1}, {-1, 1, 1}, // v7-v2-v1
/*
v0-v1-v2 (front)
v2-v3-v0
v0-v3-v4 (right)
v4-v5-v0
v0-v5-v6 (top)
v6-v1-v0
v1-v6-v7 (left)
v7-v2-v1
v7-v4-v3 (bottom)
v3-v2-v7
v4-v7-v6 (back)
v6-v5-v4
*/
std::array<std::array<GLfloat, 3>, 36> cube = {{
{1, 1, 1}, {-1, 1, 1}, {-1,-1, 1},
{-1,-1, 1}, {1,-1, 1}, {1, 1, 1},
{-1,-1,-1}, {1,-1,-1}, {1,-1, 1}, // v7-v4-v3 (bottom)
{1,-1, 1}, {-1,-1, 1}, {-1,-1,-1}, // v3-v2-v7
{1, 1, 1}, {1,-1, 1}, {1,-1,-1},
{1,-1,-1}, {1, 1,-1}, {1, 1, 1},
{1,-1,-1}, {-1,-1,-1}, {-1, 1,-1}, // v4-v7-v6 (back)
{-1, 1,-1}, {1, 1,-1}, {1,-1,-1} }; // v6-v5-v4
{1, 1, 1}, {1, 1,-1}, {-1, 1,-1},
{-1, 1,-1}, {-1, 1, 1}, {1, 1, 1},
GLfloat cube_colors[36][3] = {
{1, 0, 0}, {1, 0, 0}, {1, 0, 0}, // v0-v1-v2 (front)
{1, 0, 0}, {1, 0, 0}, {1, 0, 0}, // v2-v3-v0
{-1, 1, 1}, {-1, 1,-1}, {-1,-1,-1},
{-1,-1,-1}, {-1,-1, 1}, {-1, 1, 1},
{0, 1, 0}, {0, 1, 0}, {0, 1, 0}, // v0-v3-v4 (right)
{0, 1, 0}, {0, 1, 0}, {0, 1, 0}, // v4-v5-v0
{-1,-1,-1}, {1,-1,-1}, {1,-1, 1},
{1,-1, 1}, {-1,-1, 1}, {-1,-1,-1},
{0, 0, 1}, {0, 0, 1}, {0, 0, 1}, // v0-v5-v6 (top)
{0, 0, 1}, {0, 0, 1}, {0, 0, 1}, // v6-v1-v0
{1,-1,-1}, {-1,-1,-1}, {-1, 1,-1},
{-1, 1,-1}, {1, 1,-1}, {1,-1,-1}
}};
// GLfloat cube_colors[36][3] = {
// {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
// {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, // v1-v6-v7 (left)
{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, // v7-v2-v1
// {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
// {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
{0, 1, 1}, {0, 1, 1}, {0, 1, 1}, // v7-v4-v3 (bottom)
{0, 1, 1}, {0, 1, 1}, {0, 1, 1}, // v3-v2-v7
// {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
// {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
{1, 0, 1}, {1, 0, 1}, {1, 0, 1}, // v4-v7-v6 (back)
{1, 0, 1}, {1, 0, 1}, {1, 0, 1} }; // v6-v5-v4
// {1, 1, 0}, {1, 1, 0}, {1, 1, 0},
// {1, 1, 0}, {1, 1, 0}, {1, 1, 0},
// {0, 1, 1}, {0, 1, 1}, {0, 1, 1},
// {0, 1, 1}, {0, 1, 1}, {0, 1, 1},
// {1, 0, 1}, {1, 0, 1}, {1, 0, 1},
// {1, 0, 1}, {1, 0, 1}, {1, 0, 1}
// };
std::array<std::array<GLfloat, 3>, 36> background_vertices = {
{
{-1, 1, 0}, {1, 1, 0}, {-1, -1, 0},
{1, 1, 0}, {1, -1, 0}, {-1, -1, 0}
}};
GLfloat background_colors[40][3] = {
{.2, .6, .8}, {.2, .6, .8}, {1, 1, 0},
{.2, .6, .8}, {1, 1, 0}, {1, 1, 0}
};
GLuint background_colors_buffer;
glGenBuffers(1, &background_colors_buffer);
std::vector<std::array<GLfloat, 3>> vertices;
vertices.reserve(cube.size() + background_vertices.size());
vertices.insert(vertices.begin(), cube.begin(), cube.end());
vertices.insert(vertices.end(), background_vertices.begin(), background_vertices.end());
glm::mat4 projection = glm::perspective(glm::radians(45.0f),
(float) sw / (float) sh, 0.1f, 100.0f);
glm::mat4 view = glm::lookAt(
@ -158,21 +241,11 @@ int main(int argc, char *argv[])
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 mvp;
// These pointers will receive the contents of our shader source code files
GLchar *vertexsource, *fragmentsource;
// These are handles used to reference the shaders
GLuint vertexshader, fragmentshader;
// This is a handle to the shader program
GLuint shaderprogram;
// int q = SDL_GL_BindTexture(texture, NULL, NULL);
// printf("bind texture returns %i\n", q);
SDL_Surface *surface = rotateSurface90Degrees(
IMG_Load("tile.png"), 2);
printf("bytes per pixel %i\n", surface->format->BytesPerPixel);
GLuint t_id;
glCreateTextures(GL_TEXTURE_2D, 1, &t_id);
glBindTexture(GL_TEXTURE_2D, t_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, surface->pixels);
@ -192,7 +265,14 @@ int main(int argc, char *argv[])
0, 0, 1, 0, 1, 1,
1, 1, 0, 1, 0, 0};
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glGenBuffers(1, &uvbuffer);
GLuint fake_texture_id;
unsigned char fake_texture_color[4] = {255, 255, 255, 255};
glCreateTextures(GL_TEXTURE_2D, 1, &fake_texture_id);
glBindTexture(GL_TEXTURE_2D, fake_texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
fake_texture_color);
// Allocate and assign a Vertex Array Object to our handle
glGenVertexArrays(1, &vao);
@ -200,167 +280,72 @@ int main(int argc, char *argv[])
// Bind our Vertex Array Object as the current used object
glBindVertexArray(vao);
// Allocate and assign two Vertex Buffer Objects to our handle
// Allocate and assign one Vertex Buffer Objects to our handle
glGenBuffers(1, &vbo);
// Bind our first VBO as being the active buffer and storing vertex coordinates
// Bind vbo as being the active buffer and storing vertex coordinates
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Copy the vertex data from diamond to our buffer
// 8 * sizeof(GLfloat) is the size of the diamond array
glBufferData(GL_ARRAY_BUFFER, 108 * sizeof(GLfloat), cube,
// Copy vertex data into buffer
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat) * 3, &vertices.front(),
GL_STATIC_DRAW);
// Specify that our coordinate data is going into attribute
// index 0, and contains two floats per vertex
// index 0, and contains three floats per vertex
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Enable attribute index 0 as being used
glEnableVertexAttribArray(0);
// Bind our second VBO as being the active buffer and storing vertex colors
// glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
// Bind our second VBO as being the active buffer and storing texture coordinates
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
// Copy the color data from colors to our buffer
// 12 * sizeof(GLfloat) is the size of the colors array
// glBufferData(GL_ARRAY_BUFFER, 108 * sizeof(GLfloat),
// cube_colors, GL_STATIC_DRAW);
// Copy the data from cube_uv to our buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_uv), cube_uv, GL_STATIC_DRAW);
// Specify that our color data is going into attribute index 1
// and contains three floats per vertex
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Specify that our texture coordinate data is going into attribute index 1
// and contains two floats per vertex
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
// Enable attribute index 1
glEnableVertexAttribArray(1);
// Read our shaders into the appropriate buffers
vertexsource = file_to_buf("triangle.vert");
fragmentsource = file_to_buf("triangle.frag");
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, background_colors_buffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat) * 3, 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,
(vertices.size() - background_vertices.size()) * sizeof(GLfloat) * 3,
background_vertices.size() * sizeof(GLfloat) * 3, background_colors);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Create an empty vertex shader handle
vertexshader = glCreateShader(GL_VERTEX_SHADER);
GLuint vertex_shader = load_shader("triangle.vert", GL_VERTEX_SHADER);
GLuint fragment_shader = load_shader("triangle.frag", GL_FRAGMENT_SHADER);
GLuint flat_shader = load_shader("flat.vert", GL_VERTEX_SHADER);
// Send the vertex shader source code to GL
// Note that the source code is NULL character terminated
// GL will automatically detect that therefore the length
// info can be 0 in this case (the last parameter)
glShaderSource(vertexshader, 1, (const GLchar**) &vertexsource, 0);
GLuint world_program = glCreateProgram();
glAttachShader(world_program, vertex_shader);
glAttachShader(world_program, fragment_shader);
glBindAttribLocation(world_program, 0, "in_Position");
glBindAttribLocation(world_program, 1, "vertexUV");
glBindAttribLocation(world_program, 2, "in_Color");
link_shader(world_program);
// Compile the vertex shader
glCompileShader(vertexshader);
GLuint flat_program = glCreateProgram();
glAttachShader(flat_program, flat_shader);
glAttachShader(flat_program, fragment_shader);
glBindAttribLocation(flat_program, 0, "in_Position");
glBindAttribLocation(flat_program, 1, "vertexUV");
glBindAttribLocation(flat_program, 2, "in_Color");
link_shader(flat_program);
glGetShaderiv(vertexshader, GL_COMPILE_STATUS, &IsCompiled_VS);
if(IsCompiled_VS == 0)
{
glGetShaderiv(vertexshader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
vertexInfoLog = (char *) malloc(maxLength);
glGetShaderInfoLog(vertexshader, maxLength, &maxLength, vertexInfoLog);
// Handle the error in an appropriate way
// such as displaying a message or writing to a log file.
fprintf(stderr, "vertex shader compilation failed %s\n", vertexInfoLog);
free(vertexInfoLog);
return 0;
}
// Create an empty fragment shader handle
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
// Send the fragment shader source code to GL
// Note that the source code is NULL character terminated
// GL will automatically detect that therefore the length info
// can be 0 in this case (the last parameter)
glShaderSource(fragmentshader, 1, (const GLchar**) &fragmentsource, 0);
// Compile the fragment shader
glCompileShader(fragmentshader);
glGetShaderiv(fragmentshader, GL_COMPILE_STATUS, &IsCompiled_FS);
if(IsCompiled_FS == 0)
{
glGetShaderiv(fragmentshader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
fragmentInfoLog = (char *)malloc(maxLength);
glGetShaderInfoLog(fragmentshader, maxLength, &maxLength, fragmentInfoLog);
// Handle the error in an appropriate way such as displaying a
// message or writing to a log file
fprintf(stderr, "fragment shader compilation failed %s\n", fragmentInfoLog);
free(fragmentInfoLog);
return 0;
}
// If we reached this point it means the vertex and fragment
// shaders compiled and are syntax error free
// We must link them together to make a GL shader program
// GL shader programs are monolithic. It is a single piece made of
// 1 vertex shader and 1 fragment shader
// Assign our program handle a "name"
shaderprogram = glCreateProgram();
// Attach our shaders to our program
glAttachShader(shaderprogram, vertexshader);
glAttachShader(shaderprogram, fragmentshader);
// Bind attribute index 0 (coordinates) to in_Position and attribute
// index 1 (color) to in_Color
// Attribute locations must be setup before calling glLinkProgram
glBindAttribLocation(shaderprogram, 0, "in_Position");
// glBindAttribLocation(shaderprogram, 1, "in_Color");
glBindAttribLocation(shaderprogram, 1, "vertexUV");
// Link our program
// At this stage, the vertex and fragment programs are inspected,
// optimized and a binary code is generated for the shader
// The binary code is uploaded to the GPU, if there is no error
glLinkProgram(shaderprogram);
GLuint m_id = glGetUniformLocation(shaderprogram, "MVP");
GLuint t_uniform_id = glGetUniformLocation(shaderprogram, "myTextureSampler");
GLuint m_id = glGetUniformLocation(world_program, "MVP");
GLuint t_uniform_id = glGetUniformLocation(world_program, "myTextureSampler");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, t_id);
glUniform1i(t_uniform_id, 0);
// Again, we must check and make sure that it linked
// If it fails, it would mean either there is a mismatch between the vertex
// and fragment shaders. It might be that you have surpassed your
// GPU's abilities. Perhaps too many ALU operations or
// too many texel fetch instructions or too many interpolators or
// dynamic loops
glGetProgramiv(shaderprogram, GL_LINK_STATUS, (int *) &IsLinked);
if(IsLinked == 0)
{
// Noticed that glGetProgramiv is used to get the length for
// a shader program, not glGetShaderiv
glGetProgramiv(shaderprogram, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
shaderProgramInfoLog = (char *) malloc(maxLength);
// Notice that glGetProgramInfoLog, not glGetShaderInfoLog
glGetProgramInfoLog(shaderprogram, maxLength, &maxLength,
shaderProgramInfoLog);
// Handle the error in an appropriate way such as displaying a
// message or writing to a log file
fprintf(stderr, "shader linking failed %s\n", shaderProgramInfoLog);
free(shaderProgramInfoLog);
return 0;
}
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Load the shader into the rendering pipeline
glUseProgram(shaderprogram);
while (!done)
{
while (SDL_PollEvent(&event))
@ -369,6 +354,10 @@ int main(int argc, char *argv[])
{
done = 1;
}
else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_F9)
{
capture_screen(window);
}
}
// glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
// glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), diamond, GL_STATIC_DRAW);
@ -376,9 +365,21 @@ int main(int argc, char *argv[])
glClearColor(.7, .7, .5, 1);
r += .025;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glUseProgram(flat_program);
glBindTexture(GL_TEXTURE_2D, fake_texture_id);
glDisableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 36, 6);
model = glm::rotate(model, .01f, glm::vec3(0.0f, 1.0f, 0.0f));
mvp = projection * view * model;
glEnable(GL_DEPTH_TEST);
glUseProgram(world_program);
glUniformMatrix4fv(m_id, 1, GL_FALSE, &mvp[0][0]);
glBindTexture(GL_TEXTURE_2D, t_id);
glEnableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glVertexAttrib3f(2, 1, 1, 1);
glDrawArrays(GL_TRIANGLES, 0, 36);
//glFlush();
//SDL_Rect rect = {x++, 0, 240, 160};

View File

@ -1,16 +1,10 @@
#version 130
// It was expressed that some drivers required this next line to function properly
precision highp float;
// in vec3 ex_Color;
in vec4 ex_Color;
in vec2 UV;
// out vec4 FragColor;
out vec4 color;
uniform sampler2D myTextureSampler;
void main(void) {
// Pass through our original color with full opacity.
// FragColor = vec4(ex_Color,1.0);
color = texture(myTextureSampler, UV);
void main(void)
{
gl_FragColor = texture(myTextureSampler, UV) * ex_Color;
}

View File

@ -1,28 +1,17 @@
#version 130
// in_Position was bound to attribute index 0 and in_Color was bound to attribute index 1
in vec3 in_Position;
// in vec3 in_Color;
in vec3 in_Color;
in vec2 vertexUV;
// We output the ex_Color variable to the next shader in the chain
// out vec3 ex_Color;
out vec4 ex_Color;
out vec2 UV;
uniform mat4 MVP;
// uniform mat4 MVP = mat4(vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1));
void main(void) {
// Since we are using flat lines, our input only had two points: x and y.
// Set the Z coordinate to 0 and W coordinate to 1
// gl_Position = vec4(in_Position.x / 2, in_Position.y / 2, in_Position.z / 2, 1.0);
void main(void)
{
gl_Position = MVP * vec4(in_Position, 1);
// GLSL allows shorthand use of vectors too, the following is also valid:
// gl_Position = vec4(in_Position, 1.0);
// We're simply passing the color through unmodified
// ex_Color = in_Color;
ex_Color = vec4(in_Color, 1);
UV = vertexUV;
}