-
-
Save davertron/916742 to your computer and use it in GitHub Desktop.
#ifdef WIN32 | |
# include "windows.h" | |
#endif | |
#include <iostream> | |
#include <sstream> | |
#include <fstream> | |
#include <cstdlib> | |
#include <ctime> | |
#include <GL/glew.h> | |
#include <GL/glut.h> | |
#include <SDL/SDL.h> | |
#define W_WIDTH 800 | |
#define W_HEIGHT 600 | |
using namespace std; | |
// GLOBALS | |
bool key[321]; | |
int FRAMES = 0; | |
float FPS = 0; | |
time_t LAST_FRAME_TIME; | |
float texture_offsets[50]; | |
GLuint frag_shader_id; | |
GLuint vert_shader_id; | |
GLuint shader_program_id; | |
GLuint tex_id; | |
GLuint fbo_id; | |
bool loadShaderSource(const string& filename, string &source){ | |
std::ifstream file; | |
file.open(filename.c_str()); | |
if(!file){ | |
return false; | |
} | |
std::stringstream stream; | |
stream << file.rdbuf(); | |
file.close(); | |
source = stream.str(); | |
return true; | |
} | |
void updateFPS(){ | |
FRAMES++; | |
time_t now = time(NULL); | |
time_t difference = now - LAST_FRAME_TIME; | |
if(difference >= 1){ | |
float percentOfSecond = 1 / difference; | |
LAST_FRAME_TIME = now; | |
FPS = percentOfSecond * FRAMES; | |
FRAMES = 0; | |
} | |
} | |
void applicationInit(){ | |
LAST_FRAME_TIME = time(NULL); | |
// Seed random number generator | |
srand((unsigned)time(0)); | |
// Set up kernel weights and calculate texture offsets | |
const int KERNEL_SIZE = 9; | |
const float step_w = 1.0 / W_WIDTH; | |
const float step_h = 1.0 / W_HEIGHT; | |
const GLfloat kernel_weights[KERNEL_SIZE] = { | |
1.0/16.0, 2.0/16.0, 1.0/16.0, | |
2.0/16.0, 4.0/16.0, 2.0/16.0, | |
1.0/16.0, 2.0/16.0, 1.0/16.0 | |
}; | |
const GLfloat texture_offsets[KERNEL_SIZE * 2] = { | |
-step_w, -step_h, | |
0.0, -step_h, | |
step_w, -step_h, | |
-step_w, 0.0, | |
0.0, 0.0, | |
step_w, 0.0, | |
-step_w, step_h, | |
0.0, step_h, | |
step_w, step_h | |
}; | |
GLuint kw = glGetUniformLocation(shader_program_id, "kernel_weights"); | |
GLuint to = glGetUniformLocation(shader_program_id, "texture_offsets"); | |
glUseProgram(shader_program_id); | |
glUniform1fv(kw, 9, kernel_weights); | |
glUniform2fv(to, 9, texture_offsets); | |
glUseProgram(0); | |
} | |
bool events(){ | |
SDL_Event event; | |
int keycode; | |
if(SDL_PollEvent(&event)){ | |
switch(event.type){ | |
case SDL_KEYDOWN: | |
keycode = event.key.keysym.sym; | |
switch(keycode){ | |
case SDLK_q: | |
return false; | |
break; | |
} | |
break; | |
case SDL_QUIT: | |
return false; | |
break; | |
} | |
} | |
return true; | |
} | |
void setupProjection(){ | |
glViewport(0, 0, W_WIDTH, W_HEIGHT); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glOrtho(0, 20, 20, 0, 0, 1); | |
glMatrixMode(GL_MODELVIEW); | |
} | |
void renderBitmapString(float x, float y, float z, void *font, char *string){ | |
char *c; | |
glRasterPos3f(x, y, z); | |
for(c=string; *c != '\0'; c++){ | |
glutBitmapCharacter(font, *c); | |
} | |
} | |
void drawFPS(){ | |
char fpsString[99]; | |
sprintf(fpsString, "FPS: %4.2f", FPS); | |
glLineWidth(1.0); | |
glColor3f(16.0/255.0, 237.0/255.0, 5.0/255.0); | |
renderBitmapString(0.0, 1.0, 0.0, GLUT_BITMAP_HELVETICA_18, fpsString); | |
} | |
void drawSquares(){ | |
glBegin(GL_QUADS); | |
glColor3f(1.0, 1.0, 1.0); | |
glVertex3f(3.0, 3.0, 0.0); | |
glVertex3f(15.0, 3.0, 0.0); | |
glVertex3f(15.0, 15.0, 0.0); | |
glVertex3f(3.0, 15.0, 0.0); | |
glColor3f(0.0, 1.0, 0.75); | |
glVertex3f(6.0, 6.0, 0.0); | |
glVertex3f(18.0, 6.0, 0.0); | |
glVertex3f(18.0, 18.0, 0.0); | |
glVertex3f(6.0, 18.0, 0.0); | |
glEnd(); | |
} | |
void update(){ | |
updateFPS(); | |
} | |
void drawTexturedQuad(){ | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glViewport(0, 0, W_WIDTH, W_HEIGHT); | |
glOrtho(0, 1, 1, 0, 0, 1); | |
glMatrixMode(GL_MODELVIEW); | |
glBindTexture(GL_TEXTURE_2D, tex_id); | |
glColor3f(1.0, 1.0, 1.0); | |
glBegin(GL_QUADS); | |
glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 0.0); | |
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 0.0); | |
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 1.0); | |
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 1.0); | |
glEnd(); | |
glBindTexture(GL_TEXTURE_2D, 0); | |
} | |
void draw(){ | |
setupProjection(); | |
// Bind and render to FBO | |
glBindFramebuffer(GL_FRAMEBUFFER, fbo_id); | |
glClear(GL_COLOR_BUFFER_BIT); | |
glMatrixMode(GL_MODELVIEW); | |
drawSquares(); | |
drawFPS(); | |
// Unbind FBO, data is now in a texture, use our shader to blur it and | |
// render it to a quad | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glUseProgram(shader_program_id); | |
drawTexturedQuad(); | |
glUseProgram(0); | |
} | |
void main_loop_function(){ | |
while(events()){ | |
update(); | |
draw(); | |
SDL_GL_SwapBuffers(); | |
} | |
} | |
// Initialize OpenGL perspective matrix | |
void GL_Setup(int width, int height){ | |
glViewport(0, 0, width, height); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glOrtho(0, 20, 20, 0, 0, 1); | |
glMatrixMode(GL_MODELVIEW); | |
glClearColor(0.0, 0.0, 0.0, 0.0); | |
// Load gaussian blur shader | |
string gaussian_vert; | |
string gaussian_frag; | |
if(loadShaderSource("gaussian.vs", gaussian_vert) && loadShaderSource("gauss2.fs", gaussian_frag)){ | |
const char* frag_source = gaussian_frag.c_str(); | |
const char* vert_source = gaussian_vert.c_str(); | |
vert_shader_id = glCreateShader(GL_VERTEX_SHADER); | |
frag_shader_id = glCreateShader(GL_FRAGMENT_SHADER); | |
int status; | |
glShaderSource(vert_shader_id, 1, &vert_source, NULL); | |
glCompileShader(vert_shader_id); | |
glGetShaderiv(vert_shader_id, GL_COMPILE_STATUS, &status); | |
if(status == GL_FALSE){ | |
int logLength; | |
GLcharARB *log; | |
log = new GLcharARB[1024]; | |
glGetInfoLogARB(shader_program_id, 1024, &logLength, log); | |
if(logLength > 0){ | |
cout << "Shader info: " << log << endl; | |
exit(-1); | |
} | |
} | |
glShaderSource(frag_shader_id, 1, &frag_source, NULL); | |
glCompileShader(frag_shader_id); | |
glGetShaderiv(vert_shader_id, GL_COMPILE_STATUS, &status); | |
if(status == GL_FALSE){ | |
int logLength; | |
GLcharARB *log; | |
log = new GLcharARB[1024]; | |
glGetInfoLogARB(shader_program_id, 1024, &logLength, log); | |
if(logLength > 0){ | |
cout << "Shader info: " << log << endl; | |
exit(-1); | |
} | |
} | |
shader_program_id = glCreateProgram(); | |
glAttachShader(shader_program_id, vert_shader_id); | |
glAttachShader(shader_program_id, frag_shader_id); | |
glLinkProgram(shader_program_id); | |
int logLength; | |
GLcharARB *log; | |
log = new GLcharARB[1024]; | |
glGetProgramInfoLog(shader_program_id, 1024, &logLength, log); | |
if(logLength > 0){ | |
cout << "Program info: " << log << endl; | |
exit(-1); | |
} | |
} else { | |
cout << "Could not load shader." << endl; | |
exit(-1); | |
} | |
// Enable texturing and create a texture object that we'll later attach to | |
// our FBO | |
glEnable(GL_TEXTURE_2D); | |
glGenTextures(1, &tex_id); | |
glBindTexture(GL_TEXTURE_2D, tex_id); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
// Create fbo | |
glGenFramebuffers(1, &fbo_id); | |
glBindFramebuffer(GL_FRAMEBUFFER, fbo_id); | |
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glBindTexture(GL_TEXTURE_2D, 0); | |
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); | |
if(status != GL_FRAMEBUFFER_COMPLETE){ | |
cout << "Fucked up the framebuffer setup dude: " << status << endl; | |
exit(-2); | |
} | |
} | |
int main(int argc, char** argv){ | |
if(SDL_Init(SDL_INIT_VIDEO) != 0){ | |
printf("Unable to initialize SDL: %s\n", SDL_GetError()); | |
} | |
const SDL_VideoInfo* info = SDL_GetVideoInfo(); | |
int vidFlags = SDL_OPENGL; | |
if(info->hw_available){ | |
vidFlags |= SDL_HWSURFACE; | |
} else { | |
vidFlags |= SDL_SWSURFACE; | |
} | |
int bpp = info->vfmt->BitsPerPixel; | |
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | |
SDL_SetVideoMode(W_WIDTH, W_HEIGHT, bpp, vidFlags); | |
glewInit(); | |
GL_Setup(W_WIDTH, W_HEIGHT); | |
glutInit(&argc, argv); | |
applicationInit(); | |
main_loop_function(); | |
return 0; | |
} |
#define KERNEL_SIZE 9 | |
uniform sampler2D sampler0; | |
uniform float kernel_weights[KERNEL_SIZE]; | |
uniform vec2 texture_offsets[KERNEL_SIZE]; | |
void main(void) | |
{ | |
vec2 offset[KERNEL_SIZE]; | |
int i; | |
vec4 sum = vec4(0.0); | |
for(i = 0; i < KERNEL_SIZE; i++){ | |
vec4 tmp = texture2D(sampler0, gl_TexCoord[0].st + texture_offsets[i]); | |
sum += tmp * kernel_weights[i]; | |
} | |
gl_FragColor = sum; | |
} |
void main(){ | |
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; | |
gl_TexCoord[0] = gl_MultiTexCoord0; | |
} |
I think I was having that issue at one point and can't quite remember exactly how I fixed it, but it has something to do with the type of the program you have it set to. I believe it should be built as a windows console application, NOT a normal windows application. I believe you can also fix it by going to the properties of your project and telling it what the entry point of the application is (i.e. it's trying to start your program by looking for something else when it should be looking for main).
Google around a bit and if you still can't fix it let me know.
Also, I just updated the code so that I calculate texture offsets and kernel weights in the main program instead of the shader, since they only need to be calculated once.
Hi
yes all i got from googling is to change Properties>linker>system>SubSystem to "Console"... but its already console in my project
I've tried this code as new win32 console app as well, with both PRE COMPILED HEADER and and EMPTY PROJECT just in case if that was a problem, but getting same error.
how can i change the "entry point of the application" ?
Actually, what might be happening is you might not be adding the correct settings for linking with SDL. When I get home I'll boot up my windows machine and let you know what I have set, but I do remember now that when using SDL you have to make sure you include all of the SDL libs and headers and everything correctly or else you'll get this error.
as far as i know, my SDL header linking is correct
please explain if their is something special in linking
What I was thinking of was make sure you have both SDL.lib AND SDLmain.lib. I didn't have SDLmain.lib initially, and I was getting the same error. I have those specified in my Project Properties -> Configuration Properties -> Linker -> Input -> Additional Dependencies.
Also, I seem to have Configuration Properties -> Linker -> System -> Subsystem set to "Windows", not "Console" as I mentioned above, you might want to give that a shot.
Hello
I was busy somewhere else. I've tried this today it works.. but straing thing happen, the output window just come and disappear
I've tries system("pause); to stop screen but getting same result.
any idea why im getting this ?
Sounds like you're probably getting a segfault or something, can you see what the output is?
cant see anything.. white window just blink and disappear
do you have any idea what prob is it ?
Sorry, no, it works fine on my linux machine. If you can get some debug information, like an error or something, that would be helpful.
Hi
im trying to run your code but getting error :-s
on RELEASE: MSVCRT.lib(crtexe.obj) : error LNK2001: unresolved external symbol _main
on DEBUG: MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
googled allot but unable to fix it
plateform: win7, VC++ 2010 express