Added texture support.

This commit is contained in:
2021-03-18 21:46:51 +11:00
parent 987229bcff
commit d945d5d530
12 changed files with 263 additions and 36 deletions

View File

@ -1,6 +1,14 @@
#version 330 core
in vec2 TexCoord;
uniform sampler2D u_Text;
out vec4 FragColor;
void main() {
FragColor = vec4(1, 1, 1, 1);
vec4 color = texture(u_Text, TexCoord);
FragColor = color;
// FragColor = color + vec4(0.5, 0.5, 0.5, 1);
// FragColor = vec4(1, 1, 1, 1);
}

View File

@ -1,11 +1,15 @@
// #version 330 core
// #extension GL_ARB_separate_shader_objects : enable
#version 330 core
#extension GL_ARB_separate_shader_objects : enable
// layout (location = 0) in vec3 aPos;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
uniform mat4 u_Proj;
uniform mat4 u_View;
out vec2 TexCoord;
void main() {
gl_Position = u_Proj * u_View * gl_Vertex;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

View File

@ -0,0 +1,53 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "quad.h"
void quadBuffer(primitive_t *primitive,
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1,
int32_t verticeStart, int32_t indiceStart
) {
vertice_t *vertices = malloc(sizeof(vertice_t) * 4);
indice_t *indices = malloc(sizeof(indice_t) * 6);
vertices[0].x = x0, vertices[0].y = y0, vertices[0].z = 0;
vertices[0].u = u0, vertices[0].v = v0;
vertices[1].x = x1, vertices[1].y = y0, vertices[1].z = 0;
vertices[1].u = u1, vertices[1].v = v0;
vertices[2].x = x0, vertices[2].y = y1, vertices[2].z = 0;
vertices[2].u = u0, vertices[2].v = v1;
vertices[3].x = x1, vertices[3].y = y1, vertices[3].z = 0;
vertices[3].u = u1, vertices[3].v = v1;
indices[0] = (indice_t)0, indices[1] = (indice_t)1, indices[2] = (indice_t)2;
indices[3] = (indice_t)1, indices[4] = (indice_t)2, indices[5] = (indice_t)3;
primitiveBufferVertices(primitive, verticeStart, 4, vertices);
primitiveBufferIndices(primitive, indiceStart, 6, indices);
free(vertices);
free(indices);
}
primitive_t * quadCreate(
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1
) {
primitive_t *primitive = primitiveCreate(4, 6);
quadBuffer(primitive,
x0, y0, u0, v0,
x1, y1, u1, v1,
0, 0
);
return primitive;
}

View File

@ -0,0 +1,19 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <stdint.h>
#include "../primitive.h"
void quadBuffer(primitive_t *primitive,
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1,
int32_t verticeStart, int32_t indiceStart
);
primitive_t * quadCreate(
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1
);

View File

@ -7,8 +7,6 @@
#include "render.h"
primitive_t *primitive;
render_t * renderInit(char *name) {
// Initialize the renderer
render_t *render = malloc(sizeof(render_t));
@ -16,42 +14,21 @@ render_t * renderInit(char *name) {
// render->width = WINDOW_WIDTH_DEFAULT;
// render->height = WINDOW_HEIGHT_DEFAULT;
//GLEnable Things
// Enable GL things.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
// Setup the alpha blend function.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
// Test
for(int i = 0; i < 100; i++) {
vertice_t *vertices = malloc(sizeof(vertice_t) * 4);
indice_t *indices = malloc(sizeof(indice_t) * 6);
vertices[0].x = -1, vertices[0].y = -1, vertices[0].z = 0;
vertices[1].x = 1, vertices[1].y = -1, vertices[1].z = 0;
vertices[2].x = -1, vertices[2].y = 1, vertices[2].z = 0;
vertices[3].x = 1, vertices[3].y = 1, vertices[3].z = 0;
indices[0] = (indice_t)0;
indices[1] = (indice_t)1;
indices[2] = (indice_t)2;
indices[3] = (indice_t)1;
indices[4] = (indice_t)2;
indices[5] = (indice_t)3;
primitive = primitiveCreate(4, 6);
primitiveBufferVertices(primitive, 0, 4, vertices);
primitiveBufferIndices(primitive, 0, 6, indices);
}
return render;
}
void renderFrame(render_t *render) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
primitiveDraw(primitive, 0, 6);
}
bool renderDispose(render_t *render) {

View File

@ -77,6 +77,7 @@ shader_t * shaderCompile(char *vertexShaderSource, char* fragmentShaderSource) {
shader->uniProj = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_PROJ);
shader->uniView = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_VIEW);
shader->uniText = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_TEXT);
// Bind the shader
shaderUse(shader);
@ -100,4 +101,10 @@ void shaderUse(shader_t *shader) {
void shaderUseCamera(shader_t *shader, camera_t *camera) {
glUniformMatrix4fv(shader->uniView, 1, GL_FALSE, (float*)camera->view);
glUniformMatrix4fv(shader->uniProj, 1, GL_FALSE, (float*)camera->projection);
}
void shaderUseTexture(shader_t *shader, texture_t *texture) {
// OpenGL requires us to set the active texure.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->id);
glUniform1i(shader->uniText, 0);
}

View File

@ -12,9 +12,11 @@
#include <stdbool.h>
#include <malloc.h>
#include "camera.h"
#include "texture.h"
#define SHADER_UNI_VIEW "u_View"
#define SHADER_UNI_PROJ "u_Proj"
#define SHADER_UNI_TEXT "u_Text"
/**
* Structure containing information about an OpenGL Shader. For simplicity sake
@ -35,6 +37,9 @@ typedef struct {
/** Matrix for the projection matrix */
GLint uniProj;
/** Uniform for the current texture */
GLint uniText;
} shader_t;
/**
@ -61,4 +66,16 @@ bool shaderDipose(shader_t *shader);
void shaderUse(shader_t *shader);
void shaderUseCamera(shader_t *shader, camera_t *camera);
/**
* Attaches a camera to the shader.
* @param shader Shader to attach to.
* @param camera Camera to attach.
*/
void shaderUseCamera(shader_t *shader, camera_t *camera);
/**
* Attaches a texture to the shader.
* @param shader Shader to attach to.
* @param texture Texture to attach.
*/
void shaderUseTexture(shader_t *shader, texture_t *texture);

