Huge graphics overhaul
This commit is contained in:
@@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.26.0)
|
||||
if (NB_BUILD_TESTS)
|
||||
enable_testing()
|
||||
include(GoogleTest)
|
||||
|
||||
add_executable(TestWindow
|
||||
./TestWindow.cpp
|
||||
)
|
||||
@@ -11,4 +12,15 @@ if (NB_BUILD_TESTS)
|
||||
NBGraphics
|
||||
)
|
||||
|
||||
add_executable(TestImages
|
||||
./testImages.cpp
|
||||
)
|
||||
target_link_libraries(TestImages
|
||||
NBCore
|
||||
NBGraphics
|
||||
GTest::gtest_main
|
||||
)
|
||||
|
||||
gtest_discover_tests(TestImages)
|
||||
|
||||
endif()
|
||||
@@ -1,7 +1,12 @@
|
||||
#include "GLLoad.hpp"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "Image.hpp"
|
||||
#include "ProgramPipeline.hpp"
|
||||
#include "VertexArray.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "Textures.hpp"
|
||||
|
||||
int main() {
|
||||
nb::logger.log("Howdy!");
|
||||
@@ -10,54 +15,90 @@ int main() {
|
||||
window.setWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
window.init();
|
||||
|
||||
nb::logger.log("Goob");
|
||||
|
||||
auto vert = std::make_shared<nb::Shader>(
|
||||
GL_VERTEX_SHADER,
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec2 aPos;\n"
|
||||
"layout (location = 1) in vec2 tPos;\n"
|
||||
"out vec2 vPos;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);\n"
|
||||
" vPos = tPos;\n"
|
||||
"}\0"
|
||||
);
|
||||
|
||||
LOG("Vertex Shader: " + vert->log());
|
||||
LOG(vert->log());
|
||||
|
||||
auto frag = std::make_shared<nb::Shader>(
|
||||
GL_FRAGMENT_SHADER,
|
||||
"#version 330 core\n"
|
||||
"in vec2 vPos;\n"
|
||||
"out vec4 FragColor;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
|
||||
" FragColor = texture(tex, vPos);\n"
|
||||
"}\n\0"
|
||||
);
|
||||
|
||||
LOG("Fragment shader: " + frag->log());
|
||||
LOG(frag->log());
|
||||
|
||||
nb::ByteVector data = nb::vectorToBytes<float>({
|
||||
-0.5, -0.5, 0.5, -0.5, 0.0, 0.5
|
||||
-0.5, -0.5, 0,0,
|
||||
-0.5, 0.5, 0,1,
|
||||
0.5, 0.5, 1,1,
|
||||
0.5, -0.5, 1,0
|
||||
});
|
||||
|
||||
nb::Program prog({vert, frag});
|
||||
prog.bind();
|
||||
|
||||
std::vector<uint32_t> indxs = {0, 1, 2, 0, 2, 3};
|
||||
|
||||
nb::VertexGroup tri(data, {
|
||||
nb::VertexAttribute{
|
||||
2,
|
||||
GL_FLOAT,
|
||||
false,
|
||||
{0, 8}
|
||||
{0, 16}
|
||||
},
|
||||
nb::VertexAttribute{
|
||||
2,
|
||||
GL_FLOAT,
|
||||
false,
|
||||
{8, 16}
|
||||
}
|
||||
});
|
||||
}, indxs);
|
||||
tri.bind();
|
||||
|
||||
int width, height, numChannels;
|
||||
auto raw_img_data = stbi_load(
|
||||
"./awesomeface.png",
|
||||
&width,
|
||||
&height,
|
||||
&numChannels,
|
||||
0
|
||||
);
|
||||
LOG(numChannels);
|
||||
using RGBA = nb::Pixel<uint8_t, nb::Red, nb::Green, nb::Blue, nb::Alpha>;
|
||||
nb::ImageReference<RGBA> img(width, height, raw_img_data);
|
||||
auto tex = nb::ImageTexture<RGBA>();
|
||||
tex.parameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
tex.parameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
tex.setImage(img);
|
||||
tex.bind();
|
||||
tri.bind();
|
||||
LOG(img.at(256, 256).r);
|
||||
stbi_image_free(raw_img_data);
|
||||
|
||||
LOG(prog.log());
|
||||
|
||||
GLFWwindow* window_ptr = window.getWindow();
|
||||
while(!glfwWindowShouldClose(window_ptr)) {
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
tri.draw();
|
||||
glfwPollEvents();
|
||||
glfwSwapBuffers(window_ptr);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,156 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "Image.hpp"
|
||||
|
||||
TEST(TestImage, SinglePixel) {
|
||||
using RGB = nb::Pixel<uint8_t, nb::Red, nb::Green, nb::Blue>;
|
||||
RGB p1;
|
||||
p1.r = 0x00;
|
||||
p1.g = 0x0F;
|
||||
p1.b = 0xFF;
|
||||
ASSERT_EQ(p1.r, 0x00);
|
||||
ASSERT_EQ(p1.g, 0x0F);
|
||||
ASSERT_EQ(p1.b, 0xFF);
|
||||
RGB p2(p1);
|
||||
ASSERT_EQ(p2.r, 0x00);
|
||||
ASSERT_EQ(p2.g, 0x0F);
|
||||
ASSERT_EQ(p2.b, 0xFF);
|
||||
RGB p3(0xA, 0xB, 0xC);
|
||||
ASSERT_EQ(p3.r, 0xA);
|
||||
ASSERT_EQ(p3.g, 0xB);
|
||||
ASSERT_EQ(p3.b, 0xC);
|
||||
RGB p4 = p3;
|
||||
ASSERT_EQ(p4.r, 0xA);
|
||||
ASSERT_EQ(p4.g, 0xB);
|
||||
ASSERT_EQ(p4.b, 0xC);
|
||||
RGB p5(0xA0, 0xB0, 0xC0);
|
||||
ASSERT_EQ(p5.r, 0xA0);
|
||||
ASSERT_EQ(p5.g, 0xB0);
|
||||
ASSERT_EQ(p5.b, 0xC0);
|
||||
|
||||
using RBAG = nb::Pixel<float,
|
||||
nb::Red, nb::Blue, nb::Alpha, nb::Green
|
||||
>;
|
||||
float a=0.5, b=0.4, c=0.0, d=0.3;
|
||||
RBAG p6 = {a, b, c, d};
|
||||
ASSERT_EQ(p6.r, a);
|
||||
ASSERT_EQ(p6.b, b);
|
||||
ASSERT_EQ(p6.a, c);
|
||||
ASSERT_EQ(p6.g, d);
|
||||
RBAG p7 = p6;
|
||||
ASSERT_EQ(p7.r, a);
|
||||
ASSERT_EQ(p7.b, b);
|
||||
ASSERT_EQ(p7.a, c);
|
||||
ASSERT_EQ(p7.g, d);
|
||||
}
|
||||
|
||||
TEST(TestImage, PixelReference) {
|
||||
using RGB = nb::Pixel<uint8_t, nb::Red, nb::Green, nb::Blue>;
|
||||
using RGBRef = nb::PixelReference<RGB>;
|
||||
|
||||
using RBAG = nb::Pixel<float,
|
||||
nb::Red, nb::Blue, nb::Alpha, nb::Green
|
||||
>;
|
||||
using RBAGRef = nb::PixelReference<RBAG>;
|
||||
|
||||
RGB p1{255, 254, 253};
|
||||
RGBRef rp1(p1);
|
||||
ASSERT_EQ(rp1.r, p1.r);
|
||||
ASSERT_EQ(rp1.g, p1.g);
|
||||
ASSERT_EQ(rp1.b, p1.b);
|
||||
|
||||
RGB p2{0xa, 0xb, 0xc};
|
||||
rp1 = p2;
|
||||
ASSERT_EQ(p1.r, p2.r);
|
||||
ASSERT_EQ(p1.g, p2.g);
|
||||
ASSERT_EQ(p1.b, p2.b);
|
||||
|
||||
RGB p3 = rp1;
|
||||
ASSERT_EQ(p3.r, p1.r);
|
||||
ASSERT_EQ(p3.g, p1.g);
|
||||
ASSERT_EQ(p3.b, p1.b);
|
||||
|
||||
RGBRef rp2 = rp1;
|
||||
rp2 = RGB(2, 4, 8);
|
||||
ASSERT_EQ(p1.r, 2);
|
||||
ASSERT_EQ(p1.g, 4);
|
||||
ASSERT_EQ(p1.b, 8);
|
||||
|
||||
int val = 27;
|
||||
rp1.b = val;
|
||||
ASSERT_EQ(rp1.r, p1.r);
|
||||
ASSERT_EQ(rp1.g, p1.g);
|
||||
ASSERT_EQ(rp1.b, p1.b);
|
||||
ASSERT_EQ(p1.b, val);
|
||||
}
|
||||
|
||||
TEST(TestImage, SimpleImage) {
|
||||
unsigned char data[] = {
|
||||
0x00, 0x00,
|
||||
0x00, 0xFF,
|
||||
0xFF, 0x00,
|
||||
0xFF, 0xFF
|
||||
};
|
||||
using RG = nb::Pixel<uint8_t, nb::Red, nb::Blue>;
|
||||
nb::Image<RG> img(
|
||||
2, 2, data
|
||||
);
|
||||
for (int i = 0; i < sizeof(data); ++i) {
|
||||
ASSERT_EQ(img.data()[i], data[i]);
|
||||
}
|
||||
auto pixel = img.at(0, 1);
|
||||
ASSERT_EQ(pixel.r, data[4]);
|
||||
ASSERT_EQ(pixel.b, data[5]);
|
||||
|
||||
}
|
||||
|
||||
TEST(TestImage, LoadImage) {
|
||||
int width, height, numChannels;
|
||||
unsigned char* data = stbi_load(
|
||||
"./awesomeface.png",
|
||||
&width,
|
||||
&height,
|
||||
&numChannels,
|
||||
0
|
||||
);
|
||||
using RGBA = nb::Pixel<unsigned char, nb::Red, nb::Green, nb::Blue, nb::Alpha>;
|
||||
nb::Image<RGBA> img(
|
||||
width, height, data
|
||||
);
|
||||
for(int i = 0; i < height; ++i) {
|
||||
for (int j = 0; j < width; ++j) {
|
||||
auto pixel = img.at(j, i);
|
||||
ASSERT_EQ(pixel.r, data[4*(i*width+j)]);
|
||||
ASSERT_EQ(pixel.g, data[4*(i*width+j) + 1]);
|
||||
ASSERT_EQ(pixel.b, data[4*(i*width+j) + 2]);
|
||||
ASSERT_EQ(pixel.a, data[4*(i*width+j) + 3]);
|
||||
}
|
||||
}
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
TEST(TestImage, ImageBounds) {
|
||||
size_t len = 10;
|
||||
uint8_t val = 0xAA;
|
||||
std::vector<uint8_t> vec(2*len*len, val);
|
||||
using RB = nb::Pixel<uint8_t, nb::Red, nb::Blue>;
|
||||
nb::Image<RB> img(
|
||||
len, len, vec.data()
|
||||
);
|
||||
for (int i=0; i < 15; ++i) {
|
||||
if (i<len) {
|
||||
auto pixel = img.at(len/2, i);
|
||||
ASSERT_EQ(pixel.r, val);
|
||||
ASSERT_EQ(pixel.b, val);
|
||||
} else {
|
||||
ASSERT_THROW(img.at(len/2, i), nb::ImageError);
|
||||
ASSERT_THROW(img.at(i, len/2), nb::ImageError);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user