Skip to content
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ target_link_libraries(
qhullstatic_r
tinyobjloader
tinyxml2
cglm
)

set_target_properties(
Expand Down
24 changes: 24 additions & 0 deletions cmake/MujocoDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ set(MUJOCO_DEP_VERSION_benchmark
set(MUJOCO_DEP_VERSION_TriangleMeshDistance
2cb643de1436e1ba8e2be49b07ec5491ac604457
CACHE STRING "Version of `TriangleMeshDistance` to be fetched."
)

set(MUJOCO_DEP_VERSION_cglm
144d1e7c29b3b0c6dede7917a0476cc95248559c
CACHE STRING "Version of `CGLM` to be fetched."
)

mark_as_advanced(MUJOCO_DEP_VERSION_lodepng)
Expand All @@ -74,6 +79,7 @@ mark_as_advanced(MUJOCO_DEP_VERSION_abseil)
mark_as_advanced(MUJOCO_DEP_VERSION_gtest)
mark_as_advanced(MUJOCO_DEP_VERSION_benchmark)
mark_as_advanced(MUJOCO_DEP_VERSION_TriangleMeshDistance)
mark_as_advanced(MUJOCO_DEP_VERSION_cglm)

include(FetchContent)
include(FindOrFetch)
Expand Down Expand Up @@ -218,6 +224,24 @@ findorfetch(
target_compile_options(ccd PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
target_link_options(ccd PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})

findorfetch(
USE_SYSTEM_PACKAGE
OFF
PACKAGE_NAME
cglm
LIBRARY_NAME
cglm
GIT_REPO
https://github.com/recp/cglm.git
GIT_TAG v0.9.6
${MUJOCO_DEP_VERSION_cglm}
TARGETS
cglm
EXCLUDE_FROM_ALL
)
target_compile_options(cglm PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
target_link_options(cglm PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})

# libCCD has an unconditional `#define _CRT_SECURE_NO_WARNINGS` on Windows.
# TODO(stunya): Remove this after https://github.com/danfis/libccd/pull/77 is merged.
if(WIN32)
Expand Down
11 changes: 11 additions & 0 deletions include/mujoco/mjrender.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ struct mjrContext_ { // custom OpenGL context
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs (nskin)
unsigned int* skinfaceVBO; // skin face index VBOs (nskin)

// Shaders
unsigned int defaultShader;
unsigned int wireframeShader;

// Plane buffers
int nplanes;
unsigned int planeIndexCount;
unsigned int planeVAO; // Plane vertex array objects (nplane)
unsigned int planeVBO; // Plane vertex buffer objects (nplane)
unsigned int planeEBO; // Plane elemental buffer objects (nplane)

// character info
int charWidth[127]; // character widths: normal and shadow
int charWidthBig[127]; // chacarter widths: big
Expand Down
2 changes: 2 additions & 0 deletions include/mujoco/mujoco.h
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ MJAPI void mjr_defaultContext(mjrContext* con);

// Allocate resources in custom OpenGL context; fontscale is mjtFontScale.
MJAPI void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale);
MJAPI void mjr3_makeContext(const mjModel* m, mjrContext* con, int fontscale);

// Change font of existing context.
MJAPI void mjr_changeFont(int fontscale, mjrContext* con);
Expand Down Expand Up @@ -819,6 +820,7 @@ MJAPI void mjr_figure(mjrRect viewport, mjvFigure* fig, const mjrContext* con);

// Render 3D scene.
MJAPI void mjr_render(mjrRect viewport, mjvScene* scn, const mjrContext* con);
MJAPI void mjr3_render(mjrRect viewport, mjvScene* scn, const mjrContext* con);

// Call glFinish.
MJAPI void mjr_finish(void);
Expand Down
26 changes: 19 additions & 7 deletions sample/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,31 @@ target_link_libraries(
)
target_link_options(basic PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})

add_executable(record record.cc array_safety.h)
target_compile_options(record PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
add_executable(basic3 basic3.cc)
target_compile_options(basic3 PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
target_link_libraries(
record
basic3
mujoco::mujoco
glfw
Threads::Threads
)
target_link_options(record PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
target_link_options(basic PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})

# add_executable(record record.cc array_safety.h)
# target_compile_options(record PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
# target_link_libraries(
# record
# mujoco::mujoco
# glfw
# Threads::Threads
# )
# target_link_options(record PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})

if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
embed_in_bundle(basic simulate)
embed_in_bundle(basic3 simulate)
embed_in_bundle(compile simulate)
embed_in_bundle(record simulate)
# embed_in_bundle(record simulate)
embed_in_bundle(testspeed simulate)
endif()

Expand All @@ -126,8 +137,9 @@ if(_INSTALL_SAMPLES)
target_add_rpath(
TARGETS
basic
basic3
compile
record
# record
testspeed
INSTALL_DIRECTORY
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
Expand All @@ -140,7 +152,7 @@ if(_INSTALL_SAMPLES)
install(
TARGETS basic
compile
record
# record
testspeed
EXPORT ${PROJECT_NAME}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT samples
Expand Down
215 changes: 215 additions & 0 deletions sample/basic3.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
// Copyright 2021 DeepMind Technologies Limited
//
// 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 <cstdio>
#include <cstring>

#include <GLFW/glfw3.h>
#include <mujoco/mujoco.h>

// MuJoCo data structures
mjModel* m = NULL; // MuJoCo model
mjData* d = NULL; // MuJoCo data
mjvCamera cam; // abstract camera
mjvOption opt; // visualization options
mjvScene scn; // abstract scene
mjrContext con; // custom GPU context

// mouse interaction
bool button_left = false;
bool button_middle = false;
bool button_right = false;
double lastx = 0;
double lasty = 0;


// keyboard callback
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods) {
// backspace: reset simulation
if (act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE) {
mj_resetData(m, d);
mj_forward(m, d);
}
}


// mouse button callback
void mouse_button(GLFWwindow* window, int button, int act, int mods) {
// update button state
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);

// update mouse position
glfwGetCursorPos(window, &lastx, &lasty);
}


// mouse move callback
void mouse_move(GLFWwindow* window, double xpos, double ypos) {
// no buttons down: nothing to do
if (!button_left && !button_middle && !button_right) {
return;
}

// compute mouse displacement, save
double dx = xpos - lastx;
double dy = ypos - lasty;
lastx = xpos;
lasty = ypos;

// get current window size
int width, height;
glfwGetWindowSize(window, &width, &height);

// get shift key state
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);

// determine action based on mouse button
mjtMouse action;
if (button_right) {
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
} else if (button_left) {
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
} else {
action = mjMOUSE_ZOOM;
}

// move camera
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
}


// scroll callback
void scroll(GLFWwindow* window, double xoffset, double yoffset) {
// emulate vertical mouse motion = 5% of window height
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
}


// main function
int main(int argc, const char** argv) {
// check command-line arguments
if (argc!=2) {
std::printf(" USAGE: basic modelfile\n");
return 0;
}

// load and compile model
char error[1000] = "Could not load binary model";
if (std::strlen(argv[1])>4 && !std::strcmp(argv[1]+std::strlen(argv[1])-4, ".mjb")) {
m = mj_loadModel(argv[1], 0);
} else {
m = mj_loadXML(argv[1], 0, error, 1000);
}
if (!m) {
mju_error("Load model error: %s", error);
}

// make data
d = mj_makeData(m);

// init GLFW
if (!glfwInit()) {
mju_error("Could not initialize GLFW");
}

// create window, make OpenGL context current, request v-sync
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 3.2 is a good minimum for macOS
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required for macOS
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// glfwWindowHint(OPENGL_PROFILE, OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);

// initialize visualization data structures
mjv_defaultCamera(&cam);
mjv_defaultOption(&opt);
mjv_defaultScene(&scn);
mjr_defaultContext(&con);

// GLint majorVersion, minorVersion;
// glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
// glGetIntegerv(GL_MINOR_VERSION, &minorVersion);

int majorVersion = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
int minorVersion = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
printf("OpenGL version: %d.%d\n", majorVersion, minorVersion);

// GLint major, minor;
// glGetIntegerv(0x821B, &major); // GL_MAJOR_VERSION = 0x821B
// glGetIntegerv(0x821C, &minor); // GL_MINOR_VERSION = 0x821C
// GLint major, minor;
// glGetIntegerv(GL_MAJOR_VERSION, &major);
// glGetIntegerv(GL_MINOR_VERSION, &minor);
// std::cout << "OpenGL Version: " << major << "." << minor << std::endl;
// const char *version = (const char *)glGetString(GL_VERSION);
// printf("OpenGL version: %s\n", version);

// create scene and context
mjv_makeScene(m, &scn, 2000);
mjr3_makeContext(m, &con, mjFONTSCALE_150);

// install GLFW mouse and keyboard callbacks
glfwSetKeyCallback(window, keyboard);
glfwSetCursorPosCallback(window, mouse_move);
glfwSetMouseButtonCallback(window, mouse_button);
glfwSetScrollCallback(window, scroll);

// run main loop, target real-time simulation and 60 fps rendering
while (!glfwWindowShouldClose(window)) {
// advance interactive simulation for 1/60 sec
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
// this loop will finish on time for the next frame to be rendered at 60 fps.
// Otherwise add a cpu timer and exit this loop when it is time to render.
mjtNum simstart = d->time;
while (d->time - simstart < 1.0/60.0) {
mj_step(m, d);
}

// get framebuffer viewport
mjrRect viewport = {0, 0, 0, 0};
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);

// update scene and render
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);

// swap OpenGL buffers (blocking call due to v-sync)
glfwSwapBuffers(window);

mjr3_render(viewport, &scn, &con);

// process pending GUI events, call GLFW callbacks
glfwPollEvents();
}

//free visualization storage
mjv_freeScene(&scn);
// mjr_freeContext(&con);

// free MuJoCo model and data
mj_deleteData(d);
mj_deleteModel(m);

// terminate GLFW (crashes with Linux NVidia drivers)
#if defined(__APPLE__) || defined(_WIN32)
glfwTerminate();
#endif

return 1;
}
2 changes: 1 addition & 1 deletion sample/cmake/SampleDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ option(MUJOCO_SAMPLES_USE_SYSTEM_MUJOCO "Use installed MuJoCo version."
unset(DEFAULT_USE_SYSTEM_MUJOCO)

option(MUJOCO_SAMPLES_USE_SYSTEM_MUJOCO "Use installed MuJoCo version." OFF)
option(MUJOCO_SAMPLES_USE_SYSTEM_GLFW "Use installed GLFW version." OFF)
option(MUJOCO_SAMPLES_USE_SYSTEM_GLFW "Use installed GLFW version." ON)

set(MUJOCO_DEP_VERSION_glfw3
7b6aead9fb88b3623e3b3725ebb42670cbe4c579 # 3.4
Expand Down
11 changes: 11 additions & 0 deletions src/render/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ set(MUJOCO_RENDER_SRCS
glad/glad.c
glad/glad.h
glad/loader.cc
glad/glad3.c
glad/glad3.h
glad/loader3.cc
render_context.c
render_context.h
render_gl2.c
Expand All @@ -24,6 +27,14 @@ set(MUJOCO_RENDER_SRCS
render_gl3.h
render_util.c
render_util.h
render3_context.c
render3_context.h
render3_gl2.c
render3_gl2.h
render3_gl3.c
render3_gl3.h
render3_util.c
render3_util.h
)

target_sources(mujoco PRIVATE ${MUJOCO_RENDER_SRCS})
Expand Down
Loading