Basic example of OpenGL ES 2.0 usage using SDL 2

From the book OpenGL ES 2.0 Programming Guide, see code reference: https://code.google.com/p/opengles-book-samples/source/browse/trunk/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c

Redefined classes

redef class Sys

glesv2 :: opengles2_hello_triangle $ Sys

The main class of the program.

All class definitions

redef class Sys

glesv2 :: opengles2_hello_triangle $ Sys

The main class of the program.
package_diagram glesv2::opengles2_hello_triangle opengles2_hello_triangle glesv2 glesv2 glesv2::opengles2_hello_triangle->glesv2 egl egl glesv2::opengles2_hello_triangle->egl sdl2 sdl2 glesv2::opengles2_hello_triangle->sdl2 realtime realtime glesv2::opengles2_hello_triangle->realtime glesv2->egl glesv2->sdl2 glesv2->realtime android android glesv2->android c c glesv2->c core core glesv2->core ...android ... ...android->android ...c ... ...c->c ...core ... ...core->core ...egl ... ...egl->egl ...sdl2 ... ...sdl2->sdl2 ...realtime ... ...realtime->realtime a_star-m a_star-m a_star-m->glesv2::opengles2_hello_triangle

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module aware

android :: aware

Android compatibility module
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module c

c :: c

Structures and services for compatibility with the C language
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module events

sdl2 :: events

SDL 2 events and related services
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sdl2_base

sdl2 :: sdl2_base

Basic SDL 2 features
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module syswm

sdl2 :: syswm

Window manager related SDL 2 services
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module egl

egl :: egl

Interface between rendering APIs (OpenGL, OpenGL ES, etc.) and the native windowing system.
module glesv2

glesv2 :: glesv2

OpenGL graphics rendering library for embedded systems, version 2.0
module realtime

realtime :: realtime

Services to keep time of the wall clock time
module sdl2

sdl2 :: sdl2

Simple DirectMedia Layer (SDL) 2.0 services for easy window creation and 2D drawing

Children

module a_star-m

a_star-m

# Basic example of OpenGL ES 2.0 usage using SDL 2
#
# From the book OpenGL ES 2.0 Programming Guide, see code reference:
# https://code.google.com/p/opengles-book-samples/source/browse/trunk/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c
module opengles2_hello_triangle is example

import glesv2
import egl
import sdl2

import realtime

if "NIT_TESTING".environ == "true" then exit(0)

var window_width = 800
var window_height = 600

#
## SDL2
#
assert sdl.initialize((new SDLInitFlags).video) else
	print sdl.error
end

var sdl_window = new SDLWindow("Title".to_cstring, window_width, window_height, (new SDLWindowFlags).opengl)
assert not sdl_window.address_is_null else print sdl.error

var sdl_wm_info = sdl_window.wm_info
var native_window = sdl_wm_info.window_handle
var native_display = sdl_wm_info.display_handle
assert not native_display.address_is_null else print "Failed to get handle to native display"

#
## EGL
#
var egl_display = new EGLDisplay(native_display)
assert egl_display.is_valid else print "EGL display is not valid"

egl_display.initialize
assert egl_display.is_valid else print egl_display.error

print "EGL version: {egl_display.version}"
print "EGL vendor: {egl_display.vendor}"
print "EGL extensions: \n* {egl_display.extensions.join("\n* ")}"
print "EGL client APIs: {egl_display.client_apis.join(", ")}"

var config_chooser = new EGLConfigChooser
#config_chooser.surface_type_egl
config_chooser.blue_size = 8
config_chooser.green_size = 8
config_chooser.red_size = 8
#config_chooser.alpha_size = 8
#config_chooser.depth_size = 8
#config_chooser.stencil_size = 8
#config_chooser.sample_buffers = 1
config_chooser.close

var configs = config_chooser.choose(egl_display)
assert configs != null else print "choosing config failed: {egl_display.error}"
assert not configs.is_empty else print "no EGL config"

print "{configs.length} EGL configs available"
for config in configs do
	var attribs = config.attribs(egl_display)
	print "* caveats: {attribs.caveat}"
	print "  conformant to: {attribs.conformant}"
	print "  size of RGBA: {attribs.red_size} {attribs.green_size} {attribs.blue_size} {attribs.alpha_size}"
	print "  buffer, depth, stencil: {attribs.buffer_size} {attribs.depth_size} {attribs.stencil_size}"
end

var config = configs.first

var surface = egl_display.create_window_surface(config, native_window, [0])
assert surface.is_ok else print egl_display.error

var context = egl_display.create_context(config)
assert context.is_ok else print egl_display.error

var make_current_res = egl_display.make_current(surface, surface, context)
assert make_current_res else print egl_display.error

var width = surface.attribs(egl_display).width
var height = surface.attribs(egl_display).height
print "Width: {width}"
print "Height: {height}"

assert egl_bind_opengl_es_api else print "eglBingAPI failed: {egl_display.error}"

#
## GLESv2
#

print "Can compile shaders? {gl.shader_compiler}"
assert_no_gl_error

assert gl.shader_compiler else print "Cannot compile shaders"

# gl program
print glGetError.to_s
var program = new GLProgram
if not glIsProgram(program) then
	print "Program is not ok: {glGetError.to_s}\nLog:"
	print glGetProgramInfoLog(program)
	abort
end
assert_no_gl_error

# vertex shader
var vertex_shader = new GLVertexShader
assert glIsShader(vertex_shader) else print "Vertex shader is not ok: {glGetError}"
glShaderSource(vertex_shader, """
attribute vec4 vPosition;
void main()
{
  gl_Position = vPosition;
}
""".to_cstring)
glCompileShader vertex_shader
assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {glGetShaderInfoLog(vertex_shader)} {glGetProgramInfoLog(program)}"
assert_no_gl_error

# fragment shader
var fragment_shader = new GLFragmentShader
assert glIsShader(fragment_shader) else print "Fragment shader is not ok: {glGetError}"
glShaderSource(fragment_shader, """
precision mediump float;
void main()
{
	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
""".to_cstring)
glCompileShader(fragment_shader)
assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {glGetShaderInfoLog(fragment_shader)}"
assert_no_gl_error

glAttachShader(program, vertex_shader)
glAttachShader(program, fragment_shader)
program.bind_attrib_location(0, "vPosition")
glLinkProgram program
assert program.is_linked else print "Linking failed: {glGetProgramInfoLog(program)}"
assert_no_gl_error

# prepare
glViewport(0, 0, width, height)
glClearColor(0.5, 0.0, 0.5, 1.0)

# draw!
var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0]
var vertex_array = new VertexArray(0, 3, vertices)
vertex_array.attrib_pointer

var clock = new Clock

var n_frames = 1000
for i in [0..n_frames[ do
	printn "."
	assert_no_gl_error

	glClear gl_COLOR_BUFFER_BIT
	glUseProgram program
	vertex_array.enable
	glDrawArrays(gl_TRIANGLES, 0, 3)
	egl_display.swap_buffers(surface)
end

print "FPS: {n_frames.to_f/clock.lapse.to_f}"

# delete
glDeleteProgram program
glDeleteShader vertex_shader
glDeleteShader fragment_shader

#
## EGL
#
# close
egl_display.make_current(new EGLSurface.none, new EGLSurface.none, new EGLContext.none)
egl_display.destroy_context context
egl_display.destroy_surface surface

#
## SDL2
#
# close
sdl.quit
lib/glesv2/examples/opengles2_hello_triangle.nit:17,1--201,8