Skip to content
Snippets Groups Projects
Commit fa6dd524 authored by Jeremy Whiting's avatar Jeremy Whiting
Browse files

Add check-gl draw a triangle test.

Just as with check-vulkan use --visible to see the triangle window
otherwise application draws a few frames and reports any gl errors
found or does exit 0 on success.
parent 30924655
No related branches found
No related tags found
1 merge request!83Add check-gl draw a triangle using opengl test
/*
* Copyright © 2019 Collabora Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <set>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
extern "C" {
#include <getopt.h>
};
const int WIDTH = 200;
const int HEIGHT = 200;
static const char *argv0;
class HelloTriangleGLApplication {
public:
HelloTriangleGLApplication(bool visible)
: m_visible(visible),
m_display(nullptr),
m_window(0),
m_context(0)
{
}
void run() {
initGL();
mainLoop();
cleanup();
}
private:
bool m_visible;
Display *m_display;
Window m_window;
GLXContext m_context;
void initGL() {
m_display = XOpenDisplay(nullptr);
if (!m_display)
{
throw std::runtime_error("Unable to open display");
}
makeWindow();
if (m_visible)
XMapWindow(m_display, m_window);
glXMakeCurrent(m_display, m_window, m_context);
}
void drawTriangle()
{
//clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Make it red
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-0.8f,-0.8f,0.0f);
glVertex3f(0.8f,-0.8f, 0.0f);
glVertex3f(0.0f, 0.6f,0.0f);
glEnd();
glEndList();
glEnable(GL_NORMALIZE);
}
void makeWindow()
{
int attribs[64];
int i = 0;
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
XVisualInfo *visinfo;
/* Singleton attributes. */
attribs[i++] = GLX_RGBA;
attribs[i++] = GLX_DOUBLEBUFFER;
/* Key/value attributes. */
attribs[i++] = GLX_RED_SIZE;
attribs[i++] = 1;
attribs[i++] = GLX_GREEN_SIZE;
attribs[i++] = 1;
attribs[i++] = GLX_BLUE_SIZE;
attribs[i++] = 1;
attribs[i++] = GLX_DEPTH_SIZE;
attribs[i++] = 1;
attribs[i++] = None;
scrnum = DefaultScreen(m_display);
root = RootWindow(m_display, scrnum);
visinfo = glXChooseVisual(m_display, scrnum, attribs);
if (!visinfo)
{
throw std::runtime_error("Error: couldn't get an RGB, Double-buffered visual");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(m_display, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
m_window = XCreateWindow( m_display, root, 0, 0, WIDTH, HEIGHT,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = 0;
sizehints.y = 0;
sizehints.width = WIDTH;
sizehints.height = HEIGHT;
sizehints.flags = USSize | USPosition;
XSetNormalHints(m_display, m_window, &sizehints);
XSetStandardProperties(m_display, m_window, "check-gl", "check-gl",
None, (char **)NULL, 0, &sizehints);
}
m_context = glXCreateContext(m_display, visinfo, NULL, True );
if (!m_context)
{
throw std::runtime_error("Error: glXCreateContext failed");
}
XFree(visinfo);
}
void mainLoop() {
for (int i = 0; i < (m_visible ? 10000 : 10); ++i) {
drawFrame();
}
}
void cleanup() {
if (m_display) {
glXMakeCurrent(m_display, None, nullptr);
if (m_context) {
glXDestroyContext(m_display, m_context);
}
if (m_window) {
XDestroyWindow(m_display, m_window);
}
XCloseDisplay(m_display);
}
}
void drawFrame() {
drawTriangle();
glXSwapBuffers(m_display, m_window);
}
};
enum {
OPTION_HELP = 1,
OPTION_VERSION,
OPTION_VISIBLE,
};
static struct option long_options[] = {
{ "help", no_argument, NULL, OPTION_HELP },
{ "version", no_argument, NULL, OPTION_VERSION },
{ "visible", no_argument, NULL, OPTION_VISIBLE },
{ NULL, 0, NULL, 0 }
};
static void usage(int code) __attribute__((__noreturn__));
static void usage(int code) {
std::ostream& stream = (code == EXIT_SUCCESS ? std::cout : std::cerr);
stream << "Usage: " << argv0 << " [OPTIONS]" << std::endl;
stream << "Options:" << std::endl;
stream << "--help\t\tShow this help and exit" << std::endl;
stream << "--visible\tMake test window visible" << std::endl;
stream << "--version\tShow version and exit" << std::endl;
std::exit(code);
}
int main(int argc, char** argv) {
int opt;
bool visible = false;
argv0 = argv[0];
while ((opt = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
switch (opt) {
case OPTION_HELP:
usage(0);
break; // not reached
case OPTION_VERSION:
/* Output version number as YAML for machine-readability,
* inspired by `ostree --version` and `docker version` */
std::cout << argv[0] << ":" << std::endl
<< " Package: steam-runtime-tools" << std::endl
<< " Version: " << VERSION << std::endl;
return EXIT_SUCCESS;
case OPTION_VISIBLE:
visible = true;
break;
case '?':
default:
usage(2);
break; // not reached
}
}
HelloTriangleGLApplication app(visible);
try {
app.run();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
......@@ -109,4 +109,16 @@ custom_target(
)
)
executable(
multiarch + '-check-gl',
'check-gl.cpp',
dependencies : [xlib, gl],
include_directories : project_include_dirs,
install : true,
install_dir : join_paths(
get_option('libexecdir'),
'steam-runtime-tools-' + api_major,
)
)
# vim:set sw=2 sts=2 et:
......@@ -190,6 +190,14 @@ xcb = dependency(
'xcb',
)
gl = dependency(
'gl'
)
xlib = dependency(
'x11'
)
libdl = c_compiler.find_library('dl', required : false)
project_include_dirs = include_directories('.')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment