Qt OpenGLWindow not rendering triangle - qt

Using Qt5 (5.12) and OpenGL 4.3, code below won't draw the rectangle I want.
compiles fine, but just shows the black background (color changes when I change the value, so at least something working) but doesn't show any the triangle
The example is from early chapters of the OpenGL blue book. Since thats the only resource I have and can comfortably follow, would like to code directly with opengl functions and avoid using Qt's class's at this point if possible.
> glxinfo
OpenGL core profile version string: 4.6.0 NVIDIA 390.77
OpenGL core profile shading language version string: 4.60 NVIDIA
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 4.6.0 NVIDIA 390.77
OpenGL shading language version string: 4.60 NVIDIA
please note Window is initialized with OpenGL, CoreProfile, 4.3 format
class Window : public QOpenGLWindow, protected QOpenGLFunctions_4_3_Core
{
Q_OBJECT
...
// QOpenGLWindow interface
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
GLuint rendering_program;
GLuint vertex_array_object;
}
initializeGL() ----------------
{
/**** COMPILE SHADERS ****/
GLuint vertex_shader, fragment_shader, program;
static const GLchar *vertex_shader_source[] = {
"#version 430 core \n",
" \n",
"void main(void) \n",
"{ \n",
" const vec4 vertices[3] = vec4[3]( \n",
" vec4( 0.25, -0.25, 0.5, 1.0), \n",
" vec4(-0.25, -0.25, 0.5, 1.0), \n",
" vec4( 0.25, 0.25, 0.5, 1.0)); \n",
" \n",
" gl_Position = vertices[gl_VertexID]; \n",
"} \n",
};
static const GLchar *fragment_shader_source[] = {
"#version 430 core \n",
" \n",
"out vec4 color; \n",
" \n",
"void main(void) \n",
"{ \n",
" color = vec4(0.0, 0.8, 1.0, 1.0); \n",
"} \n",
};
// create and compile vertex shader
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
glCompileShader(vertex_shader);
// create and compile fragment shader
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
glCompileShader(fragment_shader);
// crate a program, attach shaders to it
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
rendering_program = program;
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
}
paintGL() --------------------------
{
const GLfloat color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, color);
glUseProgram(rendering_program);
glBindVertexArray(vertex_array_object);
glDrawArrays(GL_TRIANGLES, 0, 3);
glFlush();
}

