fixed much stuff with bad usage of constructor mixed with virtual functions in gl stuff. added model loading with assimp.
This commit is contained in:
parent
aedda9d48e
commit
0105bfe430
17 changed files with 402 additions and 175 deletions
45
data/mesh/small_atomic_bomb.scad
Normal file
45
data/mesh/small_atomic_bomb.scad
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
$fn = 12;
|
||||||
|
|
||||||
|
offset = 1.0;
|
||||||
|
|
||||||
|
r_inner = 0.2;
|
||||||
|
r_outer = 0.5;
|
||||||
|
|
||||||
|
rotate([0,0,180]) {
|
||||||
|
|
||||||
|
hull() {
|
||||||
|
// hull around the small base
|
||||||
|
translate([offset, 0, 0]) sphere(r_inner);
|
||||||
|
|
||||||
|
// and the thick head
|
||||||
|
sphere(r_outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe_len=0.3;
|
||||||
|
translate([offset, 0, 0]) {
|
||||||
|
rotate([0,90,0]) cylinder(r=r_inner, pipe_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fins
|
||||||
|
w = 0.5;
|
||||||
|
h = 0.8 * r_outer;
|
||||||
|
|
||||||
|
difference() {
|
||||||
|
// fin
|
||||||
|
for (i=[0:4]) {
|
||||||
|
rotate([i*90,0,0]) {
|
||||||
|
translate([offset-w/2+pipe_len,0,-h/2]) {
|
||||||
|
hull() {
|
||||||
|
cube([w,0.05,0.01], center=true);
|
||||||
|
rotate([0,-5,0]) {
|
||||||
|
cube([w-0.2,0.05,h+0.15], center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cutout part near end of pipe
|
||||||
|
//translate([pipe_len+offset,0,0]) sphere(0.25);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(epoxy REQUIRED)
|
find_package(epoxy REQUIRED)
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED)
|
||||||
|
find_package(assimp REQUIRED)
|
||||||
|
|
||||||
set(GAME_SRC
|
set(GAME_SRC
|
||||||
main.cpp
|
main.cpp
|
||||||
|
@ -34,7 +35,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
include_directories(${OPENGL_INCLUDE_DIR})
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/libs/glm/)
|
include_directories(${CMAKE_SOURCE_DIR}/libs/glm/)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/libs/asio/asio/include/)
|
include_directories(${CMAKE_SOURCE_DIR}/libs/asio/asio/include/)
|
||||||
|
include_directories(${assimp_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_executable(game ${GAME_SRC})
|
add_executable(game ${GAME_SRC})
|
||||||
setup_target(game)
|
setup_target(game)
|
||||||
target_link_libraries(game X11 epoxy pthread)
|
|
||||||
|
target_link_libraries(game X11 epoxy pthread ${assimp_LIBRARIES} assimp)
|
||||||
|
|
|
@ -20,16 +20,20 @@
|
||||||
class GameWindow : public endofthejedi::GLWindow {
|
class GameWindow : public endofthejedi::GLWindow {
|
||||||
private:
|
private:
|
||||||
Game* m_game;
|
Game* m_game;
|
||||||
//endofthejedi::RendererPolygon2d m_renderer;
|
endofthejedi::RendererPolygon2d m_renderer;
|
||||||
//endofthejedi::RendererPolygon3d m_renderer;
|
//endofthejedi::RendererPolygon3d m_renderer;
|
||||||
endofthejedi::RendererRayTracer m_renderer;
|
//endofthejedi::RendererRayTracer m_renderer;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init() override {
|
void init() override {
|
||||||
|
std::cout<<"init" << std::endl;
|
||||||
|
|
||||||
glClearColor(0.5f, 0.6f, 0.7f, 1.0f);
|
glClearColor(0.5f, 0.6f, 0.7f, 1.0f);
|
||||||
resize();
|
resize();
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
m_renderer.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(double time) override {
|
void render(double time) override {
|
||||||
|
|
|
@ -3,75 +3,87 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
endofthejedi::VAO::VAO() { glGenVertexArrays(1, &m_name); }
|
namespace endofthejedi {
|
||||||
|
VAO::VAO() { glGenVertexArrays(1, &m_name); }
|
||||||
|
|
||||||
endofthejedi::VAO::~VAO() { glDeleteVertexArrays(1, &m_name); }
|
VAO::~VAO() { glDeleteVertexArrays(1, &m_name); }
|
||||||
|
|
||||||
void endofthejedi::VAO::bind() { glBindVertexArray(m_name); }
|
void VAO::bind() { glBindVertexArray(m_name); }
|
||||||
|
|
||||||
void endofthejedi::VAO::fill(GLuint index, GLint size, GLenum type,
|
void VAO::fill(GLuint index, GLint size, GLenum type,
|
||||||
GLboolean normalized, GLsizei stride,
|
GLboolean normalized, GLsizei stride,
|
||||||
const GLvoid *pointer) {
|
const GLvoid *pointer)
|
||||||
glEnableVertexAttribArray(index);
|
{
|
||||||
glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride, pointer);
|
(void) type;
|
||||||
}
|
|
||||||
|
|
||||||
endofthejedi::Shader::Shader() { m_program = glCreateProgram(); }
|
glEnableVertexAttribArray(index);
|
||||||
|
glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride, pointer);
|
||||||
endofthejedi::Shader::~Shader() {}
|
|
||||||
|
|
||||||
bool endofthejedi::Shader::check() {
|
|
||||||
GLint len = 0;
|
|
||||||
GLint result = 0;
|
|
||||||
|
|
||||||
glGetProgramiv(m_program, GL_LINK_STATUS, &result);
|
|
||||||
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &len);
|
|
||||||
if (len > 1) {
|
|
||||||
char *error = (char *)malloc(len);
|
|
||||||
glGetProgramInfoLog(m_program, len, NULL, error);
|
|
||||||
std::string str(error);
|
|
||||||
std::cout << str << "\n";
|
|
||||||
}
|
}
|
||||||
std::cout << "checked program"
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
return (bool)result;
|
Shader::Shader() : m_program(0) { }
|
||||||
}
|
|
||||||
|
|
||||||
bool endofthejedi::Shader::checkShader(GLuint shader) {
|
Shader::~Shader() {}
|
||||||
GLint len = 0;
|
|
||||||
GLint result = 0;
|
|
||||||
|
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
|
void Shader::init() { m_program = glCreateProgram(); }
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
|
||||||
if (len > 1) {
|
bool Shader::check() {
|
||||||
char *error = (char *)malloc(len+1);
|
GLint len = 0;
|
||||||
glGetShaderInfoLog(shader, 0, &len, error);
|
GLint result = 0;
|
||||||
std::string str(error, error + len);
|
|
||||||
std::cout << str << "\n";
|
glGetProgramiv(m_program, GL_LINK_STATUS, &result);
|
||||||
|
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &len);
|
||||||
|
if (len > 1) {
|
||||||
|
char *error = (char *)malloc(len);
|
||||||
|
glGetProgramInfoLog(m_program, len, NULL, error);
|
||||||
|
std::string str(error);
|
||||||
|
std::cout << str << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "checked program" << std::endl;
|
||||||
|
|
||||||
|
return (bool)result;
|
||||||
}
|
}
|
||||||
std::cout << "checked shader"
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
return (bool)result;
|
bool Shader::checkShader(GLuint shader) {
|
||||||
}
|
GLint len = 0;
|
||||||
|
GLint result = 0;
|
||||||
void endofthejedi::Shader::bind() { glUseProgram(m_program); }
|
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
|
||||||
void endofthejedi::Shader::unbind() { glUseProgram(0); }
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||||
|
if (len > 1) {
|
||||||
void endofthejedi::Shader::load(std::string path, GLenum shadertype) {
|
char *error = (char *)malloc(len+1);
|
||||||
GLuint cheddar = glCreateShader(shadertype);
|
glGetShaderInfoLog(shader, 0, &len, error);
|
||||||
const char *cheddardata = path.c_str();
|
std::string str(error, error + len);
|
||||||
glShaderSource(cheddar, 1, &cheddardata, NULL);
|
std::cout << str << std::endl;
|
||||||
glCompileShader(cheddar);
|
}
|
||||||
checkShader(cheddar);
|
|
||||||
glAttachShader(m_program, cheddar);
|
std::cout << "checked shader" << std::endl;
|
||||||
glLinkProgram(m_program);
|
|
||||||
check();
|
return (bool)result;
|
||||||
glDeleteShader(cheddar);
|
}
|
||||||
}
|
|
||||||
|
void Shader::bind() { glUseProgram(m_program); }
|
||||||
GLuint endofthejedi::Shader::location(std::string name) {
|
|
||||||
return glGetUniformLocation(m_program, name.c_str());
|
void Shader::unbind() { glUseProgram(0); }
|
||||||
|
|
||||||
|
void Shader::load(const std::string &path, GLenum shadertype) {
|
||||||
|
if (m_program == 0) {
|
||||||
|
std::cout<<"[shader] error: shader program is invalid (0)!" << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint cheddar = glCreateShader(shadertype);
|
||||||
|
const char *cheddardata = path.c_str();
|
||||||
|
glShaderSource(cheddar, 1, &cheddardata, NULL);
|
||||||
|
glCompileShader(cheddar);
|
||||||
|
checkShader(cheddar);
|
||||||
|
glAttachShader(m_program, cheddar);
|
||||||
|
glLinkProgram(m_program);
|
||||||
|
check();
|
||||||
|
glDeleteShader(cheddar);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Shader::location(const std::string &name) {
|
||||||
|
return glGetUniformLocation(m_program, name.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ class VAO {
|
||||||
class Shader {
|
class Shader {
|
||||||
private:
|
private:
|
||||||
GLuint m_program;
|
GLuint m_program;
|
||||||
|
|
||||||
bool check();
|
bool check();
|
||||||
bool checkShader(GLuint shader);
|
bool checkShader(GLuint shader);
|
||||||
|
|
||||||
|
@ -50,10 +51,12 @@ class Shader {
|
||||||
public:
|
public:
|
||||||
Shader();
|
Shader();
|
||||||
~Shader();
|
~Shader();
|
||||||
|
void init(); // call to init when opengl context exists
|
||||||
|
|
||||||
void bind();
|
void bind();
|
||||||
void unbind();
|
void unbind();
|
||||||
void load(std::string data, GLenum shadertype);
|
void load(const std::string &data, GLenum shadertype);
|
||||||
GLuint location(std::string name);
|
GLuint location(const std::string &name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
GameWindow window(500, 500, &game);
|
GameWindow window(500, 500, &game);
|
||||||
window.set_maxfps(60.0);
|
window.set_maxfps(60.0);
|
||||||
|
window.open();
|
||||||
|
|
||||||
while(window.running()){
|
while(window.running()){
|
||||||
window.poll();
|
window.poll();
|
||||||
|
|
211
game/opengl.cpp
211
game/opengl.cpp
|
@ -19,117 +19,126 @@ timespec diff(timespec start, timespec end) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
endofthejedi::GLWindow::GLWindow(unsigned int width, unsigned int height)
|
namespace endofthejedi {
|
||||||
: m_width(width), m_height(height) {
|
|
||||||
m_display = XOpenDisplay(NULL);
|
|
||||||
|
|
||||||
if (m_display == NULL) {
|
GLWindow::GLWindow(unsigned int width, unsigned int height) : m_width(width), m_height(height)
|
||||||
throw std::runtime_error("XOpenDisplay NULL");
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rootwnd = DefaultRootWindow(m_display);
|
void GLWindow::open()
|
||||||
|
{
|
||||||
|
m_display = XOpenDisplay(NULL);
|
||||||
|
|
||||||
m_visualinfo = glXChooseVisual(m_display, 0, m_attributes);
|
if (m_display == NULL) {
|
||||||
|
throw std::runtime_error("XOpenDisplay NULL");
|
||||||
|
}
|
||||||
|
|
||||||
if (m_visualinfo == NULL) {
|
m_rootwnd = DefaultRootWindow(m_display);
|
||||||
throw std::runtime_error("glXChooseVisual NULL");
|
|
||||||
|
m_visualinfo = glXChooseVisual(m_display, 0, m_attributes);
|
||||||
|
|
||||||
|
if (m_visualinfo == NULL) {
|
||||||
|
throw std::runtime_error("glXChooseVisual NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_colormap =
|
||||||
|
XCreateColormap(m_display, m_rootwnd, m_visualinfo->visual, AllocNone);
|
||||||
|
|
||||||
|
m_swa.colormap = m_colormap;
|
||||||
|
m_swa.event_mask = ExposureMask | KeyPressMask;
|
||||||
|
|
||||||
|
m_window = XCreateWindow(
|
||||||
|
m_display, m_rootwnd, 0, 0, m_width, m_height, 0, m_visualinfo->depth,
|
||||||
|
InputOutput, m_visualinfo->visual, CWColormap | CWEventMask, &m_swa);
|
||||||
|
|
||||||
|
m_atomWmDeleteWindow = XInternAtom(m_display, "WM_DELETE_WINDOW", False);
|
||||||
|
XSetWMProtocols(m_display, m_window, &m_atomWmDeleteWindow, 1);
|
||||||
|
|
||||||
|
XMapWindow(m_display, m_window);
|
||||||
|
XStoreName(m_display, m_window, "NAME");
|
||||||
|
|
||||||
|
m_glcontext = glXCreateContext(m_display, m_visualinfo, NULL, GL_TRUE);
|
||||||
|
|
||||||
|
XSync(m_display, False);
|
||||||
|
|
||||||
|
glXMakeCurrent(m_display, m_window, m_glcontext);
|
||||||
|
|
||||||
|
std::cout << "GL Renderer: " << glGetString(GL_RENDERER) << "\n";
|
||||||
|
std::cout << "GL Version: " << glGetString(GL_VERSION) << "\n";
|
||||||
|
std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION)
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
m_running = true;
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
XClearWindow(m_display, m_window);
|
||||||
|
XMapRaised(m_display, m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_colormap =
|
GLWindow::~GLWindow() {
|
||||||
XCreateColormap(m_display, m_rootwnd, m_visualinfo->visual, AllocNone);
|
glXMakeCurrent(m_display, None, NULL);
|
||||||
|
glXDestroyContext(m_display, m_glcontext);
|
||||||
m_swa.colormap = m_colormap;
|
XFree(m_visualinfo);
|
||||||
m_swa.event_mask = ExposureMask | KeyPressMask;
|
XDestroyWindow(m_display, m_window);
|
||||||
|
XCloseDisplay(m_display);
|
||||||
m_window = XCreateWindow(
|
|
||||||
m_display, m_rootwnd, 0, 0, width, height, 0, m_visualinfo->depth,
|
|
||||||
InputOutput, m_visualinfo->visual, CWColormap | CWEventMask, &m_swa);
|
|
||||||
|
|
||||||
m_atomWmDeleteWindow = XInternAtom(m_display, "WM_DELETE_WINDOW", False);
|
|
||||||
XSetWMProtocols(m_display, m_window, &m_atomWmDeleteWindow, 1);
|
|
||||||
|
|
||||||
XMapWindow(m_display, m_window);
|
|
||||||
XStoreName(m_display, m_window, "NAME");
|
|
||||||
|
|
||||||
m_glcontext = glXCreateContext(m_display, m_visualinfo, NULL, GL_TRUE);
|
|
||||||
|
|
||||||
XSync(m_display, False);
|
|
||||||
|
|
||||||
glXMakeCurrent(m_display, m_window, m_glcontext);
|
|
||||||
|
|
||||||
std::cout << "GL Renderer: " << glGetString(GL_RENDERER) << "\n";
|
|
||||||
std::cout << "GL Version: " << glGetString(GL_VERSION) << "\n";
|
|
||||||
std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION)
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
XClearWindow(m_display, m_window);
|
|
||||||
XMapRaised(m_display, m_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
endofthejedi::GLWindow::~GLWindow() {
|
|
||||||
glXMakeCurrent(m_display, None, NULL);
|
|
||||||
glXDestroyContext(m_display, m_glcontext);
|
|
||||||
XFree(m_visualinfo);
|
|
||||||
XDestroyWindow(m_display, m_window);
|
|
||||||
XCloseDisplay(m_display);
|
|
||||||
}
|
|
||||||
|
|
||||||
void endofthejedi::GLWindow::handleevents() {
|
|
||||||
if (XPending(m_display) > 0) {
|
|
||||||
XEvent xev;
|
|
||||||
XNextEvent(m_display, &xev);
|
|
||||||
handle(xev);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void endofthejedi::GLWindow::handle(XEvent event) {
|
void GLWindow::handleevents() {
|
||||||
if (event.type == Expose) {
|
if (XPending(m_display) > 0) {
|
||||||
XWindowAttributes attribs;
|
XEvent xev;
|
||||||
XGetWindowAttributes(m_display, m_window, &attribs);
|
XNextEvent(m_display, &xev);
|
||||||
m_width = attribs.width;
|
handle(xev);
|
||||||
m_height = attribs.height;
|
}
|
||||||
resize();
|
}
|
||||||
} else if (event.type == ClientMessage) {
|
|
||||||
if (event.xclient.data.l[0] == m_atomWmDeleteWindow) {
|
void GLWindow::handle(XEvent event) {
|
||||||
|
if (event.type == Expose) {
|
||||||
|
XWindowAttributes attribs;
|
||||||
|
XGetWindowAttributes(m_display, m_window, &attribs);
|
||||||
|
m_width = attribs.width;
|
||||||
|
m_height = attribs.height;
|
||||||
|
resize();
|
||||||
|
} else if (event.type == ClientMessage) {
|
||||||
|
if (event.xclient.data.l[0] == m_atomWmDeleteWindow) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
} else if (event.type == DestroyNotify) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
} else if (event.type == DestroyNotify) {
|
|
||||||
stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLWindow::swap() { glXSwapBuffers(m_display, m_window); }
|
||||||
|
|
||||||
|
void GLWindow::poll() {
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &prev);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);
|
||||||
|
|
||||||
|
handleevents();
|
||||||
|
render(delta);
|
||||||
|
swap();
|
||||||
|
|
||||||
|
if (m_maxfps > 0) {
|
||||||
|
sleeptime = ((1000000000.0/m_maxfps) - delta) + sleeptime;
|
||||||
|
if (sleeptime > 0.0) {
|
||||||
|
usleep((unsigned int)(sleeptime/1000.0));
|
||||||
|
sleeptime = sleeptime - (unsigned int)(sleeptime/1000.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);
|
||||||
|
delta = diff(prev, current).tv_nsec;
|
||||||
|
prev = current;
|
||||||
|
if(delta > 0.0) {
|
||||||
|
m_fps = (1000000000.0/delta);
|
||||||
|
//std::cout << m_fps << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLWindow::stop() { m_running = false; }
|
||||||
|
bool GLWindow::running() { return m_running; }
|
||||||
|
void GLWindow::init() { }
|
||||||
|
void GLWindow::render(double time) { UNUSED(time) }
|
||||||
|
void GLWindow::resize() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void endofthejedi::GLWindow::swap() { glXSwapBuffers(m_display, m_window); }
|
|
||||||
|
|
||||||
void endofthejedi::GLWindow::poll() {
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &prev);
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);
|
|
||||||
|
|
||||||
handleevents();
|
|
||||||
render(delta);
|
|
||||||
swap();
|
|
||||||
|
|
||||||
if (m_maxfps > 0) {
|
|
||||||
sleeptime = ((1000000000.0/m_maxfps) - delta) + sleeptime;
|
|
||||||
if (sleeptime > 0.0) {
|
|
||||||
usleep((unsigned int)(sleeptime/1000.0));
|
|
||||||
sleeptime = sleeptime - (unsigned int)(sleeptime/1000.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);
|
|
||||||
delta = diff(prev, current).tv_nsec;
|
|
||||||
prev = current;
|
|
||||||
if(delta > 0.0) {
|
|
||||||
m_fps = (1000000000.0/delta);
|
|
||||||
//std::cout << m_fps << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void endofthejedi::GLWindow::stop() { m_running = false; }
|
|
||||||
bool endofthejedi::GLWindow::running() { return m_running; }
|
|
||||||
void endofthejedi::GLWindow::init() { m_running = true; }
|
|
||||||
void endofthejedi::GLWindow::render(double time) { UNUSED(time) }
|
|
||||||
void endofthejedi::GLWindow::resize() {}
|
|
||||||
|
|
|
@ -67,10 +67,14 @@ namespace endofthejedi {
|
||||||
virtual void handleevents();
|
virtual void handleevents();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//initializes the X Window & creates an OpenGL context
|
// create the class. call open() afterwards
|
||||||
GLWindow(unsigned int width, unsigned int height);
|
GLWindow(unsigned int width, unsigned int height);
|
||||||
|
|
||||||
~GLWindow();
|
~GLWindow();
|
||||||
|
|
||||||
|
//initializes the X Window & creates an OpenGL context
|
||||||
|
void open();
|
||||||
|
|
||||||
//mainloop does event handling & calls render/swap
|
//mainloop does event handling & calls render/swap
|
||||||
void poll();
|
void poll();
|
||||||
void swap();
|
void swap();
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
#include "renderer_polygon_2d.hpp"
|
#include "renderer_polygon_2d.hpp"
|
||||||
|
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
|
void RendererPolygon2d::setup()
|
||||||
|
{
|
||||||
|
// (dark grey) bg
|
||||||
|
float r = 0.1;
|
||||||
|
float g = 0.1;
|
||||||
|
float b = 0.1;
|
||||||
|
glClearColor(r, g, b, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
void RendererPolygon2d::drawCircle(float x, float y, float radius,
|
void RendererPolygon2d::drawCircle(float x, float y, float radius,
|
||||||
float r, float g, float b,
|
float r, float g, float b,
|
||||||
int numSides) {
|
int numSides) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
|
|
||||||
class RendererPolygon2d : Renderer {
|
class RendererPolygon2d : public Renderer {
|
||||||
private:
|
private:
|
||||||
void drawCircle(float x, float y, float radius, float r, float g,
|
void drawCircle(float x, float y, float radius, float r, float g,
|
||||||
float b, int numSides = 12);
|
float b, int numSides = 12);
|
||||||
|
@ -27,7 +27,9 @@ namespace endofthejedi {
|
||||||
void drawExplosion(const game::Explosion *explosion);
|
void drawExplosion(const game::Explosion *explosion);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void setup() override;
|
||||||
void render(const game::State *state) override;
|
void render(const game::State *state) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
0
game/renderer_polygon_3d/polygon_model.cpp
Normal file
0
game/renderer_polygon_3d/polygon_model.cpp
Normal file
116
game/renderer_polygon_3d/polygon_model.hpp
Normal file
116
game/renderer_polygon_3d/polygon_model.hpp
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <assimp/Importer.hpp> // C++ importer interface
|
||||||
|
#include <assimp/scene.h> // Output data structure
|
||||||
|
#include <assimp/postprocess.h> // Post processing flags
|
||||||
|
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
#include <epoxy/glx.h>
|
||||||
|
|
||||||
|
class PolygonModel {
|
||||||
|
public:
|
||||||
|
PolygonModel(const std::string &filename) : m_filename(filename)
|
||||||
|
{
|
||||||
|
if (!import()) {
|
||||||
|
m_loaded = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
m_loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool import()
|
||||||
|
{
|
||||||
|
// Create an instance of the Importer class
|
||||||
|
Assimp::Importer importer;
|
||||||
|
// And have it read the given file with some example postprocessing
|
||||||
|
// Usually - if speed is not the most important aspect for you - you'll
|
||||||
|
// propably to request more postprocessing than we do in this example.
|
||||||
|
const aiScene* scene = importer.ReadFile(m_filename,
|
||||||
|
aiProcess_CalcTangentSpace |
|
||||||
|
aiProcess_Triangulate |
|
||||||
|
aiProcess_JoinIdenticalVertices |
|
||||||
|
aiProcess_SortByPType);
|
||||||
|
|
||||||
|
// If the import failed, report it
|
||||||
|
if (!scene) {
|
||||||
|
std::cout<<"[polygonmodel] loading file "
|
||||||
|
<< m_filename << " failed with: "
|
||||||
|
<< importer.GetErrorString() << std::endl;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we can access the file's contents.
|
||||||
|
copyVertices(scene);
|
||||||
|
|
||||||
|
// We're done. Everything will be cleaned up by the importer destructor
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool copyVertices(const aiScene *scene)
|
||||||
|
{
|
||||||
|
if (scene->mMeshes == 0) {
|
||||||
|
std::cout << "[polygonmodel : no meshes loaded for " << m_filename << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiNode *node = scene->mRootNode;
|
||||||
|
const aiMesh* mesh = scene->mMeshes[node->mMeshes[0]];
|
||||||
|
|
||||||
|
// 3 vertices per face, 3 floats per vertex
|
||||||
|
m_numVertices = mesh->mNumFaces*3;
|
||||||
|
|
||||||
|
m_data_position.reserve(m_numVertices);
|
||||||
|
m_data_normal.reserve(m_numVertices);
|
||||||
|
|
||||||
|
size_t t, i;
|
||||||
|
for (t=0; t<mesh->mNumFaces; ++t) {
|
||||||
|
const aiFace* face = &mesh->mFaces[t];
|
||||||
|
if (face->mNumIndices != 3) {
|
||||||
|
std::cout << "[polygonmodel] need triangles, got something different with: "
|
||||||
|
<< face->mNumIndices << " vertices" << std::endl;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<face->mNumIndices; i++) {
|
||||||
|
const size_t index = face->mIndices[i];
|
||||||
|
m_data_position.push_back(mesh->mVertices[index].x);
|
||||||
|
m_data_position.push_back(mesh->mVertices[index].y);
|
||||||
|
m_data_position.push_back(mesh->mVertices[index].z);
|
||||||
|
|
||||||
|
m_data_normal.push_back(mesh->mNormals[index].x);
|
||||||
|
m_data_normal.push_back(mesh->mNormals[index].y);
|
||||||
|
m_data_normal.push_back(mesh->mNormals[index].z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t totalBytes = 3*m_numVertices*sizeof(float);
|
||||||
|
std::cout<<"[polygonmodel] loaded " << m_numVertices << " vertices ("
|
||||||
|
<< totalBytes << " bytes)" << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &filename() const { return m_filename; }
|
||||||
|
bool ready() const { return m_loaded; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_filename;
|
||||||
|
bool m_loaded;
|
||||||
|
|
||||||
|
size_t m_numVertices;
|
||||||
|
|
||||||
|
// both will hold 3 * numVertices floats
|
||||||
|
std::vector<float> m_data_position;
|
||||||
|
std::vector<float> m_data_normal;
|
||||||
|
|
||||||
|
GLuint m_vbo_id_position;
|
||||||
|
GLuint m_vbo_id_normal;
|
||||||
|
};
|
||||||
|
|
|
@ -2,16 +2,21 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "polygon_model.hpp"
|
||||||
|
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
void RendererPolygon3d::setup()
|
void RendererPolygon3d::setup()
|
||||||
{
|
{
|
||||||
std::cout<<"setup 3d" << std::endl;
|
std::cout<<"setup 3d" << std::endl;
|
||||||
|
|
||||||
|
PolygonModel atomicBomb("../data/mesh/small_atomic_bomb.stl");
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererPolygon3d::render(const game::State *state)
|
void RendererPolygon3d::render(const game::State *state)
|
||||||
{
|
{
|
||||||
(void) state;
|
(void) state;
|
||||||
|
|
||||||
//std::cout<<"render 3d" << std::endl;
|
std::cout<<"render 3d" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,18 @@
|
||||||
#include "state/ship.hpp"
|
#include "state/ship.hpp"
|
||||||
#include "state/explosion.hpp"
|
#include "state/explosion.hpp"
|
||||||
|
|
||||||
|
class PolygonModel;
|
||||||
|
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
|
|
||||||
class RendererPolygon3d : Renderer {
|
class RendererPolygon3d : public Renderer {
|
||||||
private:
|
private:
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
void setup();
|
void setup();
|
||||||
void render(const game::State *state) override;
|
void render(const game::State *state) override;
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<PolygonModel*> m_models;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,13 @@ static const char *fss =
|
||||||
|
|
||||||
|
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
RendererRayTracer::RendererRayTracer() {
|
RendererRayTracer::RendererRayTracer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererRayTracer::setup()
|
||||||
|
{
|
||||||
|
m_shader.init();
|
||||||
m_shader.load(vss, GL_VERTEX_SHADER);
|
m_shader.load(vss, GL_VERTEX_SHADER);
|
||||||
m_shader.load(fss, GL_FRAGMENT_SHADER);
|
m_shader.load(fss, GL_FRAGMENT_SHADER);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
|
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
|
|
||||||
class RendererRayTracer: Renderer {
|
class RendererRayTracer : public Renderer {
|
||||||
private:
|
private:
|
||||||
Shader m_shader;
|
Shader m_shader;
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
RendererRayTracer();
|
RendererRayTracer();
|
||||||
|
|
||||||
|
void setup() override;
|
||||||
void render(const game::State *state) override;
|
void render(const game::State *state) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ namespace game {
|
||||||
// TODO: idea
|
// TODO: idea
|
||||||
// shoot multiple rockets at once or from different positions after
|
// shoot multiple rockets at once or from different positions after
|
||||||
// level up / upgrade ...
|
// level up / upgrade ...
|
||||||
Missile *missile = new Missile(player, player->ship->position, util::deg2rad(m_angle), player->speed);
|
|
||||||
|
// angles are supplied in degrees and are CCW
|
||||||
|
Missile *missile = new Missile(player, player->ship->position, -util::deg2rad(m_angle), player->speed);
|
||||||
|
|
||||||
Trace *trace = new Trace(missile);
|
Trace *trace = new Trace(missile);
|
||||||
missile->trace = trace;
|
missile->trace = trace;
|
||||||
|
|
Loading…
Reference in a new issue