Simple Opengl Triangle on mavericks - macos

I am new at opengl. I am starting with a simple triangle using GLFW , but I dont get anything drawn.
My system is :
OSX Mavericks 10.9.2 Intel HD 4000
compilation cmd line:
g++ main.cpp -o Test -I/usr/local/include -L/usr/local/lib -lglfw -framework Opengl
First thing I noticed odd was, on compilation , it did not identify
glGenVertexArrays , and suggested: glGenVertexArraysAPPLE same for:glBindVertexArray and suggested: glBindVertexArrayAPPLE
On using APPLE ext , didnt draw anything.
What am I missing here?
#include <iostream>
#include <OpenGL/gl.h>
#include <GLFW/glfw3.h>
#include <string.h>
GLuint vao=0;
GLuint shader_programme;
void CheckGLErrors(std::string str)
{
int errCount = 0;
GLenum currError = glGetError();
if(currError != GL_NO_ERROR)
{
//Do something with `currError`.
std::cout<<"\n"<<str<<" Error raised:"<<currError<<"\n";
}
}
void initVertex()
{
float points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
static const float colors[] =
{
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
};
glGenVertexArraysAPPLE(1, &vao);
glBindVertexArrayAPPLE (vao);
GLuint vbo = 0;
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (float), points, GL_STATIC_DRAW);
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
const char* vertex_shader =
"#version 400\n"
"in vec3 vp;"
"void main () {"
" gl_Position = vec4 (vp, 1.0);"
"}";
const char* fragment_shader =
"#version 400\n"
"out vec4 frag_colour;"
"void main () {"
" frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);"
"}";
GLuint vs = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (vs, 1, &vertex_shader, NULL);
glCompileShader (vs);
GLint status = GL_TRUE;
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
if(status != GL_TRUE) std::cout<<"VS FAILED\n";
GLuint fs = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (fs, 1, &fragment_shader, NULL);
glCompileShader (fs);
status = GL_TRUE;
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
if(status != GL_TRUE) std::cout<<"PS FAILED\n";
shader_programme = glCreateProgram ();
glAttachShader (shader_programme, fs);
glAttachShader (shader_programme, vs);
glLinkProgram (shader_programme);
}
int main(int argc, char * argv[])
{
GLFWwindow* window;
int ver[3];
glfwGetVersion(&ver[0], &ver[1], &ver[2]);
std::cout << "major " <<ver[0] <<"minor: "<<ver[1]<<" ver: "<<ver[2];
/* Initialize the library */
if (!glfwInit())
{
std::cout << "Error";
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
std::cout << "Create window Error";
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
std::cout<<"Version: " << glGetString(GL_VERSION);;
initVertex();
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPointSize(40.0f);
glClearColor(0.0f,1.0f,0.0f,0.0f);
glUseProgram(shader_programme);
glBindVertexArrayAPPLE(vao);
glDrawArrays(GL_TRIANGLE, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}

On the missing declaration for glGenVertexArrays(), you need to include gl3.h instead of gl.h to get GL3 level functionality:
#include <OpenGL/gl3.h>
One problem I see in your code is that you use vertex attribute location 0 for setting up your coordinates. The attribute location is the first argument to glEnableVertexAttribArray() and glVertexAttribPointer(). But you don't really know that the location of vp in your shader program is 0. The easiest way to ensure this is that you specify it directly in your shader code by extending the declaration of vp:
layout(location = 0) in vec3 vp;
This works with GL 3.3 and higher. An alternative with older GL versions is to make the following API call before the glLinkProgram() call:
glBindAttribLocation(shader_programme, 0, "vp");

Related

Why do I get "unsupported shader version" using "#version 300 es" at emscripten?

I don't know why I get a "unsupported shader version" error message using #version 300 es in my vertex shader with the latest emscripten 1.39. With #version 100 it works fine.
const GLchar* vertex_shader_code[] = {
"#version 300 es\n"
"precision mediump float; \n"
"void main() { \n"
"gl_Position = vec4(0.0, 0.0, 0.0, 1.0); \n"
"} \n"
};
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_version compiled;
SDL_version linked;
SDL_VERSION(&compiled);
SDL_GetVersion(&linked);
printf("Compiled SDL version: %d.%d.%d\n", compiled.major, compiled.minor, compiled.patch);
printf("Linked SDL version: %d.%d.%d\n", linked.major, linked.minor, linked.patch);
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(CANVAS_WIDTH, CANVAS_HEIGHT, 0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_shader_code, 0);
glCompileShader(vertex_shader);
auto compile_success = 0;
auto compile_info_lenght = 0;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_success);
if(compile_success == GL_FALSE) {
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &compile_info_lenght);
std::string vertex_shader_log(compile_info_lenght, ' ');
glGetShaderInfoLog(vertex_shader, compile_info_lenght, NULL, &vertex_shader_log[0]);
int n = vertex_shader_log.length();
char char_array[n + 1];
strcpy(char_array, vertex_shader_log.c_str());
printf("%s\n", char_array);
glDeleteShader(vertex_shader);
return 0;
}
For the built I use emcc -s main.cpp -o index.html --shell-file shell.html -s USE_SDL=2 -s FULL_ES3=1
Message:
Compiled SDL version: 2.0.9
Linked SDL version: 2.0.9
ERROR: unsupported shader version
What I'm doing wrong?
Without your full program, it is difficult to see everything that is wrong. You need to build with the correct options, call your WASM module correctly from JavaScript, and set up everything correctly in SDL and OpenGL.
Here is a working example:
// main.cpp
#include <stdio.h>
#include <stdarg.h>
#include <emscripten.h>
#include <SDL.h>
#include <SDL_opengles2.h>
SDL_Window *sdlWindow;
static const char *vertexShaderSource[] = {
"#version 300 es\n"
"in vec4 position;\n"
"void main(void) {\n"
" gl_Position = vec4(position.xyz, 1.0);\n"
"}\n"
};
static const char *fragmentShaderSource[] = {
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 fragColor;\n"
"void main(void) {\n"
" fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n"
};
static void
fatal(const char *const fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
printf("\n");
va_end(args);
for (;;) {
SDL_Delay(1000);
}
}
static GLuint
compileShader(GLenum shaderType, const char **shaderSource)
{
GLuint shdr = glCreateShader(shaderType);
glShaderSource(shdr, 1, shaderSource, nullptr);
glCompileShader(shdr);
GLint isCompiled = 0;
glGetShaderiv(shdr, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) {
GLint maxLength = 0;
glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &maxLength);
char *errorString = (char *) malloc(maxLength + 1);
glGetShaderInfoLog(shdr, maxLength, &maxLength, errorString);
fatal("Compile failed: %s", errorString);
}
return shdr;
}
static void
_set_SDL_Attribute(SDL_GLattr attr, int value, const char *attrName)
#define set_SDL_Attribute(x, v) _set_SDL_Attribute(x, v, #x)
{
if (SDL_GL_SetAttribute(attr, value) != 0) {
fatal("SDL set attrib failed: %s, %s", attrName, SDL_GetError());
}
}
static void
setupSDL(void)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fatal("Unable to init SDL: %s", SDL_GetError());
}
SDL_version compiled;
SDL_version linked;
SDL_VERSION(&compiled);
SDL_GetVersion(&linked);
printf("Compiled SDL version: %d.%d.%d\n",
compiled.major, compiled.minor, compiled.patch);
printf("Linked SDL version: %d.%d.%d\n",
linked.major, linked.minor, linked.patch);
set_SDL_Attribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
set_SDL_Attribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
set_SDL_Attribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
set_SDL_Attribute(SDL_GL_DOUBLEBUFFER, 1);
set_SDL_Attribute(SDL_GL_DEPTH_SIZE, 24);
SDL_Renderer *renderer;
if (SDL_CreateWindowAndRenderer(400, 400, SDL_WINDOW_OPENGL,
&sdlWindow, &renderer) < 0) {
fatal("Unable to create windown: %s", SDL_GetError());
}
SDL_GLContext glContext = SDL_GL_CreateContext(sdlWindow);
if (glContext == NULL) {
fatal("Unable to create context: %s", SDL_GetError());
}
printf("GL Version={%s}\n", glGetString(GL_VERSION));
printf("GLSL Version={%s}\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
}
static void
setupOpenGL(void)
{
GLuint shaderProgram = glCreateProgram();
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER,
fragmentShaderSource);
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
static const GLfloat vertices[] = { 0.0f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f };
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // Input offset is zero.
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black
}
static void
mainLoop(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(sdlWindow);
}
int
main(void)
{
setupSDL();
setupOpenGL();
emscripten_set_main_loop(mainLoop, 0, true);
return 0;
}
Compile with these options:
emcc main.cpp -O3 -Wall -Wextra -Werror -s WASM=1 -s USE_SDL=2 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -o foo.js
Launch from HTML like this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>Wasm Test Page</h1>
<canvas id=canvas width=400 height=400 oncontextmenu="event.preventDefault()"></canvas>
<script>var Module = { canvas: document.getElementById('canvas') }; </script>
<script src="foo.js"></script>
</body>
</html>
If everything works, you should see a red triangle on a black background in your browser window.
HTH.
For those with the same problem, the solution is SDL_WINDOW_OPENGL.
SDL_CreateWindowAndRenderer(CANVAS_WIDTH, CANVAS_HEIGHT, SDL_WINDOW_OPENGL, &window, &renderer);