This was hard to see.
The declaration of vertex_shader_source
static const GLchar *vertex_shader_source[] = {
"#version 430 core \n",
" \n",
"void main(void) \n",
"{ \n",
" const vec4 vertices[3] = vec4[3]( \n",
" vec4( 0.25, -0.25, 0.5, 1.0), \n",
" vec4(-0.25, -0.25, 0.5, 1.0), \n",
" vec4( 0.25, 0.25, 0.5, 1.0)); \n",
" \n",
" gl_Position = vertices[gl_VertexID]; \n",
"} \n",
};
and fragment_shader_source
static const GLchar *fragment_shader_source[] = {
"#version 430 core \n",
" \n",
"out vec4 color; \n",
" \n",
"void main(void) \n",
"{ \n",
" color = vec4(0.0, 0.8, 1.0, 1.0); \n",
"} \n",
};
are not of type const char*, but of const char*[]. vertex_shader has 11 elements, and fragment_shader_source has 8 elements.
The 2nd paramter of glShaderSource has to be the number of elements in the array.
So it has to be:
glShaderSource(vertex_shader, 11, vertex_shader_source, NULL);
respectively
glShaderSource(fragment_shader, 8, fragment_shader_source, NULL);
I recommend to use Raw string literal instead of arrays:
const char *vertex_shader_source = R"(
#version 430 core
void main(void)
{
const vec4 vertices[3] = vec4[3](
vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
gl_Position = vertices[gl_VertexID];
}
)";
const char *fragment_shader_source = R"(
#version 430 core
out vec4 color;
void main(void)
{
color = vec4(0.0, 0.8, 1.0, 1.0);
}
)";
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
Further, check if the compilation of the shaders succeeded:
e.g.
GLint status;
glCompileShader(vertex_shader);
glGetShaderiv( vertex_shader, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetShaderiv( vertex_shader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( vertex_shader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
and if linking the program succeeded:
e.g.
glLinkProgram(program);
glGetProgramiv( program, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( program, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}

Related

How do I send/read data from device in OpenCL?

How do I just create some data on device and then send/read it on the host?
I tried following but does not seem to work.
#include <stdio.h>
#include <stdlib.h>
#include "vectors.h"
#include "sphere.h"
#include "shading.h"
#include "ray.h"
#include "stdbool.h"
#include <CL/cl.h>
#if defined __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#elif defined (WIN32)
#include <GL/freeglut.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/freeglut_std.h>
#endif
#include <time.h>
VECTOR3D light;
SPHERE sphere[NSPHERES];
static PIXEL pixel;
VIEWPORT viewport;
VECTOR3D view_point;
VEC_BASIS camera_frame;
cl_double focal_distance;
double color;
//double kd_red, kd_green, kd_blue;
//double ks_red, ks_green, ks_blue;
double red, green, blue;
double light_intensity, ambi_light_intensity;
double theta, reflected_theta;
int bShadow = 0;
int direction[NSPHERES];
int intersection_object = -1; // none
double current_lambda = 0x7fefffffffffffff; // maximum positive double
double current_reflected_lambda = 0x7fefffffffffffff; // maximum positive double
// window identifier:
static int win;
void Timer (int obsolete) {
glutPostRedisplay();
glutTimerFunc(10, Timer, 0);
}
// opencl stuff
typedef struct cl_struct {
cl_platform_id platform_id;
cl_device_id device_id;
cl_context context;
cl_command_queue queue;
} cl_struct;
#define MAX_SOURCE_SIZE (0x100000)
void disp2(void) {
int i,j;
PIXEL* pCurrentPixel;
PIXEL* pPixels;
int VPWIDTH = viewport.xvmax - viewport.xvmin;
int VPHEIGHT = viewport.yvmax - viewport.yvmin;
pPixels = (PIXEL*)(viewport.pPixels);
//clear all pixels:
glClear(GL_COLOR_BUFFER_BIT);
// For all pixels:
for (i=0; i<VPWIDTH; i++) {
for (j=0; j<VPHEIGHT; j++) {
pCurrentPixel = (PIXEL*)(pPixels + VPWIDTH*i + j);
//set color for the current pixel:
glColor3f(pCurrentPixel->rgb[0] , pCurrentPixel->rgb[1], pCurrentPixel->rgb[2]);
// draw pixel
glBegin(GL_POINTS);
glVertex2i(i, j);
glEnd();
} // j
} //i
//glFlush();
glutSwapBuffers();
}
void init(void) {
direction[0] = 1;
direction[1] = 0;
direction[2] = 1;
pixel.i = 0;
pixel.j = 0;
// set scene:
// 1. define viewport
viewport.xvmin = -VIEWPLANE;
viewport.yvmin = -VIEWPLANE;
viewport.xvmax = VIEWPLANE;
viewport.yvmax = VIEWPLANE;
// 2. allocate enough space for pixels in viewport
viewport.pPixels = (PIXEL *) malloc(sizeof(PIXEL) * (viewport.xvmax - viewport.xvmin) * (viewport.yvmax- viewport.yvmin));
// 3. set camera:
camera_frame.u.x = 1.0;
camera_frame.u.y = 0.0;
camera_frame.u.z = 0.0;
camera_frame.v.x = 0.0;
camera_frame.v.y = 1.0;
camera_frame.v.z = 0.0;
camera_frame.n.x = 0.0;
camera_frame.n.y = 0.0;
camera_frame.n.z = 1.0;
view_point.x = (viewport.xvmax - viewport.xvmin) / 2.0 ;
view_point.y = (viewport.yvmax - viewport.yvmin) / 2.0 ;
view_point.z = 0.0;
// 4. set light:
light.x = view_point.x - 1300;
light.y = view_point.y + 1300 ;
light.z = view_point.z - 300;
ambi_light_intensity = 1.0;
light_intensity = 1.0;
focal_distance = FOCALDIST;
// 5. put spheres behind the viewport:
sphere[0].radius = RADIUS/1.5;
sphere[0].center.x = view_point.x - (RADIUS+30);
sphere[0].center.y = view_point.y ;
sphere[0].center.z = view_point.z - focal_distance - (2*RADIUS+20);
// the first sphere is blue:
set_rgb_array(sphere[0].kd_rgb, 0.0, 0.0, 0.8);
set_rgb_array(sphere[0].ks_rgb, 1.0, 1.0, 1.0);
set_rgb_array(sphere[0].ka_rgb, 0.0, 0.0, 0.2);
sphere[0].shininess = 100.0;
sphere[0].mirror = false;
sphere[1].radius = RADIUS/1.2;
sphere[1].center.x = view_point.x + 0;
sphere[1].center.y = view_point.y + 50;
sphere[1].center.z = view_point.z - focal_distance - (3*RADIUS+20);
// the second sphere is green:
set_rgb_array(sphere[1].kd_rgb, 0.0, 0.5, 0.0);
set_rgb_array(sphere[1].ks_rgb, 1.0, 1.0, 1.0);
set_rgb_array(sphere[1].ka_rgb, 0.0, 0.2, 0.0);
sphere[1].shininess = 10.0;
sphere[1].mirror = false;
sphere[2].radius = RADIUS;
sphere[2].center.x = view_point.x + (2*RADIUS+30);
sphere[2].center.y = view_point.y + 100;
sphere[2].center.z = view_point.z - focal_distance - (4*RADIUS+20);
// the third sphere is red:
set_rgb_array(sphere[2].kd_rgb, 1.0, 0.0, 0.0);
set_rgb_array(sphere[2].ks_rgb, 1.0, 1.0, 1.0);
set_rgb_array(sphere[2].ka_rgb, 0.2, 0.0, 0.0);
sphere[2].shininess = 100.0;
sphere[2].mirror = false;
sphere[3].radius = 1*RADIUS;
sphere[3].center.x = view_point.x ;
sphere[3].center.y = view_point.y - 100*RADIUS-130;
sphere[3].center.z = view_point.z - focal_distance - (4*RADIUS+20);
// the third sphere is red:
set_rgb_array(sphere[3].kd_rgb, 0.5, 0.5, 0.5);
set_rgb_array(sphere[3].ks_rgb, 1.0, 1.0, 1.0);
set_rgb_array(sphere[3].ka_rgb, 0.5, 0.5, 0.5);
sphere[3].shininess = 100.0;
sphere[3].mirror = false;
// set clearing (background) color to white:
glClearColor(0.0, 0.0, 0.0, 0.0);
// specify that ortgogonal 2D projection is to be used to
// map context of 2D world coordinats to the screen. We use the
// world-coordinate rectangle of the same aspect ratio as the display window
// so ther is no distortion:
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, WINDOW, 0.0, WINDOW);
}
int main(int argc, const char * argv[]) {
clock_t startCPU, endCPU, startGPU, endGPU;
// init glut:
glutInit (&argc, argv);
// specify the display mode to be RGB and single buffering:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
// specify the initial window position:
glutInitWindowPosition(100, 100);
// specify the initial window size:
glutInitWindowSize(WINDOW,WINDOW);
// create the window and set title:
win = glutCreateWindow("Basic Ray Tracer by Pa3cio, UL FRI");
init();
// Create the two input vectors
int i, j, k, l;
int VPWIDTH = viewport.xvmax - viewport.xvmin;
int VPHEIGHT = viewport.yvmax - viewport.yvmin;
// PIXEL* pixels = (PIXEL*) malloc(sizeof(PIXEL) * VPWIDTH * VPHEIGHT);
PIXEL* pPixelsFromGPU = (PIXEL*) malloc(sizeof(PIXEL) * VPWIDTH * VPHEIGHT);
PIXEL* pCurrentPixel;
PIXEL* pPixels;
RAY ray, shadow_ray;
SPHERE_INTERSECTION intersection, current_intersection, shadow_ray_intersection;
// Load the kernel source code into the array source_str
FILE *fp;
char *source_str;
size_t source_size;
fp = fopen("/home/rokj/sula/vpsa/seminarska/kernel.cl", "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char*)malloc(MAX_SOURCE_SIZE);
source_size = fread( source_str, 1, MAX_SOURCE_SIZE, fp);
fclose( fp );
// Get platform and device information
cl_platform_id platform_id = NULL;
cl_device_id device_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
ret = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_CPU, 1,
&device_id, &ret_num_devices);
// Create an OpenCL context
cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret);
// Create a command queue
cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
// Create memory buffers on the device for each vector
cl_mem output = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_ALLOC_HOST_PTR,
VPWIDTH * VPHEIGHT * sizeof(PIXEL), NULL, &ret);
// Create a program from the kernel source
cl_program program = clCreateProgramWithSource(context, 1,
(const char **)&source_str, (const size_t *)&source_size, &ret);
// Build the program
ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
// Create the OpenCL kernel
cl_kernel kernel = clCreateKernel(program, "compute_ray", &ret);
// Set the arguments of the kernel
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&output);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 1\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 1, sizeof(VECTOR3D), &view_point);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 2\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 2, sizeof(VECTOR3D), &camera_frame.n);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 3\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 3, sizeof(VECTOR3D), &camera_frame.u);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 4\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 4, sizeof(VECTOR3D), &camera_frame.v);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 5\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 5, sizeof(cl_int), &viewport.xvmin);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 6\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 6, sizeof(cl_int), &viewport.yvmin);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 7\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 7, sizeof(cl_double), &focal_distance);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 7\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 8, sizeof(cl_int), &VPWIDTH);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 9\n", stderr);
exit(1);
}
ret = clSetKernelArg(kernel, 9, sizeof(cl_int), &VPHEIGHT);
if (ret != CL_SUCCESS) {
fputs("error setting CL kernel arg 10\n", stderr);
exit(1);
}
ret = clFinish(command_queue);
// Execute the OpenCL kernel on the list
size_t global_item_size = VPWIDTH * VPHEIGHT; // Process the entire lists
size_t local_item_size = 1024; // Divide work items into groups of 64
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
&global_item_size, &local_item_size, 0, NULL, NULL);
// Read the memory buffer C on the device to the local variable C
ret = clEnqueueReadBuffer(command_queue, output, CL_TRUE, 0,
VPWIDTH * VPHEIGHT * sizeof(PIXEL), pPixelsFromGPU, 0, NULL, NULL);
// Display the result to the screen
//for(i = 0; i < LIST_SIZE; i++)
// printf("%d + %d = %d\n", A[i], B[i], C[i]);
// Clean up
// ret = clFlush(command_queue);
// ret = clFinish(command_queue);
// ret = clReleaseKernel(kernel);
// ret = clReleaseProgram(program);
// ret = clReleaseMemObject(b_mem_obj);
// ret = clReleaseCommandQueue(command_queue);
// ret = clReleaseContext(context);
pPixels = (PIXEL*) (pPixelsFromGPU);
// For all pixels:
for (i=0; i<VPWIDTH; i++) {
for (j=0; j<VPHEIGHT; j++) {
//pCurrentPixel = (PIXEL*)(pPixels + VPWIDTH*i + j);
// here I try to get pixel set on GPU, but it does not work
pCurrentPixel = &pPixels[i*VPWIDTH+j];
} //j
} //i
viewport.pPixels = (PIXEL*) (pPixelsFromGPU);
// register callback function to display graphics:
glutDisplayFunc(disp2);
// call Timer():
Timer(0);
// enter tha main loop and process events:
glutMainLoop();
free(pPixelsFromGPU);
return 0;
}
Definitions on host:
#include <CL/cl.h>
#ifndef DEFS_H
#define DEFS_H
#define _BLINNPHONG
//#define _LAMBERT
//#define _NOSHADING
#define NSPHERES 4
#define VIEWPLANE 500
#define WINDOW VIEWPLANE*2
#define FOCALDIST 1000
#define RADIUS 200
//#define _ANIMATE
// typedef enum {false=0, true=1} BOOL;
// typedef enum {down=0, up=1} DIRECTION;
#define CRED 0
#define CGREEN 1
#define CBLUE 2
#define true 1
#define false 0
/* --------------- VECTORS -------------------- */
typedef struct Vector3D{
cl_double x;
cl_double y;
cl_double z;
cl_double dummy1;
} VECTOR3D;
typedef struct ray {
VECTOR3D origin;
VECTOR3D direction;
} RAY;
/* ------------------- PIXEL ------------------ */
typedef struct pixel {
RAY ray;
cl_double rgb[4];
cl_int i;
cl_int j;
cl_int dummy1;
cl_int dummy2;
cl_int dummy3;
cl_int dummy4;
cl_int dummy5;
cl_int dummy6;
} PIXEL;
/* ----------------- VIEWPORT ----------------- */
typedef struct vp {
cl_int xvmin;
cl_int yvmin;
cl_int xvmax;
cl_int yvmax;
PIXEL* pPixels;
} VIEWPORT;
/* ---------------- SPHERE -------------------- */
typedef struct sp_intersection {
cl_double lambda_in;
cl_double lambda_out;
VECTOR3D normal;
VECTOR3D point;
cl_int valid;
} SPHERE_INTERSECTION;
typedef struct sph {
VECTOR3D center;
cl_double radius;
cl_double kd_rgb[3];
cl_double ks_rgb[3];
cl_double ka_rgb[3];
cl_double shininess;
cl_int mirror;
}SPHERE;
/* ------------------- RAY --------------------- */
/* --------------- VECTOR BASIS ---------------- */
typedef struct vb {
VECTOR3D u;
VECTOR3D v;
VECTOR3D n;
} VEC_BASIS;
#endif
In kernel:
typedef struct pixel {
RAY ray;
double rgb[4];
int i;
int j;
int dummy1;
int dummy2;
int dummy3;
int dummy4;
int dummy5;
int dummy6;
} PIXEL;
And kernel:
typedef struct Vector3D {
double x;
double y;
double z;
double dummy1;
} VECTOR3D;
typedef struct ray {
VECTOR3D origin;
VECTOR3D direction;
} RAY;
typedef struct pixel {
RAY ray;
double rgb[4];
int i;
int j;
int dummy1;
int dummy2;
int dummy3;
int dummy4;
int dummy5;
int dummy6;
} PIXEL;
void vec_sub(VECTOR3D *v1, VECTOR3D *v2, VECTOR3D *v3) {
v1->x = v2->x - v3->x;
v1->y = v2->y - v3->y;
v1->z = v2->z - v3->z;
}
void vec_add(VECTOR3D *v1, VECTOR3D *v2, VECTOR3D *v3) {
v1->x = v2->x + v3->x;
v1->y = v2->y + v3->y;
v1->z = v2->z + v3->z;
}
void vec_scale(double scale, VECTOR3D *v1, VECTOR3D *v2) {
v1->x = scale * v2->x;
v1->y = scale * v2->y;
v1->z = scale * v2->z;
}
double dotproduct(VECTOR3D *v1, VECTOR3D *v2) {
return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
}
void normalize_vector(VECTOR3D *v) {
double magnitude;
// 1. calculate the magnitude (length):
magnitude = sqrt( dotproduct(v, v) );
// 2. normalize the vector:
v->x = v->x / magnitude;
v->y = v->y / magnitude;
v->z = v->z / magnitude;
}
__kernel void compute_ray(
write_only global PIXEL *output,
VECTOR3D view_point,
VECTOR3D camera_frame_n,
VECTOR3D camera_frame_u,
VECTOR3D camera_frame_v,
const int viewport_xvmin,
const int viewport_yvmin,
const double distance,
const int w, const int h
)
{
float u, v;
VECTOR3D v1, v2, v3, v4, dir;
RAY ray;
PIXEL pixel;
int gi = get_global_id(0);
int i = gi / w;
int j = gi % w;
u = (float)(viewport_xvmin) + (float)(i) + 0.5f;
v = (float)(viewport_yvmin) + (float)(j) + 0.5f;
vec_scale(-distance, &v1, &camera_frame_n);
vec_scale(u, &v2, &camera_frame_u);
vec_scale(v, &v3, &camera_frame_v);
ray.origin.x = 22;
ray.origin.y = 22;
ray.origin.z = 22;
vec_add(&v4, &v1, &v2);
vec_add(&dir, &v4, &v3);
normalize_vector(&dir);
ray.direction.x = 11;
ray.direction.y = 11;
ray.direction.z = 11;
pixel.ray = ray;
pixel.i = 33;
pixel.j = 33;
output[i*w*j] = pixel;
}
I intentionally set i, j, origin and direction structures to fixed number so I could see if numbers are set.
Then I try to get pixel set on GPU in line
pCurrentPixel = &pPixels[i*VPWIDTH+j];
but pCurrentPixel->i for example is 0 instead of 33.
Code compiles with following commands:
gcc -c main.c -o main.o
gcc -c shading.c -o shading.o
gcc -c sphere.c -o sphere.o
gcc -c ray.c -o ray.o
gcc -c vectors.c -o vectors.o
gcc -I/usr/include -L/usr/lib/x86_64-linux-gnu main.o shading.o sphere.o ray.o vectors.o -lGL -lglut -lGLU -lX11 -lm -lrt -lOpenCL -o main
Besides setting the right VPWIDTH and VPHEIGHT output[i*w*j] = pixel; had to be changed to output[i*w+j] = pixel; in C code.

