OpenGL ES 2.0 program fail on Mali400 platform - embedded

I'm writing a simple texture stream rendering program using OpenGL ES 2.0. The program works on desktop but fail on embedded platform with Mali400 GPU. The LCD goes black with the top few lines blinking. I don't know what's wrong with my code. I tried some other OpenGL ES 2.0 programs which are OK, so the problem must lay in my code. Any help will be appreciated. Thanks.
main.c
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <sys/stat.h>
static EGLDisplay display;
static EGLSurface surface;
static void render_target_init(EGLNativeWindowType nativeWindow)
{
assert((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) != EGL_NO_DISPLAY);
EGLint majorVersion;
EGLint minorVersion;
assert(eglInitialize(display, &majorVersion, &minorVersion) == EGL_TRUE);
EGLConfig config;
EGLint numConfigs;
const EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_NONE
};
assert(eglChooseConfig(display, configAttribs, &config, 1, &numConfigs) == EGL_TRUE);
const EGLint attribList[] = {
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
EGL_NONE
};
assert((surface = eglCreateWindowSurface(display, config, nativeWindow, attribList)) != EGL_NO_SURFACE);
EGLContext context;
const EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
assert((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);
assert(eglMakeCurrent(display, surface, surface, context) == EGL_TRUE);
}
static GLuint LoadShader(const char *name, GLenum type)
{
FILE *f;
int size;
char *buff;
GLuint shader;
GLint compiled;
const char *source[1];
assert((f = fopen(name, "r")) != NULL);
// get file size
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
assert((buff = malloc(size)) != NULL);
assert(fread(buff, 1, size, f) == size);
source[0] = buff;
fclose(f);
shader = glCreateShader(type);
glShaderSource(shader, 1, source, &size);
glCompileShader(shader);
free(buff);
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char *infoLog = malloc(infoLen);
glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
fprintf(stderr, "Error compiling shader %s:\n%s\n", name, infoLog);
free(infoLog);
}
glDeleteShader(shader);
return 0;
}
return shader;
}
static void init_GLES(int width, int height)
{
GLint linked;
GLuint program;
GLuint vertexShader;
GLuint fragmentShader;
assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0);
assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0);
assert((program = glCreateProgram()) != 0);
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
GLint infoLen = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char *infoLog = malloc(infoLen);
glGetProgramInfoLog(program, infoLen, NULL, infoLog);
fprintf(stderr, "Error linking program:\n%s\n", infoLog);
free(infoLog);
}
glDeleteProgram(program);
exit(1);
}
glClearColor(0.15f, 0.15f, 0.15f, 0.15f);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glUseProgram(program);
GLfloat vertex[] = {
1, 0, 0,
0, 1, 0,
-1, 0, 0,
0, -1, 0,
};
GLfloat texcoord[] = {
1, 1,
0, 1,
0, 0,
1, 0,
};
GLushort index[] = {
0, 1, 2,
0, 3, 2,
};
GLuint VBO[3];
glGenBuffers(3, VBO);
GLint pos = glGetAttribLocation(program, "positionIn");
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat) * 3, vertex, GL_STATIC_DRAW);
glEnableVertexAttribArray(pos);
glVertexAttribPointer(pos, 3, GL_FLOAT, 0, 0, 0);
GLint tex = glGetAttribLocation(program, "texcoordIn");
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat) * 2, texcoord, GL_STATIC_DRAW);
glEnableVertexAttribArray(tex);
glVertexAttribPointer(tex, 2, GL_FLOAT, 0, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLushort), index, GL_STATIC_DRAW);
GLuint texid;
GLint texMap = glGetUniformLocation(program, "texMap");
glUniform1i(texMap, 0); // GL_TEXTURE0
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
assert(glGetError() == 0);
}
#ifdef _X_WINDOW_SYSTEM_
#include <X11/Xlib.h>
static EGLNativeWindowType CreateNativeWindow(void)
{
assert((display = XOpenDisplay(NULL)) != NULL);
int screen = DefaultScreen(display);
Window root = DefaultRootWindow(display);
Window window = XCreateWindow(display, root, 0, 0, 600, 480, 0,
DefaultDepth(display, screen), InputOutput,
DefaultVisual(display, screen),
0, NULL);
XMapWindow(display, window);
XFlush(display);
return window;
}
#endif
int display_init(int width, int height)
{
#ifdef _X_WINDOW_SYSTEM_
render_target_init(CreateNativeWindow());
#else
struct mali_native_window window;
window.width = width;
window.height = height;
render_target_init(&window);
#endif
init_GLES(width, height);
}
void render_frame(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(display, surface);
}
void update_texture(void *data, int width, int height)
{
static int first_time = 1;
if (first_time) {
printf("create texture %d %d\n", width, height);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
first_time = 0;
}
else {
printf("update texture %d %d\n", width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
}
assert(glGetError() == 0);
}
int main(void)
{
int i;
void *texture[2] = {0};
int fd = open("0.rgb", O_RDONLY);
struct stat st;
fstat(fd, &st);
texture[0] = malloc(st.st_size);
read(fd, texture[0], st.st_size);
close(fd);
fd = open("1.rgb", O_RDONLY);
fstat(fd, &st);
texture[1] = malloc(st.st_size);
read(fd, texture[1], st.st_size);
close(fd);
display_init(600, 480);
for (i = 0; i < 200; i++) {
update_texture(texture[i%2], 720, 576);
render_frame();
usleep(20000);
}
return 0;
}
vert.glsl
attribute vec3 positionIn;
attribute vec2 texcoordIn;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(positionIn, 1);
texcoord = texcoordIn;
}
frag.glsl
precision mediump float;
uniform sampler2D texMap;
varying vec2 texcoord;
void main() {
vec3 color = texture2D(texMap, texcoord).rgb;
gl_FragColor = vec4(color, 1);
}