Xcode Building OpenGL Mistake link commande failure with exit code 1

these days I am learning something about OpenGL in the website LearnOpenGL(https://learnopengl.com/Getting-started/Hello-Triangle),and i use Xcode to run the code.My Xcode's version is 10.0 (10A255).About several days before, after the command line tool is updated, some code can not be compiled.The error information is linker command failed with exit code 1 (use -v to see invocation).I have add the link library already
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int
height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float vertices[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(window))
{
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}

How to load and display an image in OpenGL ES 3.0 using C++

I'm trying to make a simple app on Android Studio using the NDK, JNI to call C++ code that load and display an image. I have managed to create the surface and draw a simple Triangle.
Now, I'm looking for a way to load and display an image in OpenGL ES 3.0 using C++. I have done the search around but all of them is either too complex to me or outdated or written in Java. It would be great if someone could guide me with a simple example.
After working around, I finally make it. Below is my C++ source code. I use stb_image library to load the image.
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// OpenGL ES 3.0 code
#include <jni.h>
#include <android/log.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <GLES3/gl3ext.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "stb_image.h"
#define LOG_TAG "libgl2jni"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
GLuint mTexture, VAO;// Create reference Id for the texture
GLuint gProgram;
GLuint gvPositionHandle;
static void printGLString(const char *name, GLenum s) {
const char *v = (const char *) glGetString(s);
LOGI("GL %s = %s\n", name, v);
}
static void checkGlError(const char* op) {
for (GLint error = glGetError(); error; error
= glGetError()) {
LOGI("after %s() glError (0x%x)\n", op, error);
}
}
auto gVertexShader =
"#version 300 es\n"
"layout (location=0) in vec3 position;\n"
"layout (location=1) in vec3 color;\n"
"layout (location=2) in vec2 texCoord;\n"
"out vec3 ourColor;\n"
"out vec2 TexCoord;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position,1.0f); // Add the xOffset to the x position of the vertex position\n"
"ourColor = color;\n"
"TexCoord= vec2(texCoord.x,1.0f-texCoord.y);\n"
"}";
auto gFragmentShader =
"#version 300 es\n"
"in vec3 ourColor;\n"
"in vec2 TexCoord;\n"
"out vec4 color;\n"
"uniform sampler2D ourTexture;\n"
"void main()\n"
"{\n"
"color = texture(ourTexture , TexCoord);\n"
"}\n";
GLuint loadShader(GLenum shaderType, const char* pSource) {
GLuint shader = glCreateShader(shaderType);
if (shader) {
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen) {
char* buf = (char*) malloc(infoLen);
if (buf) {
glGetShaderInfoLog(shader, infoLen, NULL, buf);
LOGE("Could not compile shader %d:\n%s\n",
shaderType, buf);
free(buf);
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { // Load and Bind Fragments to Progam and link program then return result
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
if (!vertexShader) {
return 0;
}
GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader) {
return 0;
}
GLuint program = glCreateProgram();
if (program) {
glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength) {
char* buf = (char*) malloc(bufLength);
if (buf) {
glGetProgramInfoLog(program, bufLength, NULL, buf);
LOGE("Could not link program:\n%s\n", buf);
free(buf);
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
bool setupGraphics(int w, int h) {
printGLString("Version", GL_VERSION);
printGLString("Vendor", GL_VENDOR);
printGLString("Renderer", GL_RENDERER);
printGLString("Extensions", GL_EXTENSIONS);
LOGI("setupGraphics(%d, %d)", w, h);
gProgram = createProgram(gVertexShader, gFragmentShader);
if (!gProgram) {
LOGE("Could not create program.");
return false;
}
gvPositionHandle = glGetAttribLocation(gProgram, "position");
checkGlError("glGetAttribLocation");
LOGI("glGetAttribLocation(\"position\") = %d\n",
gvPositionHandle);
glViewport(0, 0, w, h);
checkGlError("glViewport");
return true;
}
GLfloat recVertices[] = {
// Positions // Colors // Texture Coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left
};
GLuint indices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
void initBuffers()
{
GLuint VBOs[2], EBO; // Initialize an buffer to store all the verticles and transfer them to the GPU
glGenVertexArrays (1,&VAO); // Generate VAO
glGenBuffers(1, VBOs); // Generate VBO
glGenBuffers(1, &EBO); // Generate EBO
glBindVertexArray (VAO);// Bind the Vertex Array
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);//Bind verticles array for OpenGL to use
glBufferData(GL_ARRAY_BUFFER, sizeof(recVertices), recVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//Bind the indices for information about drawing sequence
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 1. set the vertex attributes pointers
// Position Attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Color Attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
//Texture Coordinate Attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);//3. Unbind VAO
}
void generateTexture()
{
glGenTextures(1 , &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);// Bind our 2D texture so that following set up will be applied
//Set texture wrapping parameter
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
//Set texture Filtering parameter
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
//Load the image
int picWidth,picHeight,n;
unsigned char* image = stbi_load("/storage/emulated/sdcard/Lighthouse.jpg", &picWidth, &picHeight, &n,0);
if (image == NULL ) {
LOGI("Failed to load image: %s", stbi_failure_reason());
}
//Generate the image
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB , picWidth , picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(image);// Free the reference to the image
glBindTexture(GL_TEXTURE_2D,0); //Unbind 2D textures
}
void renderFrame() {
static float grey;
grey += 0.01f;
if (grey > 1.0f) {
grey = 0.0f;
}
generateTexture();
glClearColor(grey+0.05f, grey-0.03f, grey+0.02f, grey-0.04f);
checkGlError("glClearColor");
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
checkGlError("glClear");
glUseProgram(gProgram);
checkGlError("glUseProgram");
/*glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, recVertices);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
checkGlError("glEnableVertexAttribArray");
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
checkGlError("glDrawArrays");*/
glActiveTexture(GL_TEXTURE0);
checkGlError("glActiveTexture");
glBindTexture(GL_TEXTURE_2D,mTexture);
checkGlError("glBindTexture");
GLint mlocation = glGetUniformLocation(gProgram,"ourTexture");
checkGlError("glGetUniformLocation");
glUniform1i(mlocation,0);
checkGlError("glUniform1i");
initBuffers();
glBindVertexArray(VAO);
checkGlError("glBindVertexArray");
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
}
extern "C" {
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv * env, jobject obj);
};
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
{
setupGraphics(width, height);
}
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv * env, jobject obj)
{
renderFrame();
}

egl pbuffer offscreen rendering can only read back background

I want to achieve egl offscreen rendering with pbuffer surface. but all I can read back is the background color. things I draw can't be seen.
for example, if I clear the screen with blue, the read back image via glReadPixel is just a blue-colored image, there is no other things.
I have really run out of ideas
#include <QCoreApplication>
#include <QDebug>
#include <QImage>
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <QElapsedTimer>
GLuint LoadShader(const char *shaderSrc, GLenum type)
{
GLuint shader;
GLint compiled;
// Create the shader object
shader = glCreateShader(type);
if(shader == 0)
return 0;
// Load the shader source
glShaderSource(shader, 1, &shaderSrc, NULL);
// Compile the shader
glCompileShader(shader);
// Check the compile status
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);
qDebug() << "Error compiling shader:" << infoLog;
free(infoLog);
}
glDeleteShader(shader);
return 0;
}
return shader;
}
int main(int argc, char *argv[])
{
GLuint renderBufferWidth = 1920;
GLuint renderBufferHeight = 1080;
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE };
// Step 1 - Get the default display.
EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);
// Step 2 - Initialize EGL.
eglInitialize(eglDisplay, 0, 0);
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);
// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[23];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_PBUFFER_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_CONFORMANT;
pi32ConfigAttribs[5] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[6] = EGL_COLOR_BUFFER_TYPE;
pi32ConfigAttribs[7] = EGL_RGB_BUFFER;
pi32ConfigAttribs[8] = EGL_LUMINANCE_SIZE;
pi32ConfigAttribs[9] = 0;
pi32ConfigAttribs[10] = EGL_RED_SIZE;
pi32ConfigAttribs[11] = 5;
pi32ConfigAttribs[12] = EGL_GREEN_SIZE;
pi32ConfigAttribs[13] = 6;
pi32ConfigAttribs[14] = EGL_BLUE_SIZE;
pi32ConfigAttribs[15] = 5;
pi32ConfigAttribs[16] = EGL_ALPHA_SIZE;
pi32ConfigAttribs[17] = 0;
pi32ConfigAttribs[18] = EGL_DEPTH_SIZE;
pi32ConfigAttribs[19] = 16;
pi32ConfigAttribs[20] = EGL_LEVEL;
pi32ConfigAttribs[21] = 0;
pi32ConfigAttribs[22] = EGL_NONE;
// Step 5 - Find a config that matches all requirements.
int iConfigs;
EGLConfig eglConfig;
eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1,
&iConfigs);
if (iConfigs != 1)
{
printf("Error: eglChooseConfig(): config not found.\n");
exit(-1);
}
EGLint pbufferAttribs[5];
pbufferAttribs[0] = EGL_WIDTH;
pbufferAttribs[1] = renderBufferWidth;
pbufferAttribs[2] = EGL_HEIGHT;
pbufferAttribs[3] = renderBufferHeight;
pbufferAttribs[4] = EGL_NONE;
// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
if (eglSurface == EGL_NO_SURFACE)
{
qDebug() << "surface error";
exit(1);
}
// Step 7 - Create a context.
EGLContext eglContext;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL,
ai32ContextAttribs);
if (eglContext == EGL_NO_CONTEXT)
{
qDebug() << "context error";
exit(1);
}
// Step 8 - Bind the context to the current thread
bool result = eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!result)
{
qDebug() << "make current error" << eglGetError();
}
GLuint programObject;
{ //init
char* vShaderStr =
"attribute vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
char* fShaderStr =
"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;
// Load the vertex/fragment shaders
vertexShader = LoadShader(vShaderStr, GL_VERTEX_SHADER);
fragmentShader = LoadShader(fShaderStr, GL_FRAGMENT_SHADER);
// Create the program object
programObject = glCreateProgram();
if(programObject == 0)
return 0;
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
// Bind vPosition to attribute 0
glBindAttribLocation(programObject, 0, "vPosition");
// Link the program
glLinkProgram(programObject);
// Check the link status
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);
qDebug() <<"Error linking program:" << infoLog;
free(infoLog);
}
glDeleteProgram(programObject);
}
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}
{//draw
GLfloat vVertices[] = {0.0f, 1.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f};
// Set the viewport
glViewport(0, 0, 1920, 1080);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use the program object
glUseProgram(programObject);
// Load the vertex data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
int size = 4 * renderBufferHeight * renderBufferWidth;
unsigned char *data2 = new unsigned char[size];
eglSwapBuffers( eglDisplay, eglSurface);
glReadPixels(0,0,renderBufferWidth,renderBufferHeight,GL_RGBA, GL_UNSIGNED_BYTE, data2);
qDebug() << glGetError() << eglGetError();
QImage saveImage(data2, renderBufferWidth, renderBufferHeight, QImage::Format_RGBA8888_Premultiplied);
saveImage.save("haha.png");
QCoreApplication a(argc, argv);
qDebug() << "done";
return a.exec();
}
today, I ran the same program on a machine with NVIDIA graphics card and the proprietary driver installed.
it turned out that the code works very well.
this is likely a bug of intel driver.