How to use QPainter for overlaying in QOpenGLWidget [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I've received the problem, using QPainter for overlaying in QOpenGLWidget Qt.
I create a CameraSurface_GL class that draw yuv image received from ip camera.
Here's my code:
#include "camerasurface_gl.h"
#include <QtWidgets>
#include <QtGui>
#include <QOpenGLFunctions_3_0>
const char* YUV420P_VS = ""
"#version 330\n"
""
"uniform mat4 u_pm;"
"uniform vec4 draw_pos;"
""
"const vec2 verts[4] = vec2[] ("
" vec2(-0.5, 0.5), "
" vec2(-0.5, -0.5), "
" vec2( 0.5, 0.5), "
" vec2( 0.5, -0.5) "
");"
""
"const vec2 texcoords[4] = vec2[] ("
" vec2(0.0, 1.0), "
" vec2(0.0, 0.0), "
" vec2(1.0, 1.0), "
" vec2(1.0, 0.0) "
"); "
""
"out vec2 v_coord; "
""
"void main() {"
" vec2 vert = verts[gl_VertexID];"
" vec4 p = vec4((0.5 * draw_pos.z) + draw_pos.x + (vert.x * draw_pos.z), "
" (0.5 * draw_pos.w) + draw_pos.y + (vert.y * draw_pos.w), "
" 0, 1);"
" gl_Position = u_pm * p;"
" v_coord = texcoords[gl_VertexID];"
"}"
"";
const char* YUV420P_FS = ""
"#version 330\n"
"uniform sampler2D y_tex;"
"uniform sampler2D u_tex;"
"uniform sampler2D v_tex;"
"in vec2 v_coord;"
"layout( location = 0 ) out vec4 fragcolor;"
""
"const vec3 R_cf = vec3(1, 0.000000, 1.13983);"
"const vec3 G_cf = vec3(1, -0.39465, -0.58060);"
"const vec3 B_cf = vec3(1, 2.03211, 0.000000);"
"const vec3 offset = vec3(-0.0625, -0.5, -0.5);"
""
"void main() {"
" float y = texture(y_tex, v_coord).r;"
" float u = texture(u_tex, v_coord).r;"
" float v = texture(v_tex, v_coord).r;"
" vec3 yuv = vec3(y,u,v);"
" yuv += offset;"
" fragcolor = vec4(0.0, 0.0, 0.0, 1.0);"
" fragcolor.r = dot(yuv, R_cf);"
" fragcolor.g = dot(yuv, G_cf);"
" fragcolor.b = dot(yuv, B_cf);"
"}"
"";
CameraSurface_GL::CameraSurface_GL(QWidget *parent) :
QOpenGLWidget(parent)
,vid_w(0)
,vid_h(0)
,win_w(0)
,win_h(0)
,vao(0)
,vao1(0)
,y_tex(0)
,u_tex(0)
,v_tex(0)
,vert(0)
,frag(0)
,prog(0)
,u_pos(-1)
,textures_created(false)
,shader_created(false)
{
qRegisterMetaType<YUVFrame>("YUVFrame");
m_ipCamera = new IpCamera;
m_yuvWidth = 0;
m_yuvHeight = 0;
connect(m_ipCamera, SIGNAL(frameChanged(YUVFrame)), this, SLOT(slotFrameChanged(YUVFrame)));
m_frameCount = 0;
m_setup = 0;
}
CameraSurface_GL::~CameraSurface_GL()
{
glDeleteTextures(1, &y_tex);
glDeleteTextures(1, &u_tex);
glDeleteTextures(1, &v_tex);
glDeleteProgram(prog);
}
void CameraSurface_GL::openCamera(QString ipAddress, QString userName, QString password)
{
if(m_ipCamera->isRunning())
m_ipCamera->close();
qDebug() << "open camera";
bool opend = m_ipCamera->open(ipAddress, userName, password);
if(opend == false)
return;
}
void CameraSurface_GL::closeCamera()
{
m_ipCamera->close();
}
void CameraSurface_GL::slotFrameChanged(YUVFrame frame)
{
m_yuvData = QByteArray((char*)frame.yuvData, frame.width * frame.height * 3 / 2);
m_yuvWidth = frame.width;
m_yuvHeight = frame.height;
if(m_setup == 0)
{
setup_gl(frame.width, frame.height);
resize_gl(rect().width(), rect().height());
m_setup = 1;
}
update();
m_frameCount ++;
}
void CameraSurface_GL::setup_gl(int width, int height)
{
vid_w = width;
vid_h = height;
if(!vid_w || !vid_h) {
printf("Invalid texture size.\n");
return;
}
if(!setupTextures()) {
return;
}
if(!setupShader()) {
return;
}
return;
}
void CameraSurface_GL::resize_gl(int width, int height)
{
win_w = width;
win_h = height;
pm.setToIdentity();
pm.ortho(0, win_w, win_h, 0, 0.0, 100.0f);
glUseProgram(prog);
glUniformMatrix4fv(glGetUniformLocation(prog, "u_pm"), 1, GL_FALSE, pm.data());
}
void CameraSurface_GL::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
if(m_setup)
{
resize_gl(width, height);
}
}
bool CameraSurface_GL::setupTextures()
{
if(textures_created) {
printf("Textures already created.\n");
return false;
}
glGenTextures(1, &y_tex);
glBindTexture(GL_TEXTURE_2D, y_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w, vid_h, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &u_tex);
glBindTexture(GL_TEXTURE_2D, u_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w/2, vid_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &v_tex);
glBindTexture(GL_TEXTURE_2D, v_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w/2, vid_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
textures_created = true;
return true;
}
bool CameraSurface_GL::setupShader()
{
if(shader_created) {
printf("Already creatd the shader.\n");
return false;
}
vert = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vert, 1, &YUV420P_VS, 0);
glCompileShader(vert);
frag = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(frag, 1, &YUV420P_FS, 0);
glCompileShader(frag);
prog = glCreateProgram();
glAttachShader(prog, vert);
glAttachShader(prog, frag);
glLinkProgram(prog);
glUseProgram(prog);
glUniform1i(glGetUniformLocation(prog, "y_tex"), 0);
glUniform1i(glGetUniformLocation(prog, "u_tex"), 1);
glUniform1i(glGetUniformLocation(prog, "v_tex"), 2);
u_pos = glGetUniformLocation(prog, "draw_pos");
glUseProgram(0);
return true;
}
void CameraSurface_GL::setYPixels(uint8_t* pixels, int stride)
{
glBindTexture(GL_TEXTURE_2D, y_tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w, vid_h, GL_RED, GL_UNSIGNED_BYTE, pixels);
}
void CameraSurface_GL::setUPixels(uint8_t* pixels, int stride)
{
glBindTexture(GL_TEXTURE_2D, u_tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w/2, vid_h/2, GL_RED, GL_UNSIGNED_BYTE, pixels);
}
void CameraSurface_GL::setVPixels(uint8_t* pixels, int stride)
{
glBindTexture(GL_TEXTURE_2D, v_tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w/2, vid_h/2, GL_RED, GL_UNSIGNED_BYTE, pixels);
}
void CameraSurface_GL::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0, 0, 0, 1);
}
void CameraSurface_GL::paintEvent(QPaintEvent* e)
{
QPainter painter;
painter.begin(this);
painter.beginNativePainting();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(m_yuvData.size())
{
setYPixels((unsigned char*)m_yuvData.data(), m_yuvWidth);
setUPixels((unsigned char*)m_yuvData.data() + m_yuvWidth * m_yuvHeight, m_yuvWidth / 2);
setVPixels((unsigned char*)m_yuvData.data() + m_yuvWidth * m_yuvHeight * 5 / 4, m_yuvWidth / 2);
glBindVertexArray(vao);
glUseProgram(prog);
glUniform4f(u_pos, rect().left(), rect().top(), rect().width(), rect().height());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, y_tex);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, u_tex);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, v_tex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glUseProgram(0);
}
painter.endNativePainting();
painter.end();
}
I want to the draw contents on the yuv layer, so I appended the following code in void paintEvent(QPaintEvent* e) functions:
void CameraSurface_GL::paintEvent(QPaintEvent* e)
{
QPainter painter;
painter.begin(this);
painter.beginNativePainting();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(m_yuvData.size())
{
setYPixels((unsigned char*)m_yuvData.data(), m_yuvWidth);
setUPixels((unsigned char*)m_yuvData.data() + m_yuvWidth * m_yuvHeight, m_yuvWidth / 2);
setVPixels((unsigned char*)m_yuvData.data() + m_yuvWidth * m_yuvHeight * 5 / 4, m_yuvWidth / 2);
glBindVertexArray(vao);
glUseProgram(prog);
glUniform4f(u_pos, rect().left(), rect().top(), rect().width(), rect().height());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, y_tex);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, u_tex);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, v_tex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glUseProgram(0);
}
painter.endNativePainting();
//////new appended code//////
QPixmap memPix(rect().width(), rect().height());
QPainter memDC;
memDC.setPen(Qt::red);
memDC.drawRect(QRect(0, 0, 100, 100));
painter.drawPixmap(rect(), memPix);
/////end/////
painter.end();
}
At this time, I received the issue crashing my program.
And, When I also changed to the following, I received the same:
void CameraSurface_GL::paintEvent(QPaintEvent* e)
{
QPainter painter;
painter.begin(this);
painter.beginNativePainting();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(m_yuvData.size())
{
setYPixels((unsigned char*)m_yuvData.data(), m_yuvWidth);
setUPixels((unsigned char*)m_yuvData.data() + m_yuvWidth * m_yuvHeight, m_yuvWidth / 2);
setVPixels((unsigned char*)m_yuvData.data() + m_yuvWidth * m_yuvHeight * 5 / 4, m_yuvWidth / 2);
}
painter.endNativePainting();
QPixmap memPix(rect().width(), rect().height());
QPainter memDC;
memDC.setPen(Qt::red);
memDC.drawRect(QRect(0, 0, 100, 100));
painter.drawPixmap(rect(), memPix);
painter.end();
}
And, When I remove the part of calling setYPixels, setUPixels and setVPixels, my program is not crashing.
I can't know why I received the error. I want to know the cause of this issue.
You should unbind any textures, buffers and so on. I have had quite similar problem with unbinded VBO.

