#include #include #include #include #include #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #define FACTOR 80 #define WIDTH ((FACTOR) * 16) #define HEIGHT ((FACTOR) * 9) SDL_Event e; float vertices[] = { // Positions Color TexCoords -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Bottom-left }; GLuint elements[] = { 0, 1, 2, 2, 3, 0, }; char * read_file(const char* path){ FILE* file = fopen(path, "r"); fseek(file, 0, SEEK_END); int eof = ftell(file); fseek(file, 0, SEEK_SET); char* file_content = malloc(eof * sizeof(char)); fread(file_content, sizeof(char), eof, file); fclose(file); return file_content; } GLuint CompileShader(const char* data, GLenum type){ GLuint shader = glCreateShader(type); glShaderSource(shader, 1, &data, NULL); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); char buffer[512]; glGetShaderInfoLog(shader, 512, NULL, buffer); printf("%s", buffer); return shader; } GLuint LinkShader(GLuint vertexShader, GLuint fragmentShader){ GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); GLint status; glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status); char buffer[512]; glGetProgramInfoLog(shaderProgram, 512, NULL, buffer); printf("%s", buffer); glUseProgram(shaderProgram); return shaderProgram; } int main(void) { const char* vs = read_file("./shader.vs"); const char* fs = read_file("./shader.fs"); if(SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO)){ SDL_Log("Unable to initialize SDL: %s", SDL_GetError()); } SDL_Window *win; win = SDL_CreateWindow("Game of life", 0, 0, WIDTH, HEIGHT, SDL_WINDOW_OPENGL); if(!win){ SDL_Log("Unable to create Window: %s", SDL_GetError()); } SDL_GLContext con = SDL_GL_CreateContext(win); if(!con){ SDL_Log("Unable to create OpenGL Context: %s", SDL_GetError()); } if(glewInit()){ SDL_Log("SDL_INIT error"); }; SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); // vectors GLuint vertexBuffer; glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // reuse vectors GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); GLuint vertexShader = CompileShader(vs, GL_VERTEX_SHADER); GLuint fragmentShader = CompileShader(fs, GL_FRAGMENT_SHADER); GLuint shaderProgram = LinkShader(vertexShader, fragmentShader); // Textures int width, height; unsigned char *image, *image2; GLuint tex[2]; glGenTextures(2, tex); //Load image glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex[0]); image = stbi_load("./sample.png", &width, &height, NULL, 3); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); stbi_image_free(image); glUniform1i(glGetUniformLocation(shaderProgram, "kitty"), 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //Load image glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tex[1]); image2 = stbi_load("./sample2.png", &width, &height, NULL, 3); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2); stbi_image_free(image2); glGenerateMipmap(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(shaderProgram, "puppy"), 1); /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); */ /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); */ /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); */ /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); */ GLint posAttrib = glGetAttribLocation(shaderProgram, "positions"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 7, 0); GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); glEnableVertexAttribArray(colAttrib); glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, (void*)(2*sizeof(float))); GLint texCoordsAttrib = glGetAttribLocation(shaderProgram, "texCoords"); glEnableVertexAttribArray(texCoordsAttrib); glVertexAttribPointer(texCoordsAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 7, (void*)(5*sizeof(float))); int i = 0; bool should_close = false; while(!should_close){ i++; glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glUniform1i(glGetUniformLocation(shaderProgram, "triangleColor"), i); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); /* glDrawArrays(GL_TRIANGLES, 0, 3); */ SDL_GL_SwapWindow(win); while(SDL_PollEvent(&e)){ if(e.type == SDL_QUIT) should_close = true; if(e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_a) should_close = true; } } glDeleteProgram(shaderProgram); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); SDL_GL_DeleteContext(con); SDL_DestroyWindow(win); SDL_Quit(); return 0; }