Add some framebuffer boilerplate and stop trying to load a circle from an object file

This commit is contained in:
hiimgoodpack 2021-01-30 19:43:04 -05:00
parent bbb8e397d3
commit 1fdde43b57
Signed by: hiimgoodpack
GPG key ID: 4E0E62733C14AE69
7 changed files with 105 additions and 2135 deletions

3
.gitmodules vendored
View file

@ -1,6 +1,3 @@
[submodule "digraphene-headers"]
path = digraphene-headers
url = https://gitlab.com/TestingPlant/digraphene-headers.git
[submodule "fast_obj"]
path = fast_obj
url = https://github.com/thisistherk/fast_obj.git

@ -1 +0,0 @@
Subproject commit ac312c9c6d63c1902647e8a47190a18878e7f282

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -14,73 +14,29 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define FAST_OBJ_IMPLEMENTATION
#include "../fast_obj/fast_obj.h"
#include <mesh.h>
#include <GLFW/glfw3.h>
#include <shader.h>
#include <cstring>
#include <cassert>
#include <iostream>
#include <type_traits>
typedef struct {
linalg::aliases::float3 position;
linalg::aliases::float2 position;
} Vertex;
typedef unsigned int Element;
const Mesh::Attribute VERTEX_ATTRIBUTES[] = {
{
.index = 0,
.size = 3,
.size = 2,
.type = GL_FLOAT,
.stride = sizeof(Vertex),
.pointer = (void*)offsetof(Vertex, position)
}
};
Mesh::InstancedElements processMesh(const char* const path) {
fastObjMesh* mesh = fast_obj_read(path);
assert(mesh && "An error occured while reading a mesh. Make sure the path is correct and points to a wavefront object file");
const unsigned int vertexCount = mesh->position_count-1;
const unsigned int indexCount = mesh->face_count*3;
Vertex* const vertices = new Vertex[vertexCount];
Element* const elements = new Element[indexCount];
// Index 0 is an invalid index to use in an object file, so we'll remove it
for (unsigned int i = 1; i < mesh->position_count; i++) {
vertices[i-1].position = {mesh->positions[i*3], mesh->positions[i*3+1], mesh->positions[i*3+2]};
}
for (unsigned int i = 0; i < mesh->face_count; i += 3) {
elements[i] = mesh->indices[i].p-1;
elements[i+1] = mesh->indices[i].t-1;
elements[i+2] = mesh->indices[i].n-1;
}
fast_obj_destroy(mesh);
// TODO: Make a way to clean up buffers
Buffer::Specialized<Vertex, GL_ARRAY_BUFFER> vertexBuffer(vertices, vertexCount * sizeof(Vertex), GL_STATIC_DRAW);
Buffer::Specialized<Element, GL_ELEMENT_ARRAY_BUFFER> elementBuffer(elements, indexCount * sizeof(Element), GL_STATIC_DRAW);
delete[] vertices;
delete[] elements;
Mesh::Buffer buffers[2] = {
{
.buffer = vertexBuffer,
.attributes = VERTEX_ATTRIBUTES,
.attributeCount = sizeof(VERTEX_ATTRIBUTES)/sizeof(Mesh::Attribute)
},
{
.buffer = elementBuffer
}
};
return Mesh::InstancedElements(buffers, 2, indexCount, 1, GL_UNSIGNED_INT);
}
#include <fstream>
std::string readExternalFile(const char* name) {
std::string contents;
@ -149,7 +105,10 @@ void onGLFWError(int errorCode, const char* error) {
Shader::Program shader;
const unsigned int resultLength = 350;
int main() {
// Get a context
glfwSetErrorCallback(onGLFWError);
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@ -158,18 +117,83 @@ int main() {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_VISIBLE, false);
GLFWwindow* window = glfwCreateWindow(1, 1, "You aren't supposed to see this", NULL, NULL);
//glfwWindowHint(GLFW_VISIBLE, false);
GLFWwindow* window = glfwCreateWindow(resultLength, resultLength, "You aren't supposed to see this", NULL, NULL);
glfwMakeContextCurrent(window);
Mesh::InstancedElements sphere = processMesh("../meshes/sphere.obj");
// Load a square
/*
0--1
| |
3--2
*/
const Vertex squareVertices[] = {
{
.position = {-1, 1}
},
{
.position = {1, 1}
},
{
.position = {1, -1}
},
{
.position = {-1, -1}
}
};
const Element squareElements[] = {0, 1, 3, 1, 2, 3};
Buffer::Specialized<Vertex, GL_ARRAY_BUFFER> vertexBuffer(squareVertices, sizeof(squareVertices), GL_STATIC_DRAW);
Buffer::Specialized<Element, GL_ELEMENT_ARRAY_BUFFER> elementBuffer(squareElements, sizeof(squareElements), GL_STATIC_DRAW);
Mesh::Buffer buffers[2] = {
{
.buffer = vertexBuffer,
.attributes = VERTEX_ATTRIBUTES,
.attributeCount = sizeof(VERTEX_ATTRIBUTES)/sizeof(Mesh::Attribute)
},
{
.buffer = elementBuffer
}
};
Mesh::InstancedElements square(buffers, 2, sizeof(squareElements)/sizeof(Element), 1, GL_UNSIGNED_INT);
// Load shaders
{
std::string vertexCode = readExternalFile("../shaders/vertex.glsl");
shader.add(vertexCode.c_str(), -1, GL_VERTEX_SHADER);
assert(shader.add(vertexCode.c_str(), -1, GL_VERTEX_SHADER) == Shader::Error::NONE);
std::string fragmentCode = readExternalFile("../shaders/fragment.glsl");
shader.add(fragmentCode.c_str(), -1, GL_FRAGMENT_SHADER);
assert(shader.add(fragmentCode.c_str(), -1, GL_FRAGMENT_SHADER) == Shader::Error::NONE);
}
shader.link();
shader.use();
// Set up a framebuffer
/*unsigned int frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
unsigned int colorBuffer;
glGenTextures(1, &colorBuffer);
glBindTexture(GL_TEXTURE_2D, colorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resultLength, resultLength, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0);
unsigned int renderBuffer;
glGenRenderbuffers(1, &renderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, resultLength, resultLength);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE && "Generated framebuffer is incomplete");
*/
glClearColor(0.5, 0, 0, 1);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
square.draw();
glfwSwapBuffers(window);
glfwPollEvents();
}
}

View file

@ -1,9 +1,32 @@
/*
Copyright (C) 2021 hiimgoodpack
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#version 330 core
in vec2 vTexCoord;
unfirom sampler2D aTexture0;
uniform sampler2D aTexture0;
void main() {
gl_FragColor = texture(aTexture0, vTexCoord);
/*
dot(vTexCoord, vTexCoord)
essentially does pow(length(gl_FragCoord.xy),2), but
(probably) more optimized
We're doing this since we don't want fragments outside a circle
*/
float alpha = dot(vTexCoord, vTexCoord) > 1 ? 1 : 0;
gl_FragColor = vec4(0, 0, 0, alpha);
}

View file

@ -15,14 +15,12 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aTexCoord;
layout (location = 0) in vec2 aPosition;
out vec2 vTexCoord;
uniform mat4 aTransform;
void main() {
gl_Position = aTransform * vec4(aPosition, 1);
vTexCoordd = aTexCoord;
gl_Position = vec4(aPosition, 0, 1);
vTexCoord = aPosition;
}