Why i should generate texture in initializeGL qt

I'm trying to draw yuv image using Qt OpenGL.
I've create a 'CameraSurface_GL' class inherited from QGLWidget, drawing yuv image received from ip camera.
I introduce my code here.
#include "camerasurface_gl.h"
#include <QtWidgets>
#include <QtGui>
#include <QOpenGLFunctions_3_0>
const char* YUV420P_VS = ""
"#version 330\n"
""
"uniform mat4 u_pm;"
"uniform vec4 draw_pos;"
""
"const vec2 verts[4] = vec2[] ("
" vec2(-0.5, 0.5), "
" vec2(-0.5, -0.5), "
" vec2( 0.5, 0.5), "
" vec2( 0.5, -0.5) "
");"
""
"const vec2 texcoords[4] = vec2[] ("
" vec2(0.0, 1.0), "
" vec2(0.0, 0.0), "
" vec2(1.0, 1.0), "
" vec2(1.0, 0.0) "
"); "
""
"out vec2 v_coord; "
""
"void main() {"
" vec2 vert = verts[gl_VertexID];"
" vec4 p = vec4((0.5 * draw_pos.z) + draw_pos.x + (vert.x * draw_pos.z), "
" (0.5 * draw_pos.w) + draw_pos.y + (vert.y * draw_pos.w), "
" 0, 1);"
" gl_Position = u_pm * p;"
" v_coord = texcoords[gl_VertexID];"
"}"
"";
const char* YUV420P_FS = ""
"#version 330\n"
"uniform sampler2D y_tex;"
"uniform sampler2D u_tex;"
"uniform sampler2D v_tex;"
"in vec2 v_coord;"
"layout( location = 0 ) out vec4 fragcolor;"
""
"const vec3 R_cf = vec3(1, 0.000000, 1.13983);"
"const vec3 G_cf = vec3(1, -0.39465, -0.58060);"
"const vec3 B_cf = vec3(1, 2.03211, 0.000000);"
"const vec3 offset = vec3(-0.0625, -0.5, -0.5);"
""
"void main() {"
" float y = texture(y_tex, v_coord).r;"
" float u = texture(u_tex, v_coord).r;"
" float v = texture(v_tex, v_coord).r;"
" vec3 yuv = vec3(y,u,v);"
" yuv += offset;"
" fragcolor = vec4(0.0, 0.0, 0.0, 1.0);"
" fragcolor.r = dot(yuv, R_cf);"
" fragcolor.g = dot(yuv, G_cf);"
" fragcolor.b = dot(yuv, B_cf);"
"}"
"";
CameraSurface_GL::CameraSurface_GL(QWidget *parent) :
QGLWidget(parent)
,vid_w(0)
,vid_h(0)
,win_w(0)
,win_h(0)
,vao(0)
,y_tex(0)
,u_tex(0)
,v_tex(0)
,vert(0)
,frag(0)
,prog(0)
,u_pos(-1)
,textures_created(false)
,shader_created(false)
{
qRegisterMetaType<YUVFrame>("YUVFrame");
m_ipCamera = new IpCamera;
connect(m_ipCamera, SIGNAL(frameChanged(YUVFrame)), this, SLOT(slotFrameChanged(YUVFrame)));
m_frameCount = 0;
m_setup = 0;
}
CameraSurface_GL::~CameraSurface_GL()
{
glDeleteTextures(1, &y_tex);
glDeleteTextures(1, &u_tex);
glDeleteTextures(1, &v_tex);
glDeleteProgram(prog);
}
void CameraSurface_GL::openCamera(QString ipAddress, QString userName, QString password)
{
if(m_ipCamera->isRunning())
m_ipCamera->close();
bool opend = m_ipCamera->open(ipAddress, userName, password);
if(opend == false)
return;
}
void CameraSurface_GL::closeCamera()
{
m_ipCamera->close();
}
void CameraSurface_GL::slotFrameChanged(YUVFrame frame)
{
m_yuvFrame = frame;
update();
}
void CameraSurface_GL::setup_gl(int width, int height)
{
vid_w = width;
vid_h = height;
if(!vid_w || !vid_h) {
printf("Invalid texture size.\n");
return;
}
if(!setupTextures()) {
return;
}
if(!setupShader()) {
return;
}
glGenVertexArrays(1, &vao);
return;
}
void CameraSurface_GL::resize_gl(int width, int height)
{
win_w = width;
win_h = height;
pm.setToIdentity();
pm.ortho(0, win_w, win_h, 0, 0.0, 100.0f);
glUseProgram(prog);
glUniformMatrix4fv(glGetUniformLocation(prog, "u_pm"), 1, GL_FALSE, pm.data());
}
void CameraSurface_GL::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0, 0, 0, 1);
setup_gl(1920, 1080);
}
void CameraSurface_GL::paintGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(m_yuvFrame.yuvData.size())
{
setYPixels((unsigned char*)m_yuvFrame.yuvData.data(), yuvFrame.width);
setUPixels((unsigned char*)m_yuvFrame.yuvData.data() + yuvFrame.width * yuvFrame.height, yuvFrame.width / 2);
setVPixels((unsigned char*)m_yuvFrame.yuvData.data() + yuvFrame.width * yuvFrame.height * 5 / 4, yuvFrame.width / 2);
glBindVertexArray(vao);
glUseProgram(prog);
QRect frameRect = rect();
glUniform4f(u_pos, frameRect.left(), frameRect.top(), frameRect.width(), frameRect.height());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, y_tex);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, u_tex);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, v_tex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
}
void CameraSurface_GL::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
resize_gl(width, height);
}
bool CameraSurface_GL::setupTextures()
{
if(textures_created) {
printf("Textures already created.\n");
return false;
}
glGenTextures(1, &y_tex);
glBindTexture(GL_TEXTURE_2D, y_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w, vid_h, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &u_tex);
glBindTexture(GL_TEXTURE_2D, u_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w/2, vid_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &v_tex);
glBindTexture(GL_TEXTURE_2D, v_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w/2, vid_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
textures_created = true;
return true;
}
bool CameraSurface_GL::setupShader()
{
if(shader_created) {
printf("Already creatd the shader.\n");
return false;
}
vert = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vert, 1, &YUV420P_VS, 0);
glCompileShader(vert);
frag = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(frag, 1, &YUV420P_FS, 0);
glCompileShader(frag);
prog = glCreateProgram();
glAttachShader(prog, vert);
glAttachShader(prog, frag);
glLinkProgram(prog);
glUseProgram(prog);
glUniform1i(glGetUniformLocation(prog, "y_tex"), 0);
glUniform1i(glGetUniformLocation(prog, "u_tex"), 1);
glUniform1i(glGetUniformLocation(prog, "v_tex"), 2);
u_pos = glGetUniformLocation(prog, "draw_pos");
return true;
}
void CameraSurface_GL::setYPixels(uint8_t* pixels, int stride)
{
glBindTexture(GL_TEXTURE_2D, y_tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w, vid_h, GL_RED, GL_UNSIGNED_BYTE, pixels);
}
void CameraSurface_GL::setUPixels(uint8_t* pixels, int stride)
{
glBindTexture(GL_TEXTURE_2D, u_tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w/2, vid_h/2, GL_RED, GL_UNSIGNED_BYTE, pixels);
}
void CameraSurface_GL::setVPixels(uint8_t* pixels, int stride)
{
glBindTexture(GL_TEXTURE_2D, v_tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w/2, vid_h/2, GL_RED, GL_UNSIGNED_BYTE, pixels);
}
I call 'setup' function in initializeGL, using static parameter 1920, 1080.
This is not my idea.
I want to call 'setup' function when received yuv frame from ip camera, so I changed my code to the following.
void CameraSurface_GL::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0, 0, 0, 1);
}
void CameraSurface_GL::slotFrameChanged(YUVFrame frame)
{
if(m_setup == 0)
{
setup_gl(frame.width, frame.height);
resize_gl(frame.width, frame.height);
m_setup = 1;
}
m_yuvFrame = frame;
update();
}
At this time, I can't show drawn image on view.
Why I receive the issue?
Can't I call 'setup' function in other place, in not initializeGL?

