1
0
Fork 0
fxt/main.c

219 rivejä
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;
}