Skip to content

Instantly share code, notes, and snippets.

@andresfelipemendez
Created December 25, 2018 18:35
Show Gist options
  • Select an option

  • Save andresfelipemendez/6b8328f384c7037b1a0688d982358db0 to your computer and use it in GitHub Desktop.

Select an option

Save andresfelipemendez/6b8328f384c7037b1a0688d982358db0 to your computer and use it in GitHub Desktop.
The Fundamental of C/C++ Game programming Brian Beuken Chapter Three Hello Triangle Using the Target
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <sys/time.h>
#include "bcm_host.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#define TRUE 1
#define FALSE 0
typedef struct
{
//save a Handle to a program object
GLuint programObject;
} UserData;
typedef struct Target_State
{
uint32_t width;
uint32_t height;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
EGL_DISPMANX_WINDOW_T nativeWindow;
UserData *user_data;
void(*draw_func)(struct Target_State*);
} Target_State;
Target_State state;
Target_State* p_state = &state;
static const EGLint attribute_list[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
static const EGLint context_attributes[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
GLuint LoadShader(GLenum type, const char *shaderSrc)
{
GLuint TheShader = glCreateShader(type);
if (TheShader == 0) return 0;
glShaderSource(TheShader, 1, &shaderSrc, NULL);
glCompileShader(TheShader);
GLint IsItCompiled;
glGetShaderiv(TheShader, GL_COMPILE_STATUS, &IsItCompiled);
if (!IsItCompiled) {
GLint Retinfolen = 0;
glGetShaderiv(TheShader, GL_INFO_LOG_LENGTH, &Retinfolen);
if (Retinfolen > 1)
{
char* infoLog = (char*)malloc(sizeof(char)*Retinfolen);
glGetShaderInfoLog(TheShader, Retinfolen, NULL, infoLog);
fprintf(stderr, "Error compiling this shader:\n%s\n", infoLog);
free(infoLog);
}
glDeleteShader(TheShader);
return 0;
}
return TheShader;
}
int Init(Target_State *p_state)
{
p_state->user_data = (UserData *)malloc(sizeof(UserData));
GLbyte vShaderStr[] =
"attribute vec4 a_position;\n"
"attribute vec2 a_texCoord;\n"
"varying vec2 v_texCoord;\n"
"void main()\n"
"{gl_Position=a_position;\n"
"v_texCoord=a_texCoord;}\n";
GLbyte fShaderStr[] =
"precision mediump float;\n"
"varying vec2 v_texCoord;\n"
"uniform sampler2D s_texture;\n"
"void main()\n"
"{gl_FragColor=vec4(1.0,0.0,0.0,1.0);}\n";
GLuint programObject, vertexShader, fragmentShader;
vertexShader = LoadShader(GL_VERTEX_SHADER, (char*)vShaderStr);
fragmentShader = LoadShader(GL_FRAGMENT_SHADER, (char*)fShaderStr);
programObject = glCreateProgram();
if (programObject == 0) return 0;
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
glLinkProgram(programObject);
GLint AreTheyLinked;
glGetProgramiv(programObject, GL_LINK_STATUS, &AreTheyLinked);
if (!AreTheyLinked)
{
GLint RetInfoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &RetInfoLen);
if (RetInfoLen > 1)
{
GLchar* infoLog = (GLchar*)malloc(sizeof(char)*RetInfoLen);
glGetProgramInfoLog(programObject, RetInfoLen, NULL, infoLog);
fprintf(stderr, "Error linking program:\n%s\n", infoLog);
free(infoLog);
}
glDeleteProgram(programObject);
return FALSE;
}
p_state->user_data->programObject = programObject;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
return TRUE;
}
void init_ogl(Target_State *state, int width, int height)
{
int32_t success = 0;
EGLBoolean result;
EGLint num_config;
DISPMANX_ELEMENT_HANDLE_T DispmanElementH;
DISPMANX_DISPLAY_HANDLE_T DispmanDisplayH;
DISPMANX_UPDATE_HANDLE_T DispmanUpdateH;
VC_RECT_T dest_rect;
VC_RECT_T src_rect;
EGLConfig config;
state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(state->display != EGL_NO_DISPLAY);
result = eglInitialize(state->display, NULL, NULL);
assert(EGL_FALSE != result);
result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
assert(EGL_FALSE != result);
result = eglBindAPI(EGL_OPENGL_ES_API);
assert(EGL_FALSE != result);
state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
assert(state->context != EGL_NO_CONTEXT);
state->width = width;
state->height = height;
dest_rect.x = 0;
dest_rect.y = 0;
dest_rect.width = state->width;
dest_rect.height = state->height;
src_rect.x = 0;
src_rect.y = 0;
DispmanDisplayH = vc_dispmanx_display_open(0);
DispmanUpdateH = vc_dispmanx_update_start(0);
DispmanElementH = vc_dispmanx_element_add(
DispmanUpdateH,
DispmanDisplayH,
0,
&dest_rect,
0,
&src_rect,
DISPMANX_PROTECTION_NONE,
0,
0,
(DISPMANX_TRANSFORM_T)0);
state->nativeWindow.element = DispmanElementH;
state->nativeWindow.width = state->width;
state->nativeWindow.height = state->height;
vc_dispmanx_update_submit_sync(DispmanUpdateH);
state->surface = eglCreateWindowSurface(state->display, config, &(state->nativeWindow), NULL);
assert(state->surface != EGL_NO_SURFACE);
result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
assert(EGL_FALSE != result);
}
void Draw(Target_State *p_state)
{
UserData *userData = p_state->user_data;
GLfloat TryVertices[] =
{
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
glViewport(0, 0, p_state->width, p_state->height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(userData->programObject);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, TryVertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
if (glGetError() != GL_NO_ERROR) printf("oh bugger");
}
void esInitContext(Target_State *p_state)
{
if (p_state != NULL)
{
memset(p_state, 0, sizeof(Target_State));
}
}
void esRegisteredDrawFunc(Target_State *p_state, void(*draw_func)(Target_State*))
{
p_state->draw_func = draw_func;
}
void esMainLoop(Target_State *esContext)
{
int Counter = 0;
while (Counter++ < 200)
{
if (esContext->draw_func != NULL)
esContext->draw_func(esContext);
eglSwapBuffers(esContext->display, esContext->surface);
}
}
int main(int argc, char *argv[])
{
UserData user_data;
bcm_host_init();
esInitContext(p_state);
init_ogl(p_state, 1024, 720);
p_state->user_data = &user_data;
if (!Init(p_state))
return 0;
esRegisteredDrawFunc(p_state, Draw);
esMainLoop(p_state);
}
Include Directories: /opt/vc/include /opt/vc/include/interface/vcos/pthreads /opt/vc/include/interface/vmcs_host/linux
Library Directories: /opt/vc/lib
Library Names: brcmGLESv2 brcmEGL openmaxil bcm_host vcos vchiq_arm pthread EGL GLESv2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment