Move a lot of code to classes.
This commit is contained in:
parent
4d5b548ffe
commit
cce4c4bb1a
11 changed files with 258 additions and 61 deletions
|
@ -1,3 +1,6 @@
|
|||
[Buildset]
|
||||
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x10\x00t\x00e\x00s\x00t\x00g\x00a\x00m\x00e)
|
||||
|
||||
[CMake]
|
||||
Build Directory Count=1
|
||||
Current Build Directory Index=0
|
||||
|
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
|
|||
project(testgame)
|
||||
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)
|
||||
add_executable(testgame main.cpp renderer/main.cpp renderer/shader.cpp renderer/shapes/triangle.cpp)
|
||||
INCLUDE(FindPkgConfig)
|
||||
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
|
||||
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS})
|
||||
|
|
76
main.cpp
76
main.cpp
|
@ -3,58 +3,32 @@
|
|||
#include <main.h>
|
||||
#include <SDL.h>
|
||||
#include <GL/glew.h>
|
||||
#include <renderer/shader.h>
|
||||
using namespace std;
|
||||
bool TestGame::init()
|
||||
{
|
||||
GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
|
||||
GLint 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;
|
||||
vs = new VertexShader("shaders/triangle.v.glsl");
|
||||
if(!vs->compile()) {
|
||||
throw nullptr;
|
||||
}
|
||||
//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;
|
||||
fs = new FragmentShader("shaders/triangle.f.glsl");
|
||||
if(!fs->compile()) {
|
||||
throw nullptr;
|
||||
}
|
||||
//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;
|
||||
}
|
||||
vector<Shader *> shaders;
|
||||
shaders.push_back(vs);
|
||||
shaders.push_back(fs);
|
||||
program=link(shaders);
|
||||
//Set attributes
|
||||
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;
|
||||
throw nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -81,23 +55,11 @@ void TestGame::render()
|
|||
|
||||
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);
|
||||
|
||||
t1.render(attribute_coord2d);
|
||||
t2.render(attribute_coord2d);
|
||||
t3.render(attribute_coord2d);
|
||||
|
||||
glDisableVertexAttribArray(attribute_coord2d);
|
||||
|
||||
|
@ -107,6 +69,8 @@ void TestGame::render()
|
|||
TestGame::~TestGame()
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
delete fs;
|
||||
delete vs;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
7
main.h
7
main.h
|
@ -1,15 +1,20 @@
|
|||
#include <renderer/main.h>
|
||||
#include <renderer/shader.h>
|
||||
#include <renderer/shapes/triangle.h>
|
||||
#include <GL/glew.h>
|
||||
class TestGame: public MainClass {
|
||||
private:
|
||||
Triangle t1, t2, t3;
|
||||
GLuint program;
|
||||
GLint attribute_coord2d;
|
||||
auto render() -> void;
|
||||
VertexShader *vs;
|
||||
FragmentShader *fs;
|
||||
protected:
|
||||
virtual auto tick() -> bool;
|
||||
virtual auto init() -> bool;
|
||||
public:
|
||||
TestGame(): MainClass(640,480) {};
|
||||
TestGame(): MainClass(640,480), t1(0.0, 0.0, 0.5, 1.0, 1.0, 0.0), t2(1.0,0.0,1.5,1.0,2.0,0.0), t3(0.5,1.0,1.0,2.0,1.5,1.0) {};
|
||||
virtual ~TestGame();
|
||||
virtual auto stop() -> void;
|
||||
};
|
130
renderer/shader.cpp
Normal file
130
renderer/shader.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
#include <renderer/shader.h>
|
||||
#include <SDL.h>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
Shader::Shader(const char* filename): object(0)
|
||||
{
|
||||
SDL_RWops *rw = SDL_RWFromFile(filename, "rb");
|
||||
if(rw==NULL) throw nullptr; //Load
|
||||
|
||||
Sint64 res_size = SDL_RWsize(rw);
|
||||
shader_contents=new char[res_size+1]; //Allocate
|
||||
|
||||
Sint64 nb_read_total=0, nb_read=1;
|
||||
char* buf = shader_contents;
|
||||
while(nb_read_total < res_size && nb_read != 0 ) { //Read
|
||||
nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total));
|
||||
nb_read_total += nb_read;
|
||||
buf += nb_read;
|
||||
}
|
||||
|
||||
SDL_RWclose(rw); //Cleanup
|
||||
if (nb_read_total != res_size) {
|
||||
delete[] shader_contents;
|
||||
throw nullptr;
|
||||
}
|
||||
shader_contents[nb_read_total] = '\0';
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
delete[] shader_contents;
|
||||
if(object)
|
||||
glDeleteShader(object);
|
||||
}
|
||||
|
||||
Shader::operator GLuint()
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
void Shader::printLog()
|
||||
{
|
||||
printLog(object);
|
||||
}
|
||||
|
||||
void Shader::printLog(GLuint object)
|
||||
{
|
||||
GLint log_length = 0;
|
||||
if(glIsShader(object)) {
|
||||
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
|
||||
} else if(glIsProgram(object)) {
|
||||
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
|
||||
} else {
|
||||
cerr << "printlog: Not a shader or a program" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
char* log = new char[log_length];
|
||||
|
||||
if(glIsShader(object))
|
||||
glGetShaderInfoLog(object, log_length, NULL, log);
|
||||
else
|
||||
glGetProgramInfoLog(object, log_length, NULL, log);
|
||||
|
||||
cerr << log;
|
||||
delete[] log;
|
||||
}
|
||||
auto FragmentShader::compile() -> bool {
|
||||
const GLchar *source = shader_contents;
|
||||
GLuint res = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
const GLchar* sources[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
"#version 100\n" //OpenGL ES 2.0
|
||||
#else
|
||||
"#version 120\n" //OpenGL .1
|
||||
#endif
|
||||
,source };
|
||||
glShaderSource(res, 2, sources, NULL);
|
||||
|
||||
glCompileShader(res);
|
||||
GLint compile_ok = GL_FALSE;
|
||||
glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
|
||||
if(compile_ok == GL_FALSE) {
|
||||
printLog(res);
|
||||
glDeleteShader(res);
|
||||
return false;
|
||||
}
|
||||
object=res;
|
||||
return true;
|
||||
}
|
||||
auto VertexShader::compile() -> bool {
|
||||
const GLchar *source = shader_contents;
|
||||
GLuint res = glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
const GLchar* sources[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
"#version 100\n" //OpenGL ES 2.0
|
||||
#else
|
||||
"#version 120\n" //OpenGL .1
|
||||
#endif
|
||||
,source };
|
||||
glShaderSource(res, 2, sources, NULL);
|
||||
|
||||
glCompileShader(res);
|
||||
GLint compile_ok = GL_FALSE;
|
||||
glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
|
||||
if(compile_ok == GL_FALSE) {
|
||||
printLog(res);
|
||||
glDeleteShader(res);
|
||||
return false;
|
||||
}
|
||||
object=res;
|
||||
return true;
|
||||
}
|
||||
GLuint link(vector< Shader*> &shaders)
|
||||
{
|
||||
GLint link_ok = GL_FALSE;
|
||||
GLuint program=glCreateProgram();
|
||||
for(int i=0;i<shaders.size();i++) {
|
||||
glAttachShader(program, *shaders[i]);
|
||||
}
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
|
||||
if (link_ok==GL_FALSE) {
|
||||
shaders[0]->printLog(program);
|
||||
throw nullptr;
|
||||
}
|
||||
return program;
|
||||
}
|
31
renderer/shader.h
Normal file
31
renderer/shader.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef __RENDERER_SHADER_H
|
||||
#define __RENDERER_SHADER_H
|
||||
#include <GL/glew.h>
|
||||
#include <vector>
|
||||
class Shader {
|
||||
private:
|
||||
Shader() {}
|
||||
protected:
|
||||
char * shader_contents;
|
||||
GLuint object;
|
||||
auto printLog() -> void;
|
||||
public:
|
||||
auto printLog(GLuint object) -> void;
|
||||
Shader(const char* filename);
|
||||
virtual ~Shader();
|
||||
virtual auto compile() -> bool = 0; //Linking is done by the program.
|
||||
virtual operator GLuint();
|
||||
|
||||
};
|
||||
class FragmentShader: public Shader {
|
||||
public:
|
||||
FragmentShader(const char* filename): Shader(filename) {};
|
||||
virtual auto compile() -> bool;
|
||||
};
|
||||
class VertexShader: public Shader {
|
||||
public:
|
||||
VertexShader(const char* filename): Shader(filename) {};
|
||||
virtual auto compile() -> bool;
|
||||
};
|
||||
auto link(std::vector<Shader*> &shaders) -> GLuint;
|
||||
#endif
|
7
renderer/shapes/float2D.h
Normal file
7
renderer/shapes/float2D.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef __SHAPES_FLOAT2D_H
|
||||
#define __SHAPES_FLOAT2D_H
|
||||
struct float2D {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
#endif
|
32
renderer/shapes/triangle.cpp
Normal file
32
renderer/shapes/triangle.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <renderer/shapes/triangle.h>
|
||||
Triangle::Triangle(float x, float y, float alen, float blen, float clen)
|
||||
{
|
||||
A.x=x;
|
||||
A.y=y;
|
||||
|
||||
}
|
||||
Triangle::Triangle(float ax, float ay, float bx, float by, float cx, float cy)
|
||||
{
|
||||
A.x=ax-1.0;
|
||||
A.y=ay-1.0;
|
||||
B.x=bx-1.0;
|
||||
B.y=by-1.0;
|
||||
C.x=cx-1.0;
|
||||
C.y=cy-1.0;
|
||||
}
|
||||
|
||||
Triangle::~Triangle()
|
||||
{
|
||||
|
||||
}
|
||||
bool Triangle::render(GLint attrib)
|
||||
{
|
||||
GLfloat triangle_vertices[] = {
|
||||
A.x, A.y,
|
||||
B.x, B.y,
|
||||
C.x, C.y
|
||||
};
|
||||
glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 0, triangle_vertices);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
return true;
|
||||
}
|
16
renderer/shapes/triangle.h
Normal file
16
renderer/shapes/triangle.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef __SHAPE_TRIANGLE_HPP
|
||||
#define __SHAPE_TRIANGLE_HPP
|
||||
#include <GL/glew.h>
|
||||
#include <renderer/shapes/float2D.h>
|
||||
class Triangle {
|
||||
private:
|
||||
float2D A;
|
||||
float2D B;
|
||||
float2D C; //The three points
|
||||
public:
|
||||
Triangle(float x, float y, float alen, float blen, float clen);
|
||||
Triangle(float ax, float ay, float bx, float by, float cx, float cy);
|
||||
~Triangle();
|
||||
auto render(GLint attrib) -> bool;
|
||||
};
|
||||
#endif
|
5
shaders/triangle.f.glsl
Normal file
5
shaders/triangle.f.glsl
Normal file
|
@ -0,0 +1,5 @@
|
|||
void main(void) {
|
||||
gl_FragColor[0] = 1.0;
|
||||
gl_FragColor[1] = 1.0;
|
||||
gl_FragColor[2] = 0.0;
|
||||
}
|
4
shaders/triangle.v.glsl
Normal file
4
shaders/triangle.v.glsl
Normal file
|
@ -0,0 +1,4 @@
|
|||
attribute vec2 coord2d;
|
||||
void main(void) {
|
||||
gl_Position = vec4(coord2d, 0.0, 1.0);
|
||||
}
|
Loading…
Reference in a new issue