GLES 2.0 draws GL_POINTS as squares on Android?

Below is a simple QT program using a VBO to draw 6 points. The points appear as squares on Android and single pixels on the desktop. When I change gl_PointSize in the vertex shader, the squares change to the appropriate size on Android but remain single pixels on the desktop.
example.pro
QT += core gui widgets opengl
TARGET = example
TEMPLATE = app
SOURCES = main.cpp
HEADERS = main.h
main.h
#include <QGLWidget>
#include <QGLFunctions>
#include <QGLShader>
class glview : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit glview(QWidget *parent = 0);
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
private:
quint32 vbo_id[1];
QGLShaderProgram *program;
};
main.cpp
#include <QApplication>
#include "main.h"
struct vrtx {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat r;
GLfloat g;
GLfloat b;
}__attribute__((packed)) geomrtry[] = {
// x, y, z r, g, b
{1, 1, 0, 1, 0, 0},
{1.5, 2, 0, 0, 1, 0},
{2, 1, 0, 0, 0, 1},
{3, 1, 0, 1, 0, 1},
{3.5, 2, 0, 1, 1, 0},
{4, 1, 0, 0, 1, 1},
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
glview widget;
widget.show();
return app.exec();
}
glview::glview(QWidget *parent) : QGLWidget(parent)
{
}
void glview::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::white);
QGLShader *vshader = new QGLShader(QGLShader::Vertex, this);
const char *vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec4 colour;\n"
"varying mediump vec4 f_colour;\n"
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" f_colour = colour;\n"
" gl_PointSize = 12.0;\n"
"}\n";
vshader->compileSourceCode(vsrc);
QGLShader *fshader = new QGLShader(QGLShader::Fragment, this);
const char *fsrc =
"varying mediump vec4 f_colour;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = f_colour;\n"
"}\n";
fshader->compileSourceCode(fsrc);
program = new QGLShaderProgram(this);
program->addShader(vshader);
program->addShader(fshader);
program->link();
glGenBuffers(1, vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(geomrtry), geomrtry, GL_STATIC_DRAW);
glEnable(GL_DEPTH_TEST);
}
void glview::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void glview::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 matrix;
matrix.ortho(0, 5, 0, 3, -1, 1);
program->bind();
program->setUniformValue("matrix", matrix);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
int vertexLocation = program->attributeLocation("vertex");
program->enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct vrtx), 0);
int colourLocation = program->attributeLocation("colour");
program->enableAttributeArray(colourLocation);
glVertexAttribPointer(colourLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct vrtx), ((char*)NULL + 12));
//glDrawArrays(GL_TRIANGLES, 0, sizeof(geomrtry) / sizeof(struct vrtx));
glDrawArrays(GL_POINTS, 0, sizeof(geomrtry) / sizeof(struct vrtx));
glFlush();
}
You're using functionality where the size of rendered points is taken from a built-in gl_PointSize variable set in the vertex shader. This functionality is the default in ES 2.0.
The same functionality is available in desktop OpenGL as well, but it is disabled by default. It can be enabled by calling:
glEnable(GL_PROGRAM_POINT_SIZE);
If this setting is not enabled, desktop OpenGL uses the point size set with the glPointSize() API call.

