143 lines
4.3 KiB
C
143 lines
4.3 KiB
C
#include <stdlib.h>
|
|
|
|
#include <GL/glew.h>
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3/SDL_opengl.h>
|
|
|
|
#include "opengl.h"
|
|
#include "readfile.h"
|
|
|
|
shaderProgram_t sp;
|
|
|
|
GLuint createShader ( const char *shaderFile, GLenum shaderType )
|
|
{
|
|
const char *strShaderType;
|
|
if (shaderType == GL_VERTEX_SHADER) {
|
|
strShaderType = "vertex";
|
|
} else if (shaderType == GL_GEOMETRY_SHADER) {
|
|
strShaderType = "geometry";
|
|
} else if (shaderType == GL_FRAGMENT_SHADER) {
|
|
strShaderType = "fragment";
|
|
} else {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Unrecognized shader type.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
GLuint shader = glCreateShader(shaderType);
|
|
if (!shader) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Error create shader type %s.", strShaderType);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
GLchar *content = readFile(shaderFile);
|
|
glShaderSource(shader, 1, (const GLchar **)&content, NULL);
|
|
SDL_free(content);
|
|
glCompileShader(shader);
|
|
GLint status;
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
|
if (status == GL_FALSE) {
|
|
GLint infoLen;
|
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
|
|
GLchar *info = SDL_malloc(sizeof(GLchar) * (infoLen + 1));
|
|
glGetShaderInfoLog(shader, infoLen, NULL, info);
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Filed to compile %s shader:\n%s.", strShaderType, info);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
return shader;
|
|
}
|
|
|
|
void createProgram ( GLuint *shaders, int len )
|
|
{
|
|
sp.program = glCreateProgram();
|
|
if (!sp.program) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Can't to create shader program.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
for (int i = 0; i < len; i++) {
|
|
glAttachShader(sp.program, shaders[i]);
|
|
}
|
|
glLinkProgram(sp.program);
|
|
GLint status;
|
|
glGetProgramiv(sp.program, GL_LINK_STATUS, &status);
|
|
if (status == GL_FALSE) {
|
|
GLint infoLen;
|
|
glGetProgramiv(sp.program, GL_INFO_LOG_LENGTH, &infoLen);
|
|
GLchar *info = SDL_malloc(sizeof(GLchar) * (infoLen + 1));
|
|
glGetProgramInfoLog(sp.program, infoLen, NULL, info);
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Link failed: %s", info);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
void createBuffer ( void )
|
|
{
|
|
GLushort indices[] = {
|
|
0, 1, 2,
|
|
0, 2, 3
|
|
};
|
|
float vertices[] = {
|
|
-1.0f, -1.0f, -2.0f, 1.0f, // left-bottom
|
|
-1.0f, 1.0f, -2.0f, 1.0f, // left-top
|
|
1.0f, 1.0f, -2.0f, 1.0f, // right-top
|
|
1.0f, -1.0f, -2.0f, 1.0f, // right-bottom
|
|
|
|
// colours
|
|
1.0f, 0.0f, 0.0f, 1.0f, // red
|
|
0.0f, 1.0f, 0.0f, 1.0f, // green
|
|
1.0f, 0.0f, 1.0f, 1.0f, // purple
|
|
1.0f, 1.0f, 0.0f, 1.0f // yellow
|
|
};
|
|
glGenBuffers(1, &sp.vbo);
|
|
glBindBuffer(GL_ARRAY_BUFFER, sp.vbo);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
glGenBuffers(1, &sp.ibo);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sp.ibo);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
void setUniformLocation ( void )
|
|
{
|
|
sp.projMatrLoc = glGetUniformLocation(sp.program, "projMatr");
|
|
}
|
|
|
|
void startShaderProg ( void )
|
|
{
|
|
createBuffer();
|
|
|
|
GLuint shaders[] = {
|
|
createShader("vertex.glsl", GL_VERTEX_SHADER),
|
|
createShader("fragment.glsl", GL_FRAGMENT_SHADER)
|
|
};
|
|
int len = sizeof(shaders) / sizeof(shaders[0]);
|
|
createProgram(shaders, len);
|
|
for (int i = 0; i < len; i++) {
|
|
glDeleteShader(shaders[i]);
|
|
}
|
|
|
|
setUniformLocation();
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthMask(GL_TRUE);
|
|
glDepthFunc(GL_LEQUAL);
|
|
glDepthRange(0.0f, 1.0f);
|
|
}
|
|
|
|
void _GLBuffer( void )
|
|
{
|
|
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
|
|
glClearDepth(1.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glUseProgram(sp.program);
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glEnableVertexAttribArray(1);
|
|
glBindBuffer(GL_ARRAY_BUFFER, sp.vbo);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sp.ibo);
|
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void *) (4*4*sizeof(float)));
|
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
|
glDisableVertexAttribArray(0);
|
|
glDisableVertexAttribArray(1);
|
|
|
|
glUseProgram(0);
|
|
}
|