OpenGL 3.2 not working on mac os x with GLFW, can't draw anything

I'm setting up a OpenGL 3.2 Xcode project using GLFW and GLEW. I've added the GLFW include path to the header paths, and added libglfw.a to the project. I've also added the cocoa and OpenGL frameworks. Then I try to use this sample code:
main.cpp:
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/glfw.h>
#include "math3d.h"
GLuint VBO;
static const char* pVS = " \n\
#version 150 \n\
\n\
layout (location = 0) in vec3 Position; \n\
\n\
void main() \n\
{ \n\
gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0); \n\
}";
static const char* pFS = " \n\
#version 150 \n\
\n\
out vec4 FragColor; \n\
\n\
void main() \n\
{ \n\
FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n\
}";
static void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glfwSwapBuffers();
}
static void CreateVertexBuffer()
{
Vector3f Vertices[3];
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}
static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType)
{
GLuint ShaderObj = glCreateShader(ShaderType);
if (ShaderObj == 0) {
fprintf(stderr, "Error creating shader type %d\n", ShaderType);
return ;
}
const GLchar* p[1];
p[0] = pShaderText;
GLint Lengths[1];
Lengths[0]= strlen(pShaderText);
glShaderSource(ShaderObj, 1, p, Lengths);
glCompileShader(ShaderObj);
GLint success;
glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);
return;
}
glAttachShader(ShaderProgram, ShaderObj);
}
static void CompileShaders()
{
GLuint ShaderProgram = glCreateProgram();
if (ShaderProgram == 0) {
fprintf(stderr, "Error creating shader program\n");
return;
}
AddShader(ShaderProgram, pVS, GL_VERTEX_SHADER);
AddShader(ShaderProgram, pFS, GL_FRAGMENT_SHADER);
GLint Success = 0;
GLchar ErrorLog[1024] = { 0 };
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
if (Success == 0) {
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
return;
}
glValidateProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);
if (!Success) {
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
return;
}
glUseProgram(ShaderProgram);
}
int main(int argc, char** argv)
{
glfwInit();
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
glfwOpenWindow(600, 600, 0, 0, 0, 0, 0, 0, GLFW_WINDOW);
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
CreateVertexBuffer();
CompileShaders();
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
while (1)
{
RenderScene();
}
return 0;
}
math3d.h:
#ifndef GLFWTest_math3d_h
#define GLFWTest_math3d_h
struct Vector3f
{
float x;
float y;
float z;
Vector3f()
{
}
Vector3f(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
}
};
#endif
but nothing gets drawn, I only get a yellow window. Any Idea why this is happening? I'm using a mac book pro a year or so old with osx lion installed

Resources