Last active
June 3, 2019 14:19
-
-
Save jgranick/5430948 to your computer and use it in GitHub Desktop.
SimpleGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SetOutputFilter DEFLATE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
emcc -o SimpleGL.js SimpleGL.cpp SDLStage.cpp -s FULL_ES2=1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="chrome=1, IE=edge"> | |
<title>SimpleGL</title> | |
</head> | |
<body style="padding: 0; margin: 0; background-color: #FFFFFF;"> | |
<canvas id="canvas" width="640" height="480" /> | |
<script type="text/javascript"> | |
var Module = {}; | |
Module.canvas = document.getElementById('canvas'); | |
</script> | |
<script type="text/javascript" src="./SimpleGL.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "SDLStage.h" | |
SDLStage::SDLStage (int width, int height, int frameRate, int flags) { | |
if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) == 0) { | |
screen = SDL_SetVideoMode (width, height, 0, flags); | |
if (screen != NULL) { | |
previousTime = 0; | |
ticksPerFrame = (int)(1000 / frameRate); | |
active = true; | |
paused = false; | |
} else { | |
cerr << "Could not set video mode: " << SDL_GetError () << endl; | |
} | |
} else { | |
cerr << "Could not initialize SDL: " << SDL_GetError () << endl; | |
} | |
} | |
SDLStage::~SDLStage () { | |
SDL_Quit (); | |
} | |
void SDLStage::handleEvent (SDL_Event &event) { | |
switch (event.type) { | |
case SDL_ACTIVEEVENT: | |
if (event.active.state & SDL_APPACTIVE) { | |
if (event.active.gain == 0) { | |
//paused = true; | |
} else { | |
//paused = false; | |
} | |
} | |
break; | |
case SDL_VIDEOEXPOSE: | |
render (); | |
break; | |
case SDL_QUIT: | |
active = false; | |
break; | |
} | |
if (eventListener != NULL) { | |
(*eventListener) (event); | |
} | |
event.type = -1; | |
} | |
void SDLStage::render () { | |
if (renderCallback != NULL) { | |
(*renderCallback) (screen); | |
} | |
} | |
void SDLStage::setCaption (string title) { | |
if (active) { | |
SDL_WM_SetCaption (title.c_str (), title.c_str ()); | |
} | |
} | |
void SDLStage::setEventListener (void (*listener) (SDL_Event&)) { | |
eventListener = listener; | |
} | |
void SDLStage::setRenderCallback (void (*callback) (SDL_Surface*)) { | |
renderCallback = callback; | |
} | |
void SDLStage::setUpdateCallback (void (*callback) (int)) { | |
updateCallback = callback; | |
} | |
void SDLStage::step () { | |
SDL_Event event; | |
#ifndef EMSCRIPTEN | |
if (paused) { | |
if (SDL_WaitEvent (&event)) { | |
handleEvent (event); | |
} | |
} else { | |
#endif | |
while (SDL_PollEvent (&event)) { | |
handleEvent (event); | |
if (!active) { | |
break; | |
} | |
} | |
if (active) { | |
int currentTime = SDL_GetTicks (); | |
int deltaTime = currentTime - previousTime; | |
update (currentTime - previousTime); | |
render (); | |
#ifndef EMSCRIPTEN | |
while (deltaTime < ticksPerFrame) { | |
SDL_TimerID timer = SDL_AddTimer (ticksPerFrame - deltaTime, timer_onComplete, NULL); | |
SDL_WaitEvent (&event); | |
SDL_RemoveTimer (timer); | |
if (event.type != SDL_USEREVENT) { | |
handleEvent (event); | |
deltaTime = SDL_GetTicks () - previousTime; | |
} else { | |
event.type = -1; | |
break; | |
} | |
} | |
#endif | |
previousTime = currentTime; | |
} | |
#ifndef EMSCRIPTEN | |
} | |
#endif | |
} | |
void SDLStage::update (int deltaTime) { | |
if (updateCallback != NULL) { | |
(*updateCallback) (deltaTime); | |
} | |
} | |
// Event Handlers | |
Uint32 timer_onComplete (Uint32 interval, void *param) { | |
SDL_Event event; | |
SDL_UserEvent userevent; | |
userevent.type = SDL_USEREVENT; | |
userevent.code = 0; | |
userevent.data1 = NULL; | |
userevent.data2 = NULL; | |
event.type = SDL_USEREVENT; | |
event.user = userevent; | |
SDL_PushEvent (&event); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SDLSTAGE_H | |
#define SDLSTAGE_H | |
#include <iostream> | |
#include <string> | |
#include "SDL/SDL.h" | |
using namespace std; | |
class SDLStage { | |
public: | |
SDLStage (int width, int height, int frameRate, int flags); | |
~SDLStage (); | |
bool active; | |
void setCaption (string title); | |
void setEventListener (void (*listener) (SDL_Event&)); | |
void setRenderCallback (void (*callback) (SDL_Surface*)); | |
void setUpdateCallback (void (*callback) (int)); | |
void step (); | |
private: | |
void (*eventListener) (SDL_Event&); | |
bool paused; | |
int previousTime; | |
void (*renderCallback) (SDL_Surface*); | |
SDL_Surface* screen; | |
int ticksPerFrame; | |
void (*updateCallback) (int); | |
void handleEvent (SDL_Event &event); | |
void render (); | |
void update (int deltaTime); | |
}; | |
Uint32 timer_onComplete (Uint32 interval, void *param); | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SDL/SDL_image.h> | |
#include <GLES2/gl2.h> | |
#include <GLES2/gl2ext.h> | |
#include "SDLStage.h" | |
#ifdef EMSCRIPTEN | |
#include <emscripten.h> | |
#endif | |
GLuint programObject; | |
SDLStage* stage; | |
void handleEvent (SDL_Event &event) { | |
} | |
GLuint loadShader (GLenum type, const char *source) { | |
GLuint shader; | |
GLint compiled; | |
shader = glCreateShader (type); | |
if (shader == 0) { | |
cerr << "Error creating shader" << endl; | |
return 0; | |
} | |
glShaderSource (shader, 1, &source, NULL); | |
glCompileShader (shader); | |
glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled); | |
if (!compiled) { | |
GLint infoLen = 0; | |
glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLen); | |
if (infoLen > 1) { | |
char* infoLog = (char*) malloc (sizeof (char) * infoLen); | |
glGetShaderInfoLog (shader, infoLen, NULL, infoLog); | |
cerr << "Error compiling shader: " << infoLog << endl; | |
free (infoLog); | |
} | |
glDeleteShader (shader); | |
return 0; | |
} | |
return shader; | |
} | |
int initOpenGL () { | |
const char vertexShaderString[] = | |
"attribute vec4 vPosition; \n" | |
"void main() \n" | |
"{ \n" | |
" gl_Position = vPosition; \n" | |
"} \n"; | |
const char fragmentShaderString[] = | |
"precision mediump float;\n"\ | |
"void main() \n" | |
"{ \n" | |
" gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n" | |
"} \n"; | |
GLuint vertexShader; | |
GLuint fragmentShader; | |
GLint linked; | |
vertexShader = loadShader (GL_VERTEX_SHADER, vertexShaderString); | |
fragmentShader = loadShader (GL_FRAGMENT_SHADER, fragmentShaderString); | |
programObject = glCreateProgram (); | |
if (programObject == 0) { | |
cerr << "Could not create OpenGL program" << endl; | |
return 0; | |
} | |
glAttachShader (programObject, vertexShader); | |
glAttachShader (programObject, fragmentShader); | |
glBindAttribLocation (programObject, 0, "vPosition"); | |
glLinkProgram (programObject); | |
glGetProgramiv (programObject, GL_LINK_STATUS, &linked); | |
if (!linked) { | |
GLint infoLen = 0; | |
glGetProgramiv (programObject, GL_INFO_LOG_LENGTH, &infoLen); | |
if (infoLen > 1) { | |
char* infoLog = (char*) malloc (sizeof (char) * infoLen); | |
glGetProgramInfoLog (programObject, infoLen, NULL, infoLog); | |
cerr << "Error linking program: " << infoLog << endl; | |
free (infoLog); | |
} | |
glDeleteProgram (programObject); | |
return 0; | |
} | |
glClearColor (0.0f, 0.0f, 0.0f, 1.0f); | |
return 1; | |
} | |
void render (SDL_Surface *screen) { | |
GLfloat vVertices[] = { | |
0.0f, 0.5f, 0.0f, | |
-0.5f, -0.5f, 0.0f, | |
0.5f, -0.5f, 0.0f | |
}; | |
glViewport (0, 0, screen -> w, screen -> h); | |
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | |
glClear (GL_COLOR_BUFFER_BIT); | |
glUseProgram (programObject); | |
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); | |
glEnableVertexAttribArray (0); | |
glDrawArrays (GL_TRIANGLES, 0, 3); | |
SDL_GL_SwapBuffers (); | |
} | |
void update (int deltaTime) { | |
} | |
void step () { | |
stage -> step (); | |
} | |
int main (int argc, char** argv) { | |
stage = new SDLStage (640, 480, 30, SDL_OPENGL); | |
if (!initOpenGL ()) { | |
cerr << "Error initializing OpenGL" << endl; | |
return 1; | |
} | |
stage -> setCaption ("SimpleGL"); | |
stage -> setEventListener (&handleEvent); | |
stage -> setRenderCallback (&render); | |
stage -> setUpdateCallback (&update); | |
#ifdef EMSCRIPTEN | |
emscripten_set_main_loop (step, 30, true); | |
#else | |
while (stage -> active) { | |
step (); | |
} | |
#endif | |
delete stage; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment