From 4d5b548ffee5cc5d6a1a0336422e44df19e29af1 Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Sat, 27 Aug 2016 21:59:52 +0200 Subject: [PATCH] Can draw a triangle --- .kdev4/testgame.kdev4 | 46 +++++++++++++++++ CMakeLists.txt | 13 +++-- main.cpp | 112 +++++++++++++++++++++++++++++++++++++++++- main.h | 15 ++++++ renderer/main.cpp | 30 +++++++++++ renderer/main.h | 17 +++++++ 6 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 .kdev4/testgame.kdev4 create mode 100644 main.h create mode 100644 renderer/main.cpp create mode 100644 renderer/main.h diff --git a/.kdev4/testgame.kdev4 b/.kdev4/testgame.kdev4 new file mode 100644 index 0000000..28f237b --- /dev/null +++ b/.kdev4/testgame.kdev4 @@ -0,0 +1,46 @@ +[CMake] +Build Directory Count=1 +Current Build Directory Index=0 +ProjectRootRelative=./ + +[CMake][CMake Build Directory 0] +Build Directory Path=file:///usr/home/morten/projects/testgame/build +Build Type=Debug +CMake Binary=file:///usr/local/bin/cmake +Environment Profile= +Extra Arguments= +Install Directory= + +[CustomDefinesAndIncludes][ProjectPath0] +Defines=\x00\x00\x00\x00 +Includes=\x00\x00\x00\x01\x00\x00\x00H\x00/\x00u\x00s\x00r\x00/\x00h\x00o\x00m\x00e\x00/\x00m\x00o\x00r\x00t\x00e\x00n\x00/\x00p\x00r\x00o\x00j\x00e\x00c\x00t\x00s\x00/\x00t\x00e\x00s\x00t\x00g\x00a\x00m\x00e\x00/\x00. +Path=. + +[Defines And Includes][Compiler] +Name=GCC +Path=gcc +Type=GCC + +[Launch] +Launch Configurations=Launch Configuration 0 + +[Launch][Launch Configuration 0] +Configured Launch Modes=execute +Configured Launchers=nativeAppLauncher +Name=testgame +Type=Native Application + +[Launch][Launch Configuration 0][Data] +Arguments= +Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x02\x00\x00\x00\x10\x00t\x00e\x00s\x00t\x00g\x00a\x00m\x00e\x00\x00\x00\x10\x00t\x00e\x00s\x00t\x00g\x00a\x00m\x00e) +Dependency Action=Build +EnvironmentGroup= +Executable=file:///usr/home/morten/projects/testgame/ +External Terminal=konsole --noclose --workdir %workdir -e %exe +Project Target=testgame,testgame +Use External Terminal=false +Working Directory= +isExecutable=false + +[Project] +VersionControlSupport=kdevgit diff --git a/CMakeLists.txt b/CMakeLists.txt index bfc5b7a..7c3bdc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,13 @@ cmake_minimum_required(VERSION 2.6) project(testgame) - -add_executable(testgame main.cpp) - +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -I..") +set(CMAKE_LD_FLAGS "${CMAKE_LD_FLAGS} -L/usr/local/bin") +add_executable(testgame main.cpp renderer/main.cpp) +INCLUDE(FindPkgConfig) +PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2) +INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS}) +find_library(SDL SDL2) +find_library(GLEW GLEW) +find_library(GL GL) +TARGET_LINK_LIBRARIES(testgame ${SDL} ${GLEW} ${GL}) install(TARGETS testgame RUNTIME DESTINATION bin) diff --git a/main.cpp b/main.cpp index 8bb47f1..572c924 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,116 @@ #include +#include +#include +#include +#include +using namespace std; +bool TestGame::init() +{ + GLint compile_ok = GL_FALSE, link_ok = GL_FALSE; + //Compile Vertex shader + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + const char *vs_source = + //"#version 100\n" // OpenGL ES 2.0 + "#version 120\n" // OpenGL 2.1 + "attribute vec2 coord2d; " + "void main(void) { " + " gl_Position = vec4(coord2d, 0.0, 1.0); " + "}"; + glShaderSource(vs, 1, &vs_source, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok); + if (!compile_ok) { + cerr << "Error in vertex shader" << endl; + return false; + } + //Compile Fragment shader + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + const char *fs_source = + //"#version 100\n" // OpenGL ES 2.0 + "#version 120\n" // OpenGL 2.1 + "void main(void) { " + " gl_FragColor[0] = 0.0; " + " gl_FragColor[1] = 0.0; " + " gl_FragColor[2] = 1.0; " + "}"; + glShaderSource(fs, 1, &fs_source, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok); + if (!compile_ok) { + cerr << "Error in fragment shader" << endl; + return false; + } + //Linking + program = glCreateProgram(); + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &link_ok); + if (!link_ok) { + cerr << "Error in glLinkProgram" << endl; + return false; + } + const char* attribute_name = "coord2d"; + attribute_coord2d = glGetAttribLocation(program, attribute_name); + if (attribute_coord2d == -1) { + cerr << "Could not bind attribute " << attribute_name << endl; + return false; + } + + return true; +} +void TestGame::stop() +{ + //To be written +} +bool TestGame::tick() +{ + SDL_Event ev; + while (SDL_PollEvent(&ev)) { + if (ev.type == SDL_QUIT) + return false; + } + render(); + return true; +} +void TestGame::render() +{ + //Clear Background + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(program); + glEnableVertexAttribArray(attribute_coord2d); + GLfloat triangle_vertices[] = { + 0.0, 0.8, + -0.8, -0.8, + 0.8, -0.8, + }; + // Describe our vertices array to OpenGL (it can't guess its format automatically) + glVertexAttribPointer( + attribute_coord2d, // attribute + 2, // number of elements per vertex, here (x,y) + GL_FLOAT, // the type of each element + GL_FALSE, // take our values as-is + 0, // no extra data between each position + triangle_vertices // pointer to the C array + ); + + // Push each element in buffer_vertices to the vertex shader + glDrawArrays(GL_TRIANGLES, 0, 3); + + glDisableVertexAttribArray(attribute_coord2d); + + // Display the result + SDL_GL_SwapWindow(window); +} +TestGame::~TestGame() +{ + glDeleteProgram(program); +} int main(int argc, char **argv) { - std::cout << "Hello, world!" << std::endl; + TestGame game; + game.start(); return 0; } diff --git a/main.h b/main.h new file mode 100644 index 0000000..428c320 --- /dev/null +++ b/main.h @@ -0,0 +1,15 @@ +#include +#include +class TestGame: public MainClass { +private: + GLuint program; + GLint attribute_coord2d; + auto render() -> void; +protected: + virtual auto tick() -> bool; + virtual auto init() -> bool; +public: + TestGame(): MainClass(640,480) {}; + virtual ~TestGame(); + virtual auto stop() -> void; +}; \ No newline at end of file diff --git a/renderer/main.cpp b/renderer/main.cpp new file mode 100644 index 0000000..f856f61 --- /dev/null +++ b/renderer/main.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +using namespace std; +MainClass::MainClass(int width, int height) +{ + SDL_Init(SDL_INIT_VIDEO); + window = SDL_CreateWindow("Testgame", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL); + SDL_GL_CreateContext(window); +} +void MainClass::start() +{ + /* Extension wrangler initialising */ + GLenum glew_status = glewInit(); + if (glew_status != GLEW_OK) { + cerr << "Error: glewInit: " << glewGetErrorString(glew_status) << endl; + throw nullptr; + } + if(!init()) { + cerr << "Error: could not init game!" << endl; + throw nullptr; + } + while(tick()); + stop(); +} +MainClass::~MainClass() +{ + SDL_DestroyWindow(window); + SDL_Quit(); +} diff --git a/renderer/main.h b/renderer/main.h new file mode 100644 index 0000000..4046f03 --- /dev/null +++ b/renderer/main.h @@ -0,0 +1,17 @@ +#ifndef __RENDERER_MAIN_H +#define __RENDERER_MAIN_H +#include +class MainClass { +private: + MainClass() {}; +protected: + SDL_Window* window; + virtual auto tick() -> bool = 0; + virtual auto init() -> bool = 0; +public: + MainClass(int width, int height); + virtual ~MainClass(); + virtual auto start() -> void; + virtual auto stop() -> void =0; +}; +#endif \ No newline at end of file