219 lines
4.4 KiB
C
219 lines
4.4 KiB
C
#include "gl_2_1.h"
|
|
#include "SDL.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
struct renderinfo
|
|
{
|
|
int ScrW;
|
|
int ScrH;
|
|
|
|
SDL_Window *Window;
|
|
SDL_Renderer *Renderer;
|
|
SDL_GLContext Context;
|
|
|
|
GLuint VertShader;
|
|
GLuint FragShader;
|
|
GLuint Program;
|
|
|
|
GLuint VBO;
|
|
GLuint EBO;
|
|
|
|
struct
|
|
{
|
|
GLint Position;
|
|
} Attrib;
|
|
|
|
struct
|
|
{
|
|
GLint Ticks;
|
|
} Uniform;
|
|
};
|
|
|
|
struct renderinfo re;
|
|
|
|
GLuint R_CreateBuffer(GLenum type, void const *data, GLsizei size)
|
|
{
|
|
GLuint buffer;
|
|
glGenBuffers(1, &buffer);
|
|
glBindBuffer(type, buffer);
|
|
glBufferData(type, size, data, GL_STATIC_DRAW);
|
|
return buffer;
|
|
}
|
|
|
|
GLuint R_CreateShader(GLenum type, char const *src)
|
|
{
|
|
char log[512];
|
|
GLint success;
|
|
GLuint shader;
|
|
|
|
shader = glCreateShader(type);
|
|
glShaderSource(shader, 1, &src, NULL);
|
|
glCompileShader(shader);
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
|
|
|
if(!success)
|
|
{
|
|
glGetShaderInfoLog(shader, 512, NULL, log);
|
|
fprintf(stderr, "Shader compile failed!\n%s\n", log);
|
|
exit(1);
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
GLuint R_LinkProgram(GLuint vertShader, GLuint fragShader)
|
|
{
|
|
char log[512];
|
|
GLint success;
|
|
GLuint program;
|
|
|
|
program = glCreateProgram();
|
|
glAttachShader(program, vertShader);
|
|
glAttachShader(program, fragShader);
|
|
glLinkProgram(program);
|
|
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
|
|
|
if(!success)
|
|
{
|
|
glGetProgramInfoLog(program, 512, NULL, log);
|
|
fprintf(stderr, "Failed to link shader program!\n%s\n", log);
|
|
exit(1);
|
|
}
|
|
|
|
return program;
|
|
}
|
|
|
|
char const *FXT_ReadFile(char const *fname)
|
|
{
|
|
FILE *fp;
|
|
char *buf;
|
|
size_t size;
|
|
|
|
fp = fopen(fname, "r");
|
|
buf = malloc(4096);
|
|
size = fread(buf, 1, 4096, fp);
|
|
buf[size] = '\0';
|
|
|
|
return realloc(buf, size + 1);
|
|
}
|
|
|
|
void R_InitGL()
|
|
{
|
|
GLfloat const vertices[] = {
|
|
-1.0, -1.0,
|
|
1.0, -1.0,
|
|
-1.0, 1.0,
|
|
1.0, 1.0
|
|
};
|
|
|
|
GLushort const indices[] = { 0, 1, 2, 3 };
|
|
|
|
// Init viewport.
|
|
glViewport(0, 0, re.ScrW, re.ScrH);
|
|
glClearColor(0.2, 0.3, 0.3, 1.0);
|
|
|
|
// Init buffers.
|
|
re.VBO = R_CreateBuffer(GL_ARRAY_BUFFER, vertices, sizeof(vertices));
|
|
re.EBO = R_CreateBuffer(GL_ELEMENT_ARRAY_BUFFER, indices, sizeof(indices));
|
|
|
|
// Init shaders.
|
|
re.VertShader = R_CreateShader(GL_VERTEX_SHADER, FXT_ReadFile("main.vp.glsl"));
|
|
re.FragShader = R_CreateShader(GL_FRAGMENT_SHADER, FXT_ReadFile("main.fp.glsl"));
|
|
re.Program = R_LinkProgram(re.VertShader, re.FragShader);
|
|
|
|
// Init uniform and attribute locations.
|
|
|
|
re.Uniform.Ticks = glGetUniformLocation(re.Program, "Ticks");
|
|
re.Attrib.Position = glGetAttribLocation(re.Program, "Position");
|
|
}
|
|
|
|
void R_Quit()
|
|
{
|
|
// Delete GL bound stuff.
|
|
glDeleteShader(re.VertShader);
|
|
glDeleteShader(re.FragShader);
|
|
glDeleteProgram(re.Program);
|
|
glDeleteBuffers(1, &re.VBO);
|
|
|
|
// Delete SDL bound stuff.
|
|
SDL_DestroyWindow(re.Window);
|
|
SDL_Quit();
|
|
}
|
|
|
|
void R_Init()
|
|
{
|
|
re.ScrW = 640;
|
|
re.ScrH = 480;
|
|
|
|
// Init GL info.
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
|
// Init window.
|
|
SDL_CreateWindowAndRenderer(re.ScrW, re.ScrH, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN, &re.Window, &re.Renderer);
|
|
|
|
// Init GL context.
|
|
re.Context = SDL_GL_CreateContext(re.Window);
|
|
SDL_GL_SetSwapInterval(1);
|
|
|
|
ogl_LoadFunctions();
|
|
|
|
R_InitGL();
|
|
|
|
atexit(R_Quit);
|
|
}
|
|
|
|
void R_Main()
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
// Bind shader.
|
|
glUseProgram(re.Program);
|
|
|
|
// Send uniforms.
|
|
glUniform1i(re.Uniform.Ticks, SDL_GetTicks());
|
|
|
|
// Bind vertex buffer.
|
|
glBindBuffer(GL_ARRAY_BUFFER, re.VBO);
|
|
glVertexAttribPointer(re.Attrib.Position, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, NULL);
|
|
glEnableVertexAttribArray(re.Attrib.Position);
|
|
|
|
// Bind element buffer, draw.
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, re.EBO);
|
|
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, NULL);
|
|
|
|
// Disable vertex buffer.
|
|
glDisableVertexAttribArray(re.Attrib.Position);
|
|
|
|
// Swap video buffer (send to screen).
|
|
SDL_GL_SwapWindow(re.Window);
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
|
|
#else
|
|
int main(int argc, char **argv)
|
|
#endif
|
|
{
|
|
SDL_Event ev;
|
|
|
|
SDL_Init(SDL_INIT_EVERYTHING);
|
|
R_Init();
|
|
|
|
for(;;)
|
|
{
|
|
while(SDL_PollEvent(&ev) != 0)
|
|
{
|
|
if(ev.type == SDL_QUIT)
|
|
{
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
R_Main();
|
|
}
|
|
|
|
return 0;
|
|
}
|