OpenCL gemm kernel local memory going slower

EDIT: It was my cards fault... The local memory kernel goes a few times faster, sorry all!!
I am writing a simple sgemm (square, alpha=1, beta=0) that is supposed to take advantage of local memory, but it performs at half the speed of a naive version.
Here are the kernels:
const char* matrixMultiplySource =
"__kernel\n"
" void matrixMultiply(__global float* A, __global float* B, __global float* C)\n"
" {\n"
" int i = get_local_id(0);\n"
" int j = get_local_id(1);\n"
" int ig = get_global_id(0);\n"
" int jg = get_global_id(1);\n"
" int sizeG0 = get_global_size(0);\n"
" __local float localA[BLOCK_SIZE][BLOCK_SIZE];\n"
" __local float localB[BLOCK_SIZE][BLOCK_SIZE];\n"
" float val=0.0f;\n"
" for ( int index = 0; index < sizeG0; index += BLOCK_SIZE )\n"
" {\n"
" localA[j][i] = A[ig + sizeG0 * (index+j)];\n"
" localB[j][i] = B[index+i + sizeG0 * jg];\n"
" barrier(CLK_GLOBAL_MEM_FENCE);\n"
" #pragma unroll\n"
" for ( int kk = 0; kk < BLOCK_SIZE; ++kk)\n"
" {\n"
" val = val + localA[kk][i] * localB[j][kk];\n"
" }\n"
" barrier(CLK_GLOBAL_MEM_FENCE);\n"
" }\n"
" C[ig + sizeG0 * jg] = val;\n"
"}\n"
;
const char* matrixMultiplySource2 =
"__kernel\n"
" void matrixMultiply(__global float* A, __global float* B, __global float* C)\n"
" {\n"
" int ig = get_global_id(0);\n"
" int jg = get_global_id(1);\n"
" int sizeG0 = get_global_size(0);\n"
" float val=0;\n"
" for ( int k = 0; k < sizeG0; k++)\n"
" {\n"
" val = val + A[ig + k * sizeG0] * B[k + jg * sizeG0];\n"
" }\n"
" C[ig + sizeG0 * jg] = val;\n"
"}\n"
;
BLOCK_SIZE is 16 and I am using 1024x1024 matrices as well as warming up.
// Create OpenCL context
context = mycl::myclCreateContext( NULL, ret_num_devices, devices, NULL, NULL, &ret);
// Create Command Queue
command_queue = mycl::myclCreateCommandQueue(context, devices[0], 0, &ret);
// Create Memory Buffer
memobjA = mycl::myclCreateBuffer(context, CL_MEM_READ_ONLY, widthA * heightA * sizeof(float), NULL, &ret);
memobjB = mycl::myclCreateBuffer(context, CL_MEM_READ_ONLY, widthB * heightB * sizeof(float), NULL, &ret);
memobjC = mycl::myclCreateBuffer(context, CL_MEM_READ_WRITE, widthC * heightC * sizeof(float), NULL, &ret);
// Copy the lists A and B to their respective memory buffers
ret = mycl::myclEnqueueWriteBuffer(command_queue,memobjA, CL_TRUE, 0,
widthA * heightA * sizeof(float), A, 0, NULL, NULL);
ret = mycl::myclEnqueueWriteBuffer(command_queue, memobjB, CL_TRUE, 0,
widthB * heightB * sizeof(float), B, 0, NULL, NULL);
// Create Kernel Program from the source
program = mycl::myclCreateProgramWithSource(context, 1, (const char **)&matrixMultiplySource,
NULL, &ret);
// Build Kernel Program
ret = mycl::myclBuildProgram(program, ret_num_devices, devices, "-D BLOCK_SIZE=16", NULL, NULL);
if(ret != CL_SUCCESS){cout << "PROBREM! " << ret << endl;return -1;}
// Create OpenCL Kernel
kernel = mycl::myclCreateKernel(program, "matrixMultiply", &ret);
size_t globalThreads[2] = {heightA, widthB};
size_t localThreads[2] = {BLOCK_SIZE, BLOCK_SIZE};
// Set OpenCL Kernel Arguments
ret = mycl::myclSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobjA);
ret = mycl::myclSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobjB);
ret = mycl::myclSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&memobjC);
// Time the kernel
struct timeval timev1, timev2;
float time_seconds = 0.0f;
mycl::myclEnqueueNDRangeKernel(command_queue, kernel, 2, NULL, globalThreads, localThreads, 0, 0, NULL);
mycl::myclFinish(command_queue);
gettimeofday(&timev1, NULL);
ret = mycl::myclEnqueueNDRangeKernel(command_queue, kernel, 2, NULL, globalThreads, localThreads, 0, 0, NULL);
if(ret != CL_SUCCESS){cout << "fail! " << ret << endl;}
ret = mycl::myclFinish(command_queue);
if(ret != CL_SUCCESS){cout << "fail! " << ret << endl;}
gettimeofday(&timev2,NULL);
time_seconds=(timev2.tv_sec-timev1.tv_sec)+0.000001*(timev2.tv_usec- timev1.tv_usec);
Have you looked at the two kernels in the AMD APP KernelAnalyzer or equivalent tools? These tools compile the Kernels and show their predicted performance characteristics
You use
barrier(CLK_GLOBAL_MEM_FENCE);
where I would expect to see
barrier(CLK_LOCAL_MEM_FENCE);
as you write in the loop to local memory.
Further I doubt that the copy to localA does help you -- at one time every items there is only accessed once.

Resources