Did you try to render the frame without the texture ?
Do like gl_FragColor = vec4(1.0,0.0,0.0,1.0); then check it is still black or red.
If red check your texture function.
I think it can be a problem not to call these functions each a frame
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,c_Texture[TEXTURES_FIRST].texture_id);
glUniform1i(h_Texture[TEXTURES_FIRST],1);

Related

ContentView not updating

I’m somewhat new to Swiftui programming and probably making all kinds of beginner mistakes. That said, I’m trying to learn the language by grinding my teeth on a number of small programs and in this one, can’t seem to get the ContentView to update for numPlayers and numRows when returning from Sheet but the two Bool variables (showRowIndicators and showColumnIndicators) update correctly in ContentView.
Any help would be appreciated! :)
import SwiftUI
struct Player: Identifiable, Hashable {
var id: Int = 0
var name: String = ""
}
struct ContentView: View {
#State var players = [
Player(id: 0, name: "Player1"),
Player(id: 1, name: "Player2"),
Player(id: 2, name: "Player3"),
Player(id: 3, name: "Player4"),
Player(id: 4, name: "Player5"),
Player(id: 5, name: "Player6"),
Player(id: 6, name: "Player7"),
Player(id: 7, name: "Player8"),
Player(id: 8, name: "Player9"),
Player(id: 9, name: "Player10"),
]
#State var numbers = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
#AppStorage("numRows") var numRows: Int = 10
#AppStorage("numPlayers") var numPlayers: Int = 4
#AppStorage("showRowIndicators") var showRowIndicators: Bool = false
#AppStorage("showColumnIndicators") var showColumnIndicators: Bool = false
#State var backgroundColor: Color = Color.green
#State var showSheet: Bool = false
var rowOddBColor: Color = Color.white.opacity(0.2)
var rowEvenBColor: Color = Color.green.opacity(0.2)
var maxRows = 20
let boxWidth = 65.0
let boxHeight = 22.0
let boxPadH = 2.0
let HSspace = 7.0
let boxBackColor = Color(#colorLiteral(red: 0.8993894458, green: 0.8753863573, blue: 0.7580057979, alpha: 1))
let boxForeColor = Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1))
let totalBackColor = Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1))
let topScoreBackColor = Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))
var winningPlayer: Int = 0
var isTopScore: Int = 0
var body: some View {
ZStack {
//background
backgroundColor
.ignoresSafeArea()
//content
DisplayColumnGuides(numPlayers: $numPlayers, showColumnIndicators: $showColumnIndicators, backgroundColor: $backgroundColor, HSspace: HSspace, boxWidth: boxWidth)
ScrollView(.vertical) {
VStack(spacing: 0) {
HStack {
Image(systemName: "gear")
.font(.largeTitle)
.frame(width: 50, alignment: .leading)
.onTapGesture {
showSheet.toggle()
}
Spacer()
}
DisplayPlayerNames(players: $players, numPlayers: $numPlayers, HSspace: HSspace, boxWidth: boxWidth, boxHeight: boxHeight)
let rowCount: Int = (numRows <= maxRows ? numRows : maxRows)
ForEach(0..<rowCount) { row in
ZStack {
Text("\(row+1)")
.font(.footnote)
.foregroundColor(.white)
.frame(maxWidth: .infinity, alignment: .leading)
HStack(spacing: HSspace) {
ForEach(0..<numPlayers) { column in
TextField("", value: self.$numbers[row][column], format: .number)
.foregroundColor(boxForeColor)
.font(.title3)
.multilineTextAlignment(.center)
.keyboardType(.numbersAndPunctuation)
.frame(width: boxWidth, height: boxHeight)
// .background(boxBackColor)
.cornerRadius(5.0)
// .border(.black, width: 0.2)
}
}
.frame(maxWidth: .infinity)
.frame(height: boxHeight+5)
.background(
showRowIndicators
? ( isNumberEven(number: row)
? rowEvenBColor
: rowOddBColor
)
: nil
)
}
}
VStack(spacing: 10) {
ZStack {
Text("Total")
// .bold()
.font(.footnote)
.foregroundColor(Color.blue)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 5)
HStack(spacing: HSspace) {
ForEach(0..<numPlayers) { player in
let playerScore = addScore(playerNumber: player)
let topPlayer = getTopPlayer()
Text("\(playerScore)")
.font(.title3)
.foregroundColor(boxForeColor)
.bold()
.frame(width: boxWidth, height: boxHeight+5)
.background(topPlayer == player ? topScoreBackColor : totalBackColor)
// .border(.black)
.cornerRadius(10.0)
}
}
.padding(.top, 5)
}
}
Spacer()
}
}
.sheet(isPresented: $showSheet) {
OptionsView()
}
}
.onTapGesture {
//--- Hide Keyboard ---
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
.gesture(
DragGesture(minimumDistance: 0, coordinateSpace: .local).onEnded({ gesture in
//--- Hide keyboard on swipe down ---
if gesture.translation.height > 0 {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}))
}
func isNumberEven(number: Int) -> Bool {
return (number % 2 == 0)
}
func getTopPlayer() -> Int {
var topScore: Int = 0
var topPlayer: Int = -1
for p in 0..<players.count {
let tPlayer = addScore(playerNumber: p)
if tPlayer > topScore {
topScore = tPlayer
topPlayer = p
}
}
return topPlayer
}
func addScore(playerNumber: Int) -> Int {
let rowCount = maxRows
var playerTotal: Int = 0
for row in 0..<rowCount {
playerTotal += numbers[row][playerNumber]
}
return playerTotal
}
}
struct OptionsView: View {
#Environment(\.presentationMode) var presentationMode
#AppStorage("numRows") var numRows: Int?
#AppStorage("numPlayers") var numPlayers: Int = 4
#AppStorage("showRowIndicators") var showRowIndicators: Bool = false
#AppStorage("showColumnIndicators") var showColumnIndicators: Bool = false
var body: some View {
ZStack {
Color.brown.opacity(0.3)
VStack {
Text("Settings")
.font(.largeTitle)
.underline()
.padding(.vertical)
// Button(action: {
// presentationMode.wrappedValue.dismiss()
// }, label: {
// Image(systemName: "xmark")
// .foregroundColor(.red)
// .font(.title)
// .padding(10)
// })
// .frame(maxWidth: .infinity, alignment: .leading)
HStack {
Text("Enter # score rows (max 20)")
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
TextField("Enter # rows", value: $numRows, format: .number)
.keyboardType(.numberPad)
.multilineTextAlignment(.center)
.frame(width: 100)
.background(Color.white)
.cornerRadius(10.0)
}
.padding(.horizontal)
HStack {
Text("Enter # players (max 10)")
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
TextField("Enter # players", value: $numPlayers, format: .number)
.keyboardType(.numberPad)
.multilineTextAlignment(.center)
.frame(width: 100, alignment: .center)
.background(Color.white)
.cornerRadius(10.0)
}
.padding(.horizontal)
Toggle(isOn: $showRowIndicators, label: {
Text("Show row guides")
})
.padding(.horizontal)
.padding(.top, 20)
Toggle(isOn: $showColumnIndicators, label: {
Text("Show column guides")
})
.padding(.horizontal)
.padding(.top, 5)
Button(action: {
presentationMode.wrappedValue.dismiss()
}, label: {
Text("Close")
.foregroundColor(.blue)
.font(.title)
.frame(width: 100, height: 40.0)
.background(Color.white)
.cornerRadius(25)
.padding(10)
})
.padding(.top, 40)
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
// OptionsView()
}
}
struct DisplayColumnGuides: View {
#Binding var numPlayers: Int
#Binding var showColumnIndicators: Bool
#Binding var backgroundColor: Color
var HSspace: Double
var boxWidth: Double
var body: some View {
HStack(spacing: HSspace) {
ForEach(0..<numPlayers) { player in
Rectangle()
.fill(
showColumnIndicators
? Color.blue.opacity(0.2)
: backgroundColor
)
.frame(width: boxWidth, alignment: .center)
}
}
.padding(.vertical, 5)
}
}
struct DisplayPlayerNames: View {
#Binding var players: [Player]
#Binding var numPlayers: Int
var HSspace: Double
var boxWidth: Double
var boxHeight: Double
var body: some View {
HStack(spacing: HSspace) {
ForEach(0..<numPlayers) { player in
TextField("", text: self.$players[player].name)
// .underline()
.multilineTextAlignment(.center)
.frame(width: boxWidth, height: boxHeight, alignment: .center)
}
}
.padding(.vertical, 5)
}
}

Converting CGAL Nef_polyhedron_3 cube to Polyhedron_3

I'm trying to create a simple NEF cube from planes and get its vertices. Unfortunately, I am not getting any facets.
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
typedef Nef_polyhedron::Plane_3 Plane_3;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
// As in https://doc.cgal.org/latest/Nef_3/Nef_3_2point_set_operations_8cpp-example.html
Nef_polyhedron N1(Plane_3(1, 0, 0, -1));
Nef_polyhedron N2(Plane_3(-1, 0, 0, -1));
Nef_polyhedron N3(Plane_3(0, 1, 0, -1));
Nef_polyhedron N4(Plane_3(0, -1, 0, -1));
Nef_polyhedron N5(Plane_3(0, 0, 1, -1));
Nef_polyhedron N6(Plane_3(0, 0, -1, -1));
Nef_polyhedron cube = N1 * N2 * N3 * N4 * N5 * N6;
// Loading a cube from file works:
// std::ifstream file("cube.off");
// assert(file);
// Polyhedron p2;
// file >> p2;
// Nef_polyhedron cube(p2);
Polyhedron p;
assert(cube.is_simple());
cube.convert_to_polyhedron(p);
assert(p.facets_begin() != p.facets_end()); // asserts
What I am doing wrong?

how to write test for breaking down (RTP depayload or parsed) JPEG frame into RTP (RFC 2435)

I am a bit new and still learning about socket and RTP stuff. Basically, i want to write a program that can send a jpeg (ultimately gonna be mjpeg) through RTP using UDP protocol.
I have the program for UDP and be able to send files or stream to a local address (127.0.0.1) using openCV. ok. So that is not a problem.
However, when i try to pass the frame that capture through VideoCapture from openCV, it wont work. Or rather i have no idea how to do it to be exact.
So now, i want to break this problem down and decide to test only on the RTP side.
So as you can see in my main function, i tried to test out the functions but it doesn't look like it works.
Can someone point me to the right direction of how to properly test those function, specially the sendFrame one ?
This code mainly just copy and paste from RFC2435 document.
Thanks
`/*
* Table K.1 from JPEG spec.
*/
static const int jpeg_luma_quantizer[64] = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
`
/*
* Table K.2 from JPEG spec.
*/
static const int jpeg_chroma_quantizer[64] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
int main(int argc, char * argv[]) {
//setup openCV
cvNamedWindow("UDP Video Sender", CV_WINDOW_AUTOSIZE);
CvCapture* capture = cvCreateCameraCapture(0);
if(!capture){
std::cout<<"No camera found."<< std::endl;
goto DONE;
}
IplImage *frame;
frame = cvQueryFrame(capture);
IplImage *small = cvCreateImage(cvSize(frame->width / 2, frame->height / 2),
frame->depth, 3);
while(1){
//capture frame and resize
frame = cvQueryFrame(capture);
cvResize(frame, small, CV_INTER_LINEAR);
cvShowImage("UDP Video Sender", small);
//MakeHeaders(filename,0,5,5,0,128,0);
//MakeTables(128,frame,0);
//MakeDRIHeader();
// MakeHuffmanHeader();
MakeHuffmanHeader(128,1024,1024,uchar *lum_ac_symbols[],1024,1,1 );
//MakeQuantHeader();
DONE:
cout<<"Press any key to continue."<<endl;
}
}
/*
* Call MakeTables with the Q factor and two u_char[64] return arrays
*/
void
MakeTables(int q, u_char *lqt, u_char *cqt)
{
int i;
int factor = q;
if (q < 1) factor = 1;
if (q > 99) factor = 99;
if (q < 50)
q = 5000 / factor;
else
q = 200 - factor*2;
for (i=0; i < 64; i++) {
int lq = (jpeg_luma_quantizer[i] * q + 50) / 100;
int cq = (jpeg_chroma_quantizer[i] * q + 50) / 100;
/* Limit the quantizers to 1 <= q <= 255 */
if (lq < 1) lq = 1;
else if (lq > 255) lq = 255;
lqt[i] = lq;
if (cq < 1) cq = 1;
else if (cq > 255) cq = 255;
cqt[i] = cq;
}
}
/**The following routines can be used to create the JPEG marker segments
corresponding to the table-specification data that is absent from the
RTP/JPEG body.
*/
u_char lum_dc_codelens[] = {
0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
};
u_char lum_dc_symbols[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
};
u_char lum_ac_codelens[] = {
0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d,
};
u_char lum_ac_symbols[] = {
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa,
};
u_char chm_dc_codelens[] = {
0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
};
u_char chm_dc_symbols[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
};
u_char chm_ac_codelens[] = {
0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77,
};
u_char chm_ac_symbols[] = {
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa,
};
u_char *
MakeQuantHeader(u_char *p, u_char *qt, int tableNo)
{
*p++ = 0xff;
*p++ = 0xdb; /* DQT */
*p++ = 0; /* length msb */
*p++ = 67; /* length lsb */
*p++ = tableNo;
memcpy(p, qt, 64);
return (p + 64);
}
u_char *
MakeHuffmanHeader(u_char *p, u_char *codelens, int ncodes,
u_char *symbols, int nsymbols, int tableNo,
int tableClass)
{
*p++ = 0xff;
*p++ = 0xc4; /* DHT */
*p++ = 0; /* length msb */
*p++ = 3 + ncodes + nsymbols; /* length lsb */
*p++ = (tableClass << 4) | tableNo;
memcpy(p, codelens, ncodes);
p += ncodes;
memcpy(p, symbols, nsymbols);
p += nsymbols;
return (p);
}
u_char *
MakeDRIHeader(u_char *p, u_short dri) {
*p++ = 0xff;
*p++ = 0xdd; /* DRI */
*p++ = 0x0; /* length msb */
*p++ = 4; /* length lsb */
*p++ = dri >> 8; /* dri msb */
*p++ = dri & 0xff; /* dri lsb */
return (p);
}
/*
* Arguments:
* type, width, height: as supplied in RTP/JPEG header
* lqt, cqt: quantization tables as either derived from
* the Q field using MakeTables() or as specified
* in section 4.2.
* dri: restart interval in MCUs, or 0 if no restarts.
*
* p: pointer to return area
*
* Return value:
* The length of the generated headers.
*
* Generate a frame and scan headers that can be prepended to the
* RTP/JPEG data payload to produce a JPEG compressed image in
* interchange format (except for possible trailing garbage and
* absence of an EOI marker to terminate the scan).
*/
int MakeHeaders(u_char *p, int type, int w, int h, u_char *lqt,
u_char *cqt, u_short dri)
{
u_char *start = p;
/* convert from blocks to pixels */
w <<= 3;
h <<= 3;
*p++ = 0xff;
*p++ = 0xd8; /* SOI */
p = MakeQuantHeader(p, lqt, 0);
p = MakeQuantHeader(p, cqt, 1);
if (dri != 0)
p = MakeDRIHeader(p, dri);
*p++ = 0xff;
*p++ = 0xc0; /* SOF */
*p++ = 0; /* length msb */
*p++ = 17; /* length lsb */
*p++ = 8; /* 8-bit precision */
*p++ = h >> 8; /* height msb */
*p++ = h; /* height lsb */
*p++ = w >> 8; /* width msb */
*p++ = w; /* wudth lsb */
*p++ = 3; /* number of components */
*p++ = 0; /* comp 0 */
if (type == 0)
*p++ = 0x21; /* hsamp = 2, vsamp = 1 */
else
*p++ = 0x22; /* hsamp = 2, vsamp = 2 */
*p++ = 0; /* quant table 0 */
*p++ = 1; /* comp 1 */
*p++ = 0x11; /* hsamp = 1, vsamp = 1 */
*p++ = 1; /* quant table 1 */
*p++ = 2; /* comp 2 */
*p++ = 0x11; /* hsamp = 1, vsamp = 1 */
*p++ = 1; /* quant table 1 */
p = MakeHuffmanHeader(p, lum_dc_codelens,
sizeof(lum_dc_codelens),
lum_dc_symbols,
sizeof(lum_dc_symbols), 0, 0);
p = MakeHuffmanHeader(p, lum_ac_codelens,
sizeof(lum_ac_codelens),
lum_ac_symbols,
sizeof(lum_ac_symbols), 0, 1);
p = MakeHuffmanHeader(p, chm_dc_codelens,
sizeof(chm_dc_codelens),
chm_dc_symbols,
sizeof(chm_dc_symbols), 1, 0);
p = MakeHuffmanHeader(p, chm_ac_codelens,
sizeof(chm_ac_codelens),
chm_ac_symbols,
sizeof(chm_ac_symbols), 1, 1);
*p++ = 0xff;
*p++ = 0xda; /* SOS */
*p++ = 0; /* length msb */
*p++ = 12; /* length lsb */
*p++ = 3; /* 3 components */
*p++ = 0; /* comp 0 */
*p++ = 0; /* huffman table 0 */
*p++ = 1; /* comp 1 */
*p++ = 0x11; /* huffman table 1 */
*p++ = 2; /* comp 2 */
*p++ = 0x11; /* huffman table 1 */
*p++ = 0; /* first DCT coeff */
*p++ = 63; /* last DCT coeff */
*p++ = 0; /* sucessive approx. */
return (p - start);
};
/*
* RTP data header from RFC1889
*/
typedef struct {
unsigned int version:2; /* protocol version */
unsigned int p:1; /* padding flag */
unsigned int x:1; /* header extension flag */
unsigned int cc:4; /* CSRC count */
unsigned int m:1; /* marker bit */
unsigned int pt:7; /* payload type */
u_int16_t seq; /* sequence number */
u_int32_t ts; /* timestamp */
u_int32_t ssrc; /* synchronization source */
u_int32_t csrc[1]; /* optional CSRC list */
} rtp_hdr_t;
#define RTP_HDR_SZ 12
/* The following definition is from RFC1890 */
#define RTP_PT_JPEG 26
struct jpeghdr {
unsigned int tspec:8; /* type-specific field */
unsigned int off:24; /* fragment byte offset */
u_int8_t type; /* id of jpeg decoder params */
u_int8_t q; /* quantization factor (or table id) */
u_int8_t width; /* frame width in 8 pixel blocks */
u_int8_t height; /* frame height in 8 pixel blocks */
};
struct jpeghdr_rst {
u_int16_t dri;
unsigned int f:1;
unsigned int l:1;
unsigned int count:14;
};
struct jpeghdr_qtable {
u_int8_t mbz;
u_int8_t precision;
u_int16_t length;
};
#define RTP_JPEG_RESTART 0x40
/* Procedure SendFrame:
*
* Arguments:
* start_seq: The sequence number for the first packet of the current
* frame.
* ts: RTP timestamp for the current frame
* ssrc: RTP SSRC value
* jpeg_data: Huffman encoded JPEG scan data
* len: Length of the JPEG scan data
* type: The value the RTP/JPEG type field should be set to
* typespec: The value the RTP/JPEG type-specific field should be set
* to
* width: The width in pixels of the JPEG image
* height: The height in pixels of the JPEG image
* dri: The number of MCUs between restart markers (or 0 if there
* are no restart markers in the data
* q: The Q factor of the data, to be specified using the Independent
* JPEG group's algorithm if 1 <= q <= 99, specified explicitly
* with lqt and cqt if q >= 128, or undefined otherwise.
* lqt: The quantization table for the luminance channel if q >= 128
* cqt: The quantization table for the chrominance channels if
* q >= 128
*
* Return value:
* the sequence number to be sent for the first packet of the next
* frame.
*
* The following are assumed to be defined:
*
* PACKET_SIZE - The size of the outgoing packet
* send_packet(u_int8_t *data, int len) - Sends the packet to the network
*/
#define PACKET_SIZE 512
u_int16_t SendFrame(u_int16_t start_seq, u_int32_t ts, u_int32_t ssrc,
u_int8_t *jpeg_data, int len, u_int8_t type,
u_int8_t typespec, int width, int height, int dri,
u_int8_t q, u_int8_t *lqt, u_int8_t *cqt) {
rtp_hdr_t rtphdr;
struct jpeghdr jpghdr;
struct jpeghdr_rst rsthdr;
struct jpeghdr_qtable qtblhdr;
u_int8_t packet_buf[PACKET_SIZE];
u_int8_t *ptr;
int bytes_left = len;
int seq = start_seq;
int pkt_len, data_len;
/* Initialize RTP header
*/
rtphdr.version = 2;
rtphdr.p = 0;
rtphdr.x = 0;
rtphdr.cc = 0;
rtphdr.m = 0;
rtphdr.pt = RTP_PT_JPEG;
rtphdr.seq = start_seq;
rtphdr.ts = ts;
rtphdr.ssrc = ssrc;
/* Initialize JPEG header
*/
jpghdr.tspec = typespec;
jpghdr.off = 0;
jpghdr.type = type | ((dri != 0) ? RTP_JPEG_RESTART : 0);
jpghdr.q = q;
jpghdr.width = width / 8;
jpghdr.height = height / 8;
/* Initialize DRI header
*/
if (dri != 0) {
rsthdr.dri = dri;
rsthdr.f = 1; /* This code does not align RIs */
rsthdr.l = 1;
rsthdr.count = 0x3fff;
}
/* Initialize quantization table header
*/
if (q >= 128) {
qtblhdr.mbz = 0;
qtblhdr.precision = 0; /* This code uses 8 bit tables only */
qtblhdr.length = 128; /* 2 64-byte tables */
}
while (bytes_left > 0) {
ptr = packet_buf + RTP_HDR_SZ;
jpghdr.off = htonl(jpghdr.off);
/*convert offset in hdr to network order, copy to packet*/
memcpy(ptr, &jpghdr, sizeof(jpghdr));
jpghdr.off = ntohl(jpghdr.off);
ptr += sizeof(jpghdr);
data_len = PACKET_SIZE - (ptr - packet_buf);
if (data_len >= bytes_left) {
data_len = bytes_left;
rtphdr.m = 1;
}
rtphdr.seq = htons(rtphdr.seq);
memcpy(packet_buf, &rtphdr, RTP_HDR_SZ);
memcpy(ptr, jpeg_data + jpghdr.off, data_len);
if(((ptr-packet_buf)+data_len) &&
send(sock[0], packet_buf, (ptr - packet_buf) + data_len, 0)<0)
perror("hre");
jpghdr.off += data_len;
bytes_left -= data_len;
rtphdr.seq = ntohs(rtphdr.seq);
rtphdr.seq++;
}
free(packet_buf);
return rtphdr.seq;
}

Wavefront OBJ import to OpenGL ES 2.0 problems

I finally finished building my Wavefront OBJ parser, but still have some issues rendering my test object (cube).
So this is how i have parsed my vertices and indices (faces) into arrays of data. I have ignored textures and normals for now.
Vertices:
v -0.307796 0.00433517 0
v 0.299126 0.00433517 0
v 0.299126 0.00433517 0.48337
v -0.307796 0.00433517 0.48337
v -0.307796 0.364153 0.48337
v 0.299126 0.364153 0.48337
v 0.299126 0.364153 0
v -0.307796 0.364153 0
As:
const Vertex Vertices[] = {
{-0.307796,0.00433517,0},
{0.299126,0.00433517,0},
{0.299126,0.00433517,0.48337},
{-0.307796,0.00433517,0.48337},
{-0.307796,0.364153,0.48337},
{0.299126,0.364153,0.48337},
{0.299126,0.364153,0},
{-0.307796,0.364153,0}
};
Faces:
f 7/1/1 3/2/2 2/3/3
f 3/4/4 7/5/5 6/6/6
f 5/7/7 1/8/8 4/9/9
f 1/10/10 5/11/11 8/12/12
f 7/13/13 1/14/14 8/15/15
f 1/16/16 7/17/17 2/18/18
f 3/19/19 5/20/20 4/21/21
f 5/22/22 3/23/23 6/24/24
f 5/25/25 7/26/26 8/27/27
f 7/28/28 5/29/29 6/30/30
f 3/31/31 1/32/32 2/33/33
f 1/34/34 3/35/35 4/36/36
As:
const GLubyte Indices[] = {
7,1,1, 3,2,2, 2,3,3,
3,4,4, 7,5,5, 6,6,6,
5,7,7, 1,8,8, 4,9,9,
1,10,10, 5,11,11, 8,12,12,
7,13,13, 1,14,14, 8,15,15,
1,16,16, 7,17,17, 2,18,18,
3,19,19, 5,20,20, 4,21,21,
5,22,22, 3,23,23, 6,24,24,
5,25,25, 7,26,26, 8,27,27,
7,28,28, 5,29,29, 6,30,30,
3,31,31, 1,32,32, 2,33,33,
1,34,34, 3,35,35, 4,36,36
};
Indices only as vertex positions:
const GLubyte Indices[] = {
7, 3, 2,
3, 7, 6,
5, 1, 4,
1, 5, 8,
7, 1, 8,
1, 7, 2,
3, 5, 4,
5, 3, 6,
5, 7, 8,
7, 5, 6,
3, 1, 2,
1, 3, 4
};
SetupVBO:
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
Renderingcode:
glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
_currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
// 3
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
And the result is pretty much nothing at all, so there must be something that im doing completely wrong.
Furthermore will the indices cause any problems since i have not initialized the normals or texture coords?
The Wavefront obj format says that if you have sequences of 3 in the face definitions then their meaning is:
vertex-index/vertex-texture-index/vector-normal-index
You are reading all of the indices into a single array GLubyte Indices[] and using it as it if was just the indices of the vertices.
If you want to do away with textures and normals, you need to take only the first number of every triplet.
In
f 6/1/1 3/2/2 2/3/3 7/4/4
The face is a quad of vertices of indices [6,3,2,7]. Using the indices array like you have requires that you tell OpenGl that the indices are multiplexed in triplets. It does not look like you do that. It also requires additional buffers for normal and texture coordinates.

opengl es 2 just clrears the screen to default color value when using multiple VAOs

i'm fairly new to opengl es 2 and since i'm coding IOS apps, i thought id try it!
So I loaded up a default opengl program using the GLKit template in xcode 4 and after fumbling around in the provided code I begun modifying it so that I could draw multiple different kinds of vertex array objects...the problem is only the call to glClearColor seems to produce any results-the whole screen is just grey now:-(
I don't know what is wrong since I checked with many glGetError calls at key places in the code and it always seems to return 0...and I also, to the extent of my small knowledge, follow the steps required to draw with VAOs since when I modified the default code initially to display a plane it worked OK...
So i'm going to be very grateful if you guys could help the newbie!:)
here is a posting of the different relevant parts of the code:
//init VAOs:
glGenVertexArraysOES(NUM_VAO, _vertexArrayIDS);
glGenBuffers(NUM_VAO, _vertexBufferIDS);
glGenBuffers(NUM_VAO, _indexBufferIDS);
//init gl object for player:
//setupGLObject(VAO_PLAYER, gCubicVertexData, gCubicIndices, GL_STATIC_DRAW);
glBindVertexArrayOES(_vertexArrayIDS[VAO_PLAYER]);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubicVertexData), gCubicVertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gCubicIndices), gCubicIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(24));
//NSLog(#"glError after player init : %d", glGetError());
//init gl object for player wall:
//setupGLObject(VAO_PWALL, gPlayerWallVertexData, gPlayerWallIndices, GL_DYNAMIC_DRAW);
glBindVertexArrayOES(_vertexArrayIDS[VAO_PWALL]);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferIDS[VAO_PWALL]);
glBufferData(GL_ARRAY_BUFFER, sizeof(gPlayerWallVertexData), gPlayerWallVertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gPlayerWallIndices), gPlayerWallIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(24));
//init gl object for wall/floor plane:
//setupGLObject(VAO_WALL_FLOOR_PLANE, gPlanePyVertexData, gPlanePyIndices, GL_STATIC_DRAW);
glBindVertexArrayOES(_vertexArrayIDS[VAO_WALL_FLOOR_PLANE]);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferIDS[VAO_WALL_FLOOR_PLANE]);
glBufferData(GL_ARRAY_BUFFER, sizeof(gPlanePyVertexData), gPlanePyVertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gPlanePyIndices), gPlanePyIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(24));
glBindVertexArrayOES(0);
drawing function - glkView:(GLKView *)view drawInRect:(CGRect)rect
for (NSString *currentKey in g_renderables) {
GameObject *currentRenderable = [g_renderables objectForKey:currentKey];
if (currentRenderable.go_type == LC_FLOOR) {
glBindVertexArrayOES(_vertexArrayIDS[VAO_WALL_FLOOR_PLANE]);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, currentRenderable.go_mvm.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
NSLog(#"glError : %d", glGetError());
glDrawElements(GL_TRIANGLE_STRIP, sizeof(gPlanePyIndices)/sizeof(gPlanePyIndices[0]), GL_UNSIGNED_INT, 0);
}
else if (currentRenderable.go_type == LC_WALL) {
glBindVertexArrayOES(_vertexArrayIDS[VAO_WALL_FLOOR_PLANE]);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, currentRenderable.go_mvm.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawElements(GL_TRIANGLE_STRIP, sizeof(gPlanePyIndices)/sizeof(gPlanePyIndices[0]), GL_UNSIGNED_INT, 0);
}
else if (currentRenderable.go_type == LC_PLAYER) {
glBindVertexArrayOES(_vertexArrayIDS[VAO_PLAYER]);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, currentRenderable.go_mvm.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawElements(GL_TRIANGLE_STRIP, sizeof(gCubicIndices)/sizeof(gCubicIndices[0]), GL_UNSIGNED_INT, 0);
}
matrix computations:
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 1000.0f);
for (NSString *currentKey in g_renderables) {
GLKMatrix4 thisMvm = GLKMatrix4Identity;
GameObject *currentRenderable = [g_renderables objectForKey:currentKey];
if (currentRenderable.go_hasVisual) {
thisMvm = GLKMatrix4Translate(thisMvm, currentRenderable.go_origin.x, currentRenderable.go_origin.y, currentRenderable.go_origin.z);
if (currentRenderable.go_type == LC_WALL || currentRenderable.go_type == LC_PLAYER) {
if (currentRenderable.go_type == LC_PLAYER) {
if (currentRenderable.go_orientation == VV_MINUS_X) {
thisMvm = GLKMatrix4RotateY(thisMvm, GLKMathDegreesToRadians(90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_X) {
thisMvm = GLKMatrix4RotateY(thisMvm, GLKMathDegreesToRadians(-90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_Z) {
thisMvm = GLKMatrix4RotateY(thisMvm, GLKMathDegreesToRadians(180.0f));
}
}
else {
if (currentRenderable.go_orientation == VV_MINUS_X) {
thisMvm = GLKMatrix4RotateZ(thisMvm, GLKMathDegreesToRadians(90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_X) {
thisMvm = GLKMatrix4RotateZ(thisMvm, GLKMathDegreesToRadians(-90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_Z) {
thisMvm = GLKMatrix4RotateX(thisMvm, GLKMathDegreesToRadians(-90.0f));
}
else if (currentRenderable.go_orientation == VV_MINUS_Z) {
thisMvm = GLKMatrix4RotateX(thisMvm, GLKMathDegreesToRadians(90.0f));
}
}
}
if (currentRenderable.go_type != LC_LINKED_WALL) thisMvm = GLKMatrix4Scale(thisMvm, currentRenderable.width, currentRenderable.height, currentRenderable.depth);
thisMvm = GLKMatrix4Multiply(GLKMatrix4MakeLookAt(g_currentCam.go_origin.x, g_currentCam.go_origin.y, g_currentCam.go_origin.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f), thisMvm);
//NSLog(#"%f", thisMvm.m[10]);
thisMvm = GLKMatrix4Multiply(projectionMatrix, thisMvm);
currentRenderable.go_mvm = thisMvm;
}
}
That's it.Please help!!!
I think there is a bit of confusion in the way you understood the glclearcolor.
The main idea is that for every frame you should clear at least the color bit by doing a glclear, it is like cleaning a board after you did your drawings.
The glclearcolor instead instructs OpenGL which color should be used for the whole screen after the clear.
An example of this is the following:
glClearColor(1.0f,0.0f,0.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
This example tells OpenGL to use the red color when a color of the clear of the color_buffer_bit is required.
I hope this helps in some way.