View File

@ -0,0 +1,61 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "texture.h"
texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels) {
texture_t *texture = malloc(sizeof(texture_t));
if(texture == NULL) return NULL;
texture->width = width;
texture->height = height;
// Generate a texture ID and bind.
glGenTextures(1, &texture->id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->id);
// Setup our preferred texture params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Start by buffering all transparent black pixels.
if(pixels == NULL) {
pixels = calloc(width * height, sizeof(pixel_t));
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels
);
free(pixels);
} else {
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels
);
}
return texture;
}
void textureBufferPixels(texture_t *texture,
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
) {
glBindTexture(GL_TEXTURE_2D, texture->id);
glTexSubImage2D(GL_TEXTURE_2D, 0,
x, y, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, pixels
);
}
void textureDispose(texture_t *texture) {
glDeleteTextures(1, &texture->id);
free(texture);
}

View File

@ -0,0 +1,57 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <stdint.h>
#include <glad/glad.h>
#include <malloc.h>
#include <memory.h>
/**
* Structure detailing information about a texture.
* Because we plan to upload the pixels of a texture into the GPU, we don't
* store the pixels in memory because we don't need to!
*/
typedef struct {
int32_t width;
int32_t height;
GLuint id;
} texture_t;
/** Information about a single pixel. */
typedef struct {
uint8_t r, g, b, a;
} pixel_t;
/**
* Creates a new texture that can be written in to.
*
* @param width Width of the texture (in pixels).
* @param height Height of the texture (in pixels).
* @param pixels Default pixel array, set to NULL to set all pixel data to 0.
* @return The newly created texture instance.
*/
texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so avoid
* doing this too often.
*
* @param texture Texture to buffer in to.
* @param x X coordinate in texture space to render to.
* @param y Y coordinate in texture space to render to.
* @param width Width of the pixel region you're buffering.
* @param height Height of the pixel region you're buffering.
* @param pixels Array of pixels to buffer onto the GPU.
*/
void textureBufferPixels(texture_t *texture,
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
);
/**
* Clean a previously created texture.
* @param texture Texture to clean up.
*/
void textureDispose(texture_t *texture);

View File

@ -7,9 +7,16 @@
#include "engine.h"
#include "display/primitives/quad.h"
#include "display/texture.h"
#include "display/shader.h"
camera_t *camera;
shader_t *shader;
primitive_t *primitive;
texture_t *texture;
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
// Create the engine instance.
engine_t *engine = malloc(sizeof(engine_t));
@ -43,12 +50,30 @@ engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
cameraPerspective(camera, 45.0f, 1920.0f/1080.0f, 3.0f, 100.0f);
shaderUseCamera(shader, camera);
// Test
primitive = quadCreate(
-1, -1, 0, 0,
1, 1, 1, 1
);
texture = textureCreate(1, 1, NULL);
pixel_t *pixels = malloc(sizeof(pixel_t) * 1 * 1);
for(int32_t i = 0; i < 1*1; i++) {
pixels[i].r = 0xFF, pixels[i].g = 0x00, pixels[i].b = 0xFF;
pixels[i].a = 0xFF;
}
textureBufferPixels(texture, 0, 0, 1, 1, pixels);
shaderUseTexture(shader, texture);
return engine;
}
uint32_t engineUpdate(engine_t *engine) {
shaderUse(shader);
renderFrame(engine->render);
primitiveDraw(primitive, 0, 6);
inputUpdate(engine->input);
return 0;

View File

@ -29,9 +29,7 @@ input_t * inputInit(uint32_t inputBindCount, uint32_t inputSourceCount) {
input->times = malloc(sizeof(float) * inputBindCount);
// Create the buffer, zero all the values out.
size_t size = sizeof(inputval_t) * inputSourceCount;
input->buffer = malloc(size);
memset(input->buffer, 0, size);
input->buffer = calloc(inputSourceCount, sizeof(inputval_t));
// Pass off the input manager
return input;

View File

@ -7,6 +7,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include "../util/list/list.h"
#include "../platform.h"