344 lines
9.9 KiB
C++
344 lines
9.9 KiB
C++
#include <cstdio>
|
|
#include <cmath>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
#define GL_GLEXT_PROTOTYPES
|
|
#include <GL/gl.h>
|
|
|
|
#define GLM_FORCE_RADIANS
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <glm/gtx/transform.hpp>
|
|
|
|
#include "common.hh"
|
|
#include "shaders.hh"
|
|
#include "texture.hh"
|
|
#include "objectParser.hh"
|
|
|
|
|
|
const float cubeVertexData[][5] = {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
|
|
{1.0f, 0.0f, 0.0f, 1.0f, 0.0f},
|
|
{0.0f, 1.0f, 0.0f ,0.0f, 1.0f},
|
|
{1.0f, 1.0f, 0.0f, 1.0f, 1.0f},
|
|
|
|
{1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
|
|
{1.0f, 0.0f, -1.0f, 1.0f, 0.0f},
|
|
{1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
|
|
{1.0f, 1.0f, -1.0f, 1.0f, 1.0f},
|
|
|
|
{1.0f, 0.0f, -1.0f, 0.0f, 0.0f},
|
|
{0.0f, 0.0f, -1.0f, 1.0f, 0.0f},
|
|
{1.0f, 1.0f, -1.0f, 0.0f, 1.0f},
|
|
{0.0f, 1.0f, -1.0f, 1.0f, 1.0f},
|
|
|
|
{0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
|
|
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
|
|
{0.0f, 1.0f, -1.0f, 0.0f, 1.0f},
|
|
{0.0f, 1.0f, 0.0f, 1.0f, 1.0f},
|
|
|
|
{0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
|
|
{1.0f, 0.0f, -1.0f, 1.0f, 0.0f},
|
|
{0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
|
{1.0f, 0.0f, 0.0f, 1.0f, 1.0f},
|
|
|
|
{0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
|
|
{1.0f, 1.0f, 0.0f, 1.0f, 0.0f},
|
|
{0.0f, 1.0f, -1.0f, 0.0f, 1.0f},
|
|
{1.0f, 1.0f, -1.0f, 1.0f, 1.0f}};
|
|
|
|
const uint8_t cubeIndices[] = {0, 1, 2,
|
|
1, 2, 3,
|
|
|
|
4, 5, 6,
|
|
5, 6, 7,
|
|
|
|
8, 9, 10,
|
|
9, 10, 11,
|
|
|
|
12, 13, 14,
|
|
13, 14, 15,
|
|
|
|
16, 17, 18,
|
|
17, 18, 19,
|
|
|
|
20, 21, 22,
|
|
21, 22, 23};
|
|
|
|
const float vertices[][3] = {{0.0f, 0.0f, 0.0f},
|
|
{1.0f, 0.0f, 0.0f},
|
|
{0.0f, 1.0f, 0.0f},
|
|
{1.0f, 1.0f, 0.0f},
|
|
|
|
{0.0f, 0.0f, -1.0f},
|
|
{1.0f, 0.0f, -1.0f},
|
|
{0.0f, 1.0f, -1.0f},
|
|
{1.0f, 1.0f, -1.0f},
|
|
|
|
{-1.0f, -2.0f, -5.0f},
|
|
{-1.5f, -1.0f, -4.5f},
|
|
{-0.5f, -1.0f, -4.5f},
|
|
{-1.0f, -1.0f, -5.5f}};
|
|
|
|
const float colors[][3] = {{1.0f, 0.0f, 1.0f},
|
|
{1.0f, 0.0f, 0.0f},
|
|
{0.0f, 1.0f, 0.0f},
|
|
{0.0f, 0.0f, 1.0f},
|
|
{1.0f, 0.0f, 0.0f},
|
|
{0.0f, 1.0f, 0.0f},
|
|
{0.0f, 0.0f, 1.0f},
|
|
{1.0f, 0.0f, 1.0f},
|
|
|
|
{1.0f, 1.0f, 1.0f},
|
|
{0.0f, 0.0f, 1.0f},
|
|
{0.0f, 1.0f, 0.0f},
|
|
{1.0f, 0.0f, 0.0f}};
|
|
|
|
const float texcoords[][2] = {{0.0f, 0.0f},
|
|
{1.0f, 0.0f},
|
|
{0.0f, 1.0f},
|
|
{1.0f, 1.0f},
|
|
|
|
{1.0f, 1.0f},
|
|
{1.0f, 0.0f},
|
|
{0.0f, 1.0f},
|
|
{0.0f, 0.0f},
|
|
|
|
{0.0f, 0.0f},
|
|
{0.0f, 0.0f},
|
|
{0.0f, 0.0f},
|
|
{0.0f, 0.0f}};
|
|
|
|
const unsigned indices[] = {0, 2, 1,
|
|
2, 3, 1,
|
|
|
|
0, 4, 1,
|
|
1, 4, 5,
|
|
|
|
1, 7, 3,
|
|
1, 5, 7,
|
|
|
|
2, 3, 7,
|
|
2, 7, 6,
|
|
|
|
4, 6, 0,
|
|
0, 6, 2,
|
|
|
|
4, 5, 6,
|
|
5, 7, 6
|
|
};
|
|
|
|
const unsigned indicesPyramid[] = {8, 10, 9,
|
|
8, 11, 10,
|
|
8, 9, 11,
|
|
9, 10, 11};
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
SDL_Window *window;
|
|
int retcode = 0;
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
|
std::printf("Could not init SDL: %s\n", SDL_GetError());
|
|
return 1;
|
|
}
|
|
if (IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG) == 0) {
|
|
std::printf("Could not init SDL_image: %s\n", SDL_GetError());
|
|
SDL_Quit();
|
|
return 1;
|
|
}
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
|
|
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
|
|
|
window = SDL_CreateWindow("SDL2 Test",
|
|
SDL_WINDOWPOS_UNDEFINED,
|
|
SDL_WINDOWPOS_UNDEFINED,
|
|
640,
|
|
480,
|
|
SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL);
|
|
|
|
if (!window) {
|
|
std::printf("Could not create window: %s\n", SDL_GetError());
|
|
SDL_Quit();
|
|
return 1;
|
|
}
|
|
|
|
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
|
|
if (!glcontext) {
|
|
std::printf("Could not create GL context: %s\n", SDL_GetError());
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
return 1;
|
|
}
|
|
|
|
try {
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
{
|
|
int depth, stencil, aa, major, minor;
|
|
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth);
|
|
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil);
|
|
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &aa);
|
|
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
|
|
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
|
|
|
|
std::printf("Depth: %d, Stencil: %d, AA: %d, GL %d.%d\n",
|
|
depth, stencil, aa, major, minor);
|
|
}
|
|
|
|
int width, height;
|
|
SDL_GetWindowSize(window, &width, &height);
|
|
glm::mat4 proj = glm::perspectiveFov(75.0f, static_cast<float>(width), static_cast<float>(height),
|
|
0.1f, 100.0f);
|
|
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 10),
|
|
glm::vec3(0, 0, 0),
|
|
glm::vec3(0, 1, 0));
|
|
// sf::Font font;
|
|
// if (!font.loadFromFile("DejaVuSans.ttf")) {
|
|
// std::printf("Error loading font\n");
|
|
// return 1;
|
|
// }
|
|
|
|
// sf::Text fpsText{"0", font, 12};
|
|
// fpsText.setPosition({200, 200});
|
|
|
|
// window.setFramerateLimit(60);
|
|
|
|
// sf::Clock clock;
|
|
// sf::Time last = clock.getElapsedTime();
|
|
|
|
Texture2D cubeTex("textures/Wood_Box_Texture.jpg");
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
if (SDL_GL_ExtensionSupported("GL_EXT_texture_filter_anisotropic"))
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f);
|
|
else
|
|
std::printf("Warning: extension GL_EXT_texture_filter_anisotropic not supported\n");
|
|
|
|
auto box = readObject("objects/woodbox.obj");
|
|
|
|
VertexShader vs{fileToString("shaders/textured.vs")};
|
|
FragmentShader fs{fileToString("shaders/textured.fs")};
|
|
Program prog(vs, fs);
|
|
checkGlError();
|
|
|
|
prog.use();
|
|
glUniformMatrix4fv(prog.getUniformLocation("projection_matrix"), 1, GL_FALSE,
|
|
glm::value_ptr(proj));
|
|
glUniform1i(prog.getUniformLocation("texBase"), 0);
|
|
|
|
int vertexAL = prog.getAttribLocation("vertex");
|
|
//int vertexColorAL = prog.getAttribLocation("vertexColor");
|
|
int vertexTCAL = prog.getAttribLocation("vertexTC");
|
|
|
|
checkGlError();
|
|
|
|
GLuint buf;
|
|
glGenBuffers(1, &buf);
|
|
glBindBuffer(GL_ARRAY_BUFFER, buf);
|
|
checkGlError();
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*24*5, NULL, GL_STATIC_DRAW);
|
|
//glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*24*5, (void*)cubeVertexData[0]);
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(objVertexAttribs)*std::get<0>(box).size(),
|
|
(void*)std::get<0>(box).data());
|
|
|
|
// glBufferData(GL_ARRAY_BUFFER, sizeof(float)*(2*3*12+2*12), NULL, GL_STATIC_DRAW);
|
|
// glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*12, (void*)vertices[0]);
|
|
// glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*3*12, sizeof(float)*3*12, (void*)colors[0]);
|
|
// glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*2*3*12, sizeof(float)*2*12, (void*)texcoords[0]);
|
|
|
|
GLuint arr[2];
|
|
glGenVertexArrays(2, arr);
|
|
checkGlError();
|
|
|
|
// glBindVertexArray(arr[0]);
|
|
// glEnableVertexAttribArray(vertexAL);
|
|
// glEnableVertexAttribArray(vertexColorAL);
|
|
// glEnableVertexAttribArray(vertexTCAL);
|
|
// glVertexAttribPointer(vertexAL, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
|
// glVertexAttribPointer(vertexColorAL, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(float)*3*12));
|
|
// glVertexAttribPointer(vertexTCAL, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(float)*2*3*12));
|
|
|
|
glBindVertexArray(arr[0]);
|
|
glEnableVertexAttribArray(vertexAL);
|
|
glEnableVertexAttribArray(vertexTCAL);
|
|
glVertexAttribPointer(vertexAL, 3, GL_FLOAT, GL_FALSE, sizeof(objVertexAttribs), offsetof(objVertexAttribs, vertex));
|
|
glVertexAttribPointer(vertexTCAL, 2, GL_UNSIGNED_SHORT, GL_TRUE, sizeof(objVertexAttribs),
|
|
(void*)offsetof(objVertexAttribs, texCoords));
|
|
checkGlError();
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glEnable(GL_DEPTH_TEST);
|
|
checkGlError();
|
|
|
|
bool close = false;
|
|
|
|
while (!close) {
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
switch(event.type) {
|
|
case SDL_KEYDOWN:
|
|
close = true;
|
|
break;
|
|
case SDL_WINDOWEVENT:
|
|
if (event.window.event == SDL_WINDOWEVENT_CLOSE)
|
|
close = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
checkGlError();
|
|
|
|
prog.use();
|
|
glm::mat4 model = glm::rotate(SDL_GetTicks()*0.001f, glm::vec3(1.0f, 0.0f, 0.0f));
|
|
glUniformMatrix4fv(prog.getUniformLocation("modelview_matrix"), 1, GL_FALSE,
|
|
glm::value_ptr(view*model));
|
|
// glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, indices);
|
|
glDrawElements(GL_TRIANGLES, std::get<1>(box).size(), GL_UNSIGNED_SHORT, std::get<1>(box).data());
|
|
checkGlError();
|
|
|
|
// glUniformMatrix4fv(prog.getUniformLocation("modelview_matrix"), 1, GL_FALSE,
|
|
// glm::value_ptr(view));
|
|
// glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, indicesPyramid);
|
|
// checkGlError();
|
|
|
|
// glUseProgram(0);
|
|
// sf::Time now = clock.getElapsedTime();
|
|
// sf::Time elapsed = now - last;
|
|
// last = now;
|
|
// fpsText.setString(std::to_string(static_cast<int>(std::roundf(1.0f/elapsed.asSeconds()))));
|
|
// fpsText.setPosition({1680-fpsText.getLocalBounds().width, 0});
|
|
// window.draw(fpsText);
|
|
|
|
SDL_GL_SwapWindow(window);
|
|
}
|
|
}catch(Exception &ex) {
|
|
std::printf("%s\n", ex.toString().c_str());
|
|
retcode = 1;
|
|
}
|
|
|
|
SDL_GL_DeleteContext(glcontext);
|
|
|
|
SDL_DestroyWindow(window);
|
|
|
|
// Clean up
|
|
SDL_Quit();
|
|
|
|
return retcode;
|